aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-11-29 00:20:48 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-11-29 00:20:48 +0000
commit7b32e8a67561a7989dbfc0f1d3480dca162c6769 (patch)
treed31e2adc1f9cce4f27ca07d30bee921032e33a3c
parentbc7f430decab0bc34a533811efe457d4615f28aa (diff)
parentbb2e798ef4d546dd54cd9e95796403062b860c15 (diff)
downloadTV-oreo-m5-release.tar.gz
Change-Id: I0aff16fbf430ba5e4dbba83b8e06e4a23b38060a
-rw-r--r--Android.mk25
-rw-r--r--AndroidManifest.xml65
-rw-r--r--assets/licenses.html298
-rw-r--r--assets/whitelist.policy39
-rw-r--r--common/Android.mk5
-rw-r--r--common/OWNERS2
-rw-r--r--common/res/drawable/setup_selector_background.xml3
-rw-r--r--common/res/layout/fragment_setup_multi_pane.xml25
-rw-r--r--common/res/values-af/strings.xml5
-rw-r--r--common/res/values-am/strings.xml5
-rw-r--r--common/res/values-ar/strings.xml5
-rw-r--r--common/res/values-az-rAZ/strings.xml28
-rw-r--r--common/res/values-az/strings.xml27
-rw-r--r--common/res/values-bg/strings.xml5
-rw-r--r--common/res/values-bn-rBD/strings.xml28
-rw-r--r--common/res/values-bn/strings.xml27
-rw-r--r--common/res/values-ca/strings.xml5
-rw-r--r--common/res/values-cs/strings.xml5
-rw-r--r--common/res/values-da/strings.xml5
-rw-r--r--common/res/values-de/strings.xml5
-rw-r--r--common/res/values-el/strings.xml5
-rw-r--r--common/res/values-en-rAU/strings.xml5
-rw-r--r--common/res/values-en-rGB/strings.xml5
-rw-r--r--common/res/values-en-rIN/strings.xml5
-rw-r--r--common/res/values-es-rUS/strings.xml5
-rw-r--r--common/res/values-es/strings.xml5
-rw-r--r--common/res/values-et-rEE/strings.xml28
-rw-r--r--common/res/values-et/strings.xml27
-rw-r--r--common/res/values-eu-rES/strings.xml28
-rw-r--r--common/res/values-eu/strings.xml27
-rw-r--r--common/res/values-fa/strings.xml5
-rw-r--r--common/res/values-fi/strings.xml5
-rw-r--r--common/res/values-fr-rCA/strings.xml5
-rw-r--r--common/res/values-fr/strings.xml5
-rw-r--r--common/res/values-gl-rES/strings.xml28
-rw-r--r--common/res/values-gl/strings.xml27
-rw-r--r--common/res/values-gu-rIN/strings.xml28
-rw-r--r--common/res/values-hi/strings.xml5
-rw-r--r--common/res/values-hr/strings.xml5
-rw-r--r--common/res/values-hu/strings.xml5
-rw-r--r--common/res/values-hy-rAM/strings.xml28
-rw-r--r--common/res/values-hy/strings.xml27
-rw-r--r--common/res/values-in/strings.xml5
-rw-r--r--common/res/values-is-rIS/strings.xml28
-rw-r--r--common/res/values-is/strings.xml27
-rw-r--r--common/res/values-it/strings.xml5
-rw-r--r--common/res/values-iw/strings.xml5
-rw-r--r--common/res/values-ja/strings.xml5
-rw-r--r--common/res/values-ka-rGE/strings.xml28
-rw-r--r--common/res/values-ka/strings.xml27
-rw-r--r--common/res/values-kk-rKZ/strings.xml28
-rw-r--r--common/res/values-kk/strings.xml27
-rw-r--r--common/res/values-km-rKH/strings.xml28
-rw-r--r--common/res/values-km/strings.xml27
-rw-r--r--common/res/values-kn-rIN/strings.xml28
-rw-r--r--common/res/values-kn/strings.xml27
-rw-r--r--common/res/values-ko/strings.xml5
-rw-r--r--common/res/values-ky-rKG/strings.xml28
-rw-r--r--common/res/values-ky/strings.xml27
-rw-r--r--common/res/values-lo-rLA/strings.xml28
-rw-r--r--common/res/values-lo/strings.xml27
-rw-r--r--common/res/values-lt/strings.xml5
-rw-r--r--common/res/values-lv/strings.xml5
-rw-r--r--common/res/values-mk-rMK/strings.xml28
-rw-r--r--common/res/values-mk/strings.xml27
-rw-r--r--common/res/values-ml-rIN/strings.xml28
-rw-r--r--common/res/values-ml/strings.xml27
-rw-r--r--common/res/values-mn-rMN/strings.xml28
-rw-r--r--common/res/values-mn/strings.xml27
-rw-r--r--common/res/values-mr-rIN/strings.xml28
-rw-r--r--common/res/values-mr/strings.xml27
-rw-r--r--common/res/values-ms-rMY/strings.xml28
-rw-r--r--common/res/values-ms/strings.xml27
-rw-r--r--common/res/values-my-rMM/strings.xml28
-rw-r--r--common/res/values-my/strings.xml27
-rw-r--r--common/res/values-nb/strings.xml5
-rw-r--r--common/res/values-ne-rNP/strings.xml28
-rw-r--r--common/res/values-ne/strings.xml27
-rw-r--r--common/res/values-nl/strings.xml5
-rw-r--r--common/res/values-pa-rIN/strings.xml28
-rw-r--r--common/res/values-pl/strings.xml5
-rw-r--r--common/res/values-pt-rPT/strings.xml5
-rw-r--r--common/res/values-pt/strings.xml5
-rw-r--r--common/res/values-ro/strings.xml5
-rw-r--r--common/res/values-ru/strings.xml5
-rw-r--r--common/res/values-si-rLK/strings.xml28
-rw-r--r--common/res/values-si/strings.xml27
-rw-r--r--common/res/values-sk/strings.xml5
-rw-r--r--common/res/values-sl/strings.xml5
-rw-r--r--common/res/values-sq-rAL/strings.xml28
-rw-r--r--common/res/values-sr/strings.xml5
-rw-r--r--common/res/values-sv/strings.xml5
-rw-r--r--common/res/values-sw/strings.xml5
-rw-r--r--common/res/values-ta-rIN/strings.xml28
-rw-r--r--common/res/values-ta/strings.xml27
-rw-r--r--common/res/values-te-rIN/strings.xml28
-rw-r--r--common/res/values-te/strings.xml27
-rw-r--r--common/res/values-th/strings.xml5
-rw-r--r--common/res/values-tl/strings.xml5
-rw-r--r--common/res/values-tr/strings.xml5
-rw-r--r--common/res/values-uk/strings.xml5
-rw-r--r--common/res/values-ur-rPK/strings.xml28
-rw-r--r--common/res/values-ur/strings.xml27
-rw-r--r--common/res/values-uz-rUZ/strings.xml28
-rw-r--r--common/res/values-uz/strings.xml27
-rw-r--r--common/res/values-vi/strings.xml5
-rw-r--r--common/res/values-zh-rCN/strings.xml5
-rw-r--r--common/res/values-zh-rHK/strings.xml5
-rw-r--r--common/res/values-zh-rTW/strings.xml5
-rw-r--r--common/res/values-zu/strings.xml5
-rw-r--r--common/res/values/dimens.xml7
-rw-r--r--common/res/values/strings.xml32
-rw-r--r--common/res/values/styles.xml6
-rw-r--r--common/res/values/themes.xml1
-rw-r--r--common/src/com/android/tv/common/SharedPreferencesUtils.java6
-rw-r--r--common/src/com/android/tv/common/TvCommonUtils.java17
-rw-r--r--common/src/com/android/tv/common/TvContentRatingCache.java5
-rw-r--r--common/src/com/android/tv/common/feature/CommonFeatures.java3
-rw-r--r--common/src/com/android/tv/common/feature/Sdk.java44
-rw-r--r--common/src/com/android/tv/common/feature/SharedPreferencesFeature.java1
-rw-r--r--common/src/com/android/tv/common/feature/TestableFeature.java15
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java5
-rw-r--r--common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java14
-rw-r--r--icu/icu4j/main/classes/core/src/com/ibm/icu/text/SCSU.java2
-rw-r--r--icu/icu4j/main/classes/core/src/com/ibm/icu/text/UnicodeDecompressor.java2
-rw-r--r--jni/Android.mk21
-rw-r--r--jni/DvbManager.cpp233
-rw-r--r--jni/DvbManager.h22
-rw-r--r--jni/minijail/Android.mk28
-rw-r--r--jni/minijail/minijail.cpp65
-rw-r--r--jni/minijail/minijail.h44
-rw-r--r--jni/tunertvinput_jni.cpp18
-rw-r--r--jni/tunertvinput_jni.h22
-rw-r--r--libs/exoplayer_v2.jarbin0 -> 1077775 bytes
-rw-r--r--libs/exoplayer_v2_ext_ffmpeg.jarbin0 -> 7271 bytes
-rw-r--r--proguard.flags4
-rw-r--r--proto/channel.proto5
-rw-r--r--proto/track.proto2
-rw-r--r--res/drawable-xhdpi/cloud01.pngbin2357 -> 2260 bytes
-rw-r--r--res/drawable-xhdpi/cloud02.pngbin1118 -> 936 bytes
-rw-r--r--res/drawable-xhdpi/dvr_default_poster.pngbin766 -> 747 bytes
-rw-r--r--res/drawable-xhdpi/dvr_default_program_art.pngbin11562 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_channel_guide.pngbin906 -> 737 bytes
-rw-r--r--res/drawable-xhdpi/ic_delete_32dp.pngbin802 -> 417 bytes
-rw-r--r--[-rwxr-xr-x]res/drawable-xhdpi/ic_developer_mode_tv_white_48dp.pngbin851 -> 552 bytes
-rw-r--r--res/drawable-xhdpi/ic_dvr.pngbin934 -> 713 bytes
-rw-r--r--res/drawable-xhdpi/ic_dvr_cancel.pngbin658 -> 413 bytes
-rw-r--r--res/drawable-xhdpi/ic_dvr_cancel_32dp.pngbin1514 -> 849 bytes
-rw-r--r--res/drawable-xhdpi/ic_dvr_cancel_large.pngbin1158 -> 755 bytes
-rw-r--r--res/drawable-xhdpi/ic_dvr_delete.pngbin657 -> 383 bytes
-rw-r--r--res/drawable-xhdpi/ic_error_recording.pngbin729 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_error_white_48dp.pngbin1117 -> 712 bytes
-rw-r--r--res/drawable-xhdpi/ic_fresh.pngbin13892 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_guide_lock.pngbin737 -> 673 bytes
-rw-r--r--res/drawable-xhdpi/ic_launcher_s.pngbin401 -> 363 bytes
-rw-r--r--res/drawable-xhdpi/ic_message_lock_no_permission.pngbin2147 -> 2052 bytes
-rw-r--r--res/drawable-xhdpi/ic_message_lock_preview.pngbin1847 -> 1639 bytes
-rw-r--r--res/drawable-xhdpi/ic_pip_option_input.pngbin270 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_pip_option_layout1.pngbin175 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_pip_option_layout2.pngbin176 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_pip_option_layout3.pngbin176 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_pip_option_layout4.pngbin175 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_pip_option_layout5.pngbin178 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_pip_option_size.pngbin155 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_pip_option_swap.pngbin241 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_pip_option_swap_audio.pngbin479 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_record_start.pngbin556 -> 494 bytes
-rw-r--r--res/drawable-xhdpi/ic_recorded_program.pngbin612 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_related_actor.pngbin1275 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_related_search.pngbin2707 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_schedule_32dp.pngbin1490 -> 821 bytes
-rw-r--r--res/drawable-xhdpi/ic_scheduled_recording.pngbin902 -> 556 bytes
-rw-r--r--res/drawable-xhdpi/ic_scheduled_white.pngbin491 -> 275 bytes
-rw-r--r--res/drawable-xhdpi/ic_setup_antenna.pngbin1264 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_setup_channels.pngbin1465 -> 1267 bytes
-rw-r--r--res/drawable-xhdpi/ic_tvoption_multi_track.pngbin412 -> 388 bytes
-rw-r--r--res/drawable-xhdpi/ic_tvoption_pip.pngbin192 -> 176 bytes
-rw-r--r--res/drawable-xhdpi/ic_tvoption_pip_off.pngbin261 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_tvsidepanel_partial_locked.pngbin754 -> 684 bytes
-rw-r--r--res/drawable-xhdpi/ic_warning_gray600_36dp.pngbin335 -> 329 bytes
-rw-r--r--res/drawable-xhdpi/ic_warning_white_12dp.pngbin242 -> 228 bytes
-rw-r--r--res/drawable-xhdpi/ic_warning_white_18dp.pngbin356 -> 329 bytes
-rw-r--r--res/drawable-xhdpi/ic_warning_white_32dp.pngbin553 -> 507 bytes
-rw-r--r--res/drawable-xhdpi/ic_warning_white_96dp.pngbin992 -> 976 bytes
-rw-r--r--res/drawable-xhdpi/ic_welcome_ripple_000.pngbin1120 -> 987 bytes
-rw-r--r--res/drawable-xhdpi/tv_3a_00.pngbin106 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_error.pngbin2846 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/tv_usb_antenna.pngbin21390 -> 0 bytes
-rw-r--r--res/drawable/play_controls_time_indicator.xml2
-rw-r--r--res/drawable/playback_progress_bar.xml33
-rw-r--r--res/drawable/priority_settings_action_item_selected.xml12
-rw-r--r--res/drawable/setup_item_background.xml28
-rw-r--r--res/layout/activity_dvr_playback.xml6
-rw-r--r--res/layout/activity_dvr_schedules.xml1
-rw-r--r--res/layout/activity_tv.xml22
-rw-r--r--res/layout/block_screen.xml11
-rw-r--r--res/layout/dvr_details_description.xml3
-rw-r--r--res/layout/dvr_main.xml2
-rw-r--r--res/layout/dvr_play.xml28
-rw-r--r--res/layout/dvr_recording_card_view.xml37
-rw-r--r--res/layout/dvr_schedules_item.xml12
-rw-r--r--res/layout/guided_action_editable.xml41
-rw-r--r--res/layout/input_banner.xml2
-rw-r--r--res/layout/list_item_dvr_history.xml59
-rw-r--r--res/layout/menu_card_action.xml57
-rw-r--r--res/layout/menu_card_app_link.xml7
-rw-r--r--res/layout/menu_card_channel.xml7
-rw-r--r--res/layout/menu_card_dvr.xml16
-rw-r--r--res/layout/menu_card_guide.xml16
-rw-r--r--res/layout/menu_card_setup.xml16
-rw-r--r--res/layout/menu_card_text.xml1
-rw-r--r--res/layout/option_container.xml2
-rw-r--r--res/layout/option_fragment.xml1
-rw-r--r--res/layout/option_item_action.xml15
-rw-r--r--res/layout/option_item_channel_check.xml1
-rw-r--r--res/layout/option_item_channel_lock.xml1
-rw-r--r--res/layout/option_item_check_box.xml1
-rw-r--r--res/layout/option_item_common.xml2
-rw-r--r--res/layout/option_item_radio_button.xml1
-rw-r--r--res/layout/option_item_switch.xml1
-rw-r--r--res/layout/play_controls_contents.xml218
-rw-r--r--res/layout/select_input_item.xml2
-rw-r--r--res/layout/tunable_tv_view.xml14
-rwxr-xr-xres/raw/third_party_license_metadata21
-rwxr-xr-xres/raw/third_party_licenses3751
-rw-r--r--res/transition/dvr_details_shared_element_enter_transition.xml46
-rw-r--r--res/transition/dvr_details_shared_element_return_transition.xml45
-rw-r--r--res/values-af/strings.xml103
-rw-r--r--res/values-am/strings.xml103
-rw-r--r--res/values-ar/strings.xml133
-rw-r--r--res/values-az-rAZ/arrays.xml (renamed from res/values-az/arrays.xml)0
-rw-r--r--res/values-az-rAZ/rating_system_strings.xml (renamed from res/values-az/rating_system_strings.xml)0
-rw-r--r--res/values-az-rAZ/strings.xml359
-rw-r--r--res/values-az/strings.xml352
-rw-r--r--res/values-bg/strings.xml105
-rw-r--r--res/values-bn-rBD-v23/strings.xml (renamed from res/values-bn-v23/strings.xml)0
-rw-r--r--res/values-bn-rBD/arrays.xml (renamed from res/values-bn/arrays.xml)0
-rw-r--r--res/values-bn-rBD/rating_system_strings.xml (renamed from res/values-bn/rating_system_strings.xml)0
-rw-r--r--res/values-bn-rBD/strings.xml357
-rw-r--r--res/values-bn/strings.xml350
-rw-r--r--res/values-ca/strings.xml111
-rw-r--r--res/values-cs/strings.xml119
-rw-r--r--res/values-da/strings.xml117
-rw-r--r--res/values-de/strings.xml149
-rw-r--r--res/values-el/strings.xml107
-rw-r--r--res/values-en-rAU/strings.xml103
-rw-r--r--res/values-en-rGB/strings.xml103
-rw-r--r--res/values-en-rIN/strings.xml103
-rw-r--r--res/values-es-rUS/strings.xml107
-rw-r--r--res/values-es/strings.xml115
-rw-r--r--res/values-et-rEE-v23/strings.xml (renamed from res/values-et-v23/strings.xml)0
-rw-r--r--res/values-et-rEE/arrays.xml (renamed from res/values-et/arrays.xml)0
-rw-r--r--res/values-et-rEE/rating_system_strings.xml (renamed from res/values-et/rating_system_strings.xml)0
-rw-r--r--res/values-et-rEE/strings.xml357
-rw-r--r--res/values-et/strings.xml350
-rw-r--r--res/values-eu-rES-v23/strings.xml (renamed from res/values-eu-v23/strings.xml)0
-rw-r--r--res/values-eu-rES/arrays.xml (renamed from res/values-eu/arrays.xml)0
-rw-r--r--res/values-eu-rES/rating_system_strings.xml (renamed from res/values-eu/rating_system_strings.xml)0
-rw-r--r--res/values-eu-rES/strings.xml357
-rw-r--r--res/values-eu/strings.xml350
-rw-r--r--res/values-fa/strings.xml103
-rw-r--r--res/values-fi/strings.xml103
-rw-r--r--res/values-fr-rCA/strings.xml107
-rw-r--r--res/values-fr/strings.xml107
-rw-r--r--res/values-gl-rES-v23/strings.xml (renamed from res/values-gl-v23/strings.xml)0
-rw-r--r--res/values-gl-rES/arrays.xml (renamed from res/values-gl/arrays.xml)0
-rw-r--r--res/values-gl-rES/rating_system_strings.xml (renamed from res/values-gl/rating_system_strings.xml)0
-rw-r--r--res/values-gl-rES/strings.xml357
-rw-r--r--res/values-gl/strings.xml350
-rw-r--r--res/values-gu-rIN/strings.xml356
-rw-r--r--res/values-hi/strings.xml103
-rw-r--r--res/values-hr/strings.xml108
-rw-r--r--res/values-hu/strings.xml113
-rw-r--r--res/values-hy-rAM-v23/strings.xml (renamed from res/values-hy-v23/strings.xml)0
-rw-r--r--res/values-hy-rAM/arrays.xml (renamed from res/values-hy/arrays.xml)0
-rw-r--r--res/values-hy-rAM/rating_system_strings.xml (renamed from res/values-hy/rating_system_strings.xml)0
-rw-r--r--res/values-hy-rAM/strings.xml357
-rw-r--r--res/values-hy/strings.xml350
-rw-r--r--res/values-in/strings.xml105
-rw-r--r--res/values-is-rIS-v23/strings.xml (renamed from res/values-is-v23/strings.xml)0
-rw-r--r--res/values-is-rIS/arrays.xml (renamed from res/values-is/arrays.xml)0
-rw-r--r--res/values-is-rIS/rating_system_strings.xml (renamed from res/values-is/rating_system_strings.xml)0
-rw-r--r--res/values-is-rIS/strings.xml357
-rw-r--r--res/values-is/strings.xml350
-rw-r--r--res/values-it/strings.xml117
-rw-r--r--res/values-iw/strings.xml113
-rw-r--r--res/values-ja/strings.xml117
-rw-r--r--res/values-ka-rGE-v23/strings.xml (renamed from res/values-ka-v23/strings.xml)0
-rw-r--r--res/values-ka-rGE/arrays.xml (renamed from res/values-ka/arrays.xml)0
-rw-r--r--res/values-ka-rGE/rating_system_strings.xml (renamed from res/values-ka/rating_system_strings.xml)0
-rw-r--r--res/values-ka-rGE/strings.xml357
-rw-r--r--res/values-ka/strings.xml350
-rw-r--r--res/values-kk-rKZ-v23/strings.xml (renamed from res/values-kk-v23/strings.xml)0
-rw-r--r--res/values-kk-rKZ/arrays.xml (renamed from res/values-kk/arrays.xml)0
-rw-r--r--res/values-kk-rKZ/rating_system_strings.xml (renamed from res/values-kk/rating_system_strings.xml)0
-rw-r--r--res/values-kk-rKZ/strings.xml357
-rw-r--r--res/values-kk/strings.xml350
-rw-r--r--res/values-km-rKH-v23/strings.xml (renamed from res/values-km-v23/strings.xml)0
-rw-r--r--res/values-km-rKH/arrays.xml (renamed from res/values-km/arrays.xml)0
-rw-r--r--res/values-km-rKH/rating_system_strings.xml (renamed from res/values-km/rating_system_strings.xml)0
-rw-r--r--res/values-km-rKH/strings.xml357
-rw-r--r--res/values-km/strings.xml350
-rw-r--r--res/values-kn-rIN-v23/strings.xml (renamed from res/values-kn-v23/strings.xml)0
-rw-r--r--res/values-kn-rIN/arrays.xml (renamed from res/values-kn/arrays.xml)0
-rw-r--r--res/values-kn-rIN/rating_system_strings.xml (renamed from res/values-kn/rating_system_strings.xml)0
-rw-r--r--res/values-kn-rIN/strings.xml357
-rw-r--r--res/values-kn/strings.xml350
-rw-r--r--res/values-ko/strings.xml103
-rw-r--r--res/values-ky-rKG-v23/strings.xml (renamed from res/values-ky-v23/strings.xml)0
-rw-r--r--res/values-ky-rKG/arrays.xml (renamed from res/values-ky/arrays.xml)0
-rw-r--r--res/values-ky-rKG/rating_system_strings.xml (renamed from res/values-ky/rating_system_strings.xml)0
-rw-r--r--res/values-ky-rKG/strings.xml357
-rw-r--r--res/values-ky/strings.xml350
-rw-r--r--res/values-ldrtl/dimens.xml1
-rw-r--r--res/values-lo-rLA-v23/strings.xml (renamed from res/values-lo-v23/strings.xml)0
-rw-r--r--res/values-lo-rLA/arrays.xml (renamed from res/values-lo/arrays.xml)0
-rw-r--r--res/values-lo-rLA/rating_system_strings.xml (renamed from res/values-lo/rating_system_strings.xml)0
-rw-r--r--res/values-lo-rLA/strings.xml357
-rw-r--r--res/values-lo/strings.xml350
-rw-r--r--res/values-lt/strings.xml113
-rw-r--r--res/values-lv/strings.xml108
-rw-r--r--res/values-mk-rMK-v23/strings.xml (renamed from res/values-mk-v23/strings.xml)0
-rw-r--r--res/values-mk-rMK/arrays.xml (renamed from res/values-mk/arrays.xml)0
-rw-r--r--res/values-mk-rMK/rating_system_strings.xml (renamed from res/values-mk/rating_system_strings.xml)0
-rw-r--r--res/values-mk-rMK/strings.xml357
-rw-r--r--res/values-mk/strings.xml350
-rw-r--r--res/values-ml-rIN-v23/strings.xml (renamed from res/values-ml-v23/strings.xml)0
-rw-r--r--res/values-ml-rIN/arrays.xml (renamed from res/values-ml/arrays.xml)0
-rw-r--r--res/values-ml-rIN/rating_system_strings.xml (renamed from res/values-ml/rating_system_strings.xml)0
-rw-r--r--res/values-ml-rIN/strings.xml355
-rw-r--r--res/values-ml/strings.xml348
-rw-r--r--res/values-mn-rMN-v23/strings.xml (renamed from res/values-mn-v23/strings.xml)0
-rw-r--r--res/values-mn-rMN/arrays.xml (renamed from res/values-mn/arrays.xml)0
-rw-r--r--res/values-mn-rMN/rating_system_strings.xml (renamed from res/values-mn/rating_system_strings.xml)0
-rw-r--r--res/values-mn-rMN/strings.xml355
-rw-r--r--res/values-mn/strings.xml348
-rw-r--r--res/values-mr-rIN-v23/strings.xml (renamed from res/values-mr-v23/strings.xml)0
-rw-r--r--res/values-mr-rIN/arrays.xml (renamed from res/values-mr/arrays.xml)0
-rw-r--r--res/values-mr-rIN/rating_system_strings.xml (renamed from res/values-mr/rating_system_strings.xml)0
-rw-r--r--res/values-mr-rIN/strings.xml357
-rw-r--r--res/values-mr/strings.xml350
-rw-r--r--res/values-ms-rMY-v23/strings.xml (renamed from res/values-ms-v23/strings.xml)0
-rw-r--r--res/values-ms-rMY/arrays.xml (renamed from res/values-ms/arrays.xml)0
-rw-r--r--res/values-ms-rMY/rating_system_strings.xml (renamed from res/values-ms/rating_system_strings.xml)0
-rw-r--r--res/values-ms-rMY/strings.xml357
-rw-r--r--res/values-ms/strings.xml350
-rw-r--r--res/values-my-rMM-v23/strings.xml (renamed from res/values-my-v23/strings.xml)0
-rw-r--r--res/values-my-rMM/arrays.xml (renamed from res/values-my/arrays.xml)0
-rw-r--r--res/values-my-rMM/rating_system_strings.xml (renamed from res/values-my/rating_system_strings.xml)0
-rw-r--r--res/values-my-rMM/strings.xml357
-rw-r--r--res/values-my/strings.xml350
-rw-r--r--res/values-nb/strings.xml103
-rw-r--r--res/values-ne-rNP-v23/strings.xml (renamed from res/values-ne-v23/strings.xml)0
-rw-r--r--res/values-ne-rNP/arrays.xml (renamed from res/values-ne/arrays.xml)0
-rw-r--r--res/values-ne-rNP/rating_system_strings.xml (renamed from res/values-ne/rating_system_strings.xml)0
-rw-r--r--res/values-ne-rNP/strings.xml357
-rw-r--r--res/values-ne/strings.xml350
-rw-r--r--res/values-nl/strings.xml109
-rw-r--r--res/values-pa-rIN/strings.xml356
-rw-r--r--res/values-pl/strings.xml115
-rw-r--r--res/values-pt-rPT/strings.xml131
-rw-r--r--res/values-pt/strings.xml131
-rw-r--r--res/values-ro/strings.xml108
-rw-r--r--res/values-ru/strings.xml113
-rw-r--r--res/values-si-rLK-v23/strings.xml (renamed from res/values-si-v23/strings.xml)0
-rw-r--r--res/values-si-rLK/arrays.xml (renamed from res/values-si/arrays.xml)0
-rw-r--r--res/values-si-rLK/rating_system_strings.xml (renamed from res/values-si/rating_system_strings.xml)0
-rw-r--r--res/values-si-rLK/strings.xml357
-rw-r--r--res/values-si/strings.xml350
-rw-r--r--res/values-sk/strings.xml133
-rw-r--r--res/values-sl/strings.xml119
-rw-r--r--res/values-sq-rAL/strings.xml356
-rw-r--r--res/values-sr/strings.xml110
-rw-r--r--res/values-sv/strings.xml107
-rw-r--r--res/values-sw/strings.xml107
-rw-r--r--res/values-ta-rIN-v23/strings.xml (renamed from res/values-ta-v23/strings.xml)0
-rw-r--r--res/values-ta-rIN/arrays.xml (renamed from res/values-ta/arrays.xml)0
-rw-r--r--res/values-ta-rIN/rating_system_strings.xml (renamed from res/values-ta/rating_system_strings.xml)0
-rw-r--r--res/values-ta-rIN/strings.xml357
-rw-r--r--res/values-ta/strings.xml350
-rw-r--r--res/values-te-rIN-v23/strings.xml (renamed from res/values-te-v23/strings.xml)0
-rw-r--r--res/values-te-rIN/arrays.xml (renamed from res/values-te/arrays.xml)0
-rw-r--r--res/values-te-rIN/rating_system_strings.xml (renamed from res/values-te/rating_system_strings.xml)0
-rw-r--r--res/values-te-rIN/strings.xml357
-rw-r--r--res/values-te/strings.xml350
-rw-r--r--res/values-th/strings.xml105
-rw-r--r--res/values-tl/strings.xml107
-rw-r--r--res/values-tr/strings.xml105
-rw-r--r--res/values-uk/strings.xml117
-rw-r--r--res/values-ur-rPK-v23/strings.xml (renamed from res/values-ur-v23/strings.xml)0
-rw-r--r--res/values-ur-rPK/arrays.xml (renamed from res/values-ur/arrays.xml)0
-rw-r--r--res/values-ur-rPK/rating_system_strings.xml (renamed from res/values-ur/rating_system_strings.xml)0
-rw-r--r--res/values-ur-rPK/strings.xml357
-rw-r--r--res/values-ur/strings.xml350
-rw-r--r--res/values-uz-rUZ-v23/strings.xml (renamed from res/values-uz-v23/strings.xml)0
-rw-r--r--res/values-uz-rUZ/arrays.xml (renamed from res/values-uz/arrays.xml)0
-rw-r--r--res/values-uz-rUZ/rating_system_strings.xml (renamed from res/values-uz/rating_system_strings.xml)0
-rw-r--r--res/values-uz-rUZ/strings.xml357
-rw-r--r--res/values-uz/strings.xml350
-rw-r--r--res/values-v23/strings.xml21
-rw-r--r--res/values-vi/strings.xml103
-rw-r--r--res/values-zh-rCN/strings.xml129
-rw-r--r--res/values-zh-rHK/strings.xml103
-rw-r--r--res/values-zh-rTW/strings.xml105
-rw-r--r--res/values-zu/strings.xml103
-rw-r--r--res/values/attr.xml25
-rw-r--r--res/values/attrs.xml48
-rw-r--r--res/values/colors.xml4
-rw-r--r--res/values/dimens.xml69
-rwxr-xr-xres/values/google-services.xml8
-rw-r--r--res/values/integers.xml9
-rw-r--r--res/values/strings.xml299
-rw-r--r--res/values/styles.xml7
-rw-r--r--res/values/themes.xml7
-rw-r--r--res/xml/remote_config_defaults.xml15
-rw-r--r--src/com/android/exoplayer/text/SubtitleView.java4
-rw-r--r--src/com/android/exoplayer2/ext/ffmpeg/FfmpegAudioDecoder.java127
-rw-r--r--src/com/android/exoplayer2/ext/ffmpeg/FfmpegLibrary.java84
-rw-r--r--src/com/android/tv/ApplicationSingletons.java27
-rw-r--r--src/com/android/tv/AudioManagerHelper.java108
-rw-r--r--src/com/android/tv/Features.java151
-rw-r--r--src/com/android/tv/InputSessionManager.java30
-rw-r--r--src/com/android/tv/MainActivity.java1498
-rw-r--r--src/com/android/tv/MainActivityWrapper.java2
-rw-r--r--src/com/android/tv/MediaSessionWrapper.java216
-rw-r--r--src/com/android/tv/SetupPassthroughActivity.java176
-rw-r--r--src/com/android/tv/TimeShiftManager.java26
-rw-r--r--src/com/android/tv/TvApplication.java162
-rw-r--r--src/com/android/tv/TvOptionsManager.java133
-rw-r--r--src/com/android/tv/analytics/DurationTimer.java62
-rw-r--r--src/com/android/tv/config/DefaultConfigManager.java6
-rw-r--r--src/com/android/tv/config/RemoteConfig.java3
-rw-r--r--src/com/android/tv/config/RemoteConfigUtils.java42
-rw-r--r--src/com/android/tv/customization/TvCustomizationManager.java118
-rw-r--r--src/com/android/tv/data/BaseProgram.java39
-rw-r--r--src/com/android/tv/data/Channel.java114
-rw-r--r--src/com/android/tv/data/ChannelDataManager.java200
-rw-r--r--src/com/android/tv/data/ChannelLogoFetcher.java307
-rw-r--r--src/com/android/tv/data/ChannelNumber.java71
-rw-r--r--src/com/android/tv/data/InternalDataUtils.java2
-rw-r--r--src/com/android/tv/data/PreviewDataManager.java636
-rw-r--r--src/com/android/tv/data/PreviewProgramContent.java259
-rw-r--r--src/com/android/tv/data/Program.java140
-rw-r--r--src/com/android/tv/data/ProgramDataManager.java76
-rw-r--r--src/com/android/tv/data/StreamInfo.java4
-rw-r--r--src/com/android/tv/data/WatchedHistoryManager.java161
-rw-r--r--src/com/android/tv/data/epg/EpgFetchHelper.java233
-rw-r--r--src/com/android/tv/data/epg/EpgFetcher.java988
-rw-r--r--src/com/android/tv/data/epg/EpgReader.java45
-rw-r--r--src/com/android/tv/data/epg/StubEpgReader.java37
-rw-r--r--src/com/android/tv/dialog/DvrHistoryDialogFragment.java130
-rw-r--r--src/com/android/tv/dialog/FullscreenDialogFragment.java2
-rw-r--r--src/com/android/tv/dialog/HalfSizedDialogFragment.java123
-rw-r--r--src/com/android/tv/dialog/PinDialogFragment.java103
-rw-r--r--src/com/android/tv/dialog/SafeDismissDialogFragment.java26
-rw-r--r--src/com/android/tv/dialog/WebDialogFragment.java17
-rw-r--r--src/com/android/tv/dvr/BaseDvrDataManager.java41
-rw-r--r--src/com/android/tv/dvr/ConflictChecker.java277
-rw-r--r--src/com/android/tv/dvr/DvrDataManager.java12
-rw-r--r--src/com/android/tv/dvr/DvrDataManagerImpl.java151
-rw-r--r--src/com/android/tv/dvr/DvrDbSync.java363
-rw-r--r--src/com/android/tv/dvr/DvrManager.java113
-rw-r--r--src/com/android/tv/dvr/DvrPlaybackActivity.java67
-rw-r--r--src/com/android/tv/dvr/DvrPlaybackMediaSessionHelper.java327
-rw-r--r--src/com/android/tv/dvr/DvrPlayer.java425
-rw-r--r--src/com/android/tv/dvr/DvrRecordingService.java122
-rw-r--r--src/com/android/tv/dvr/DvrScheduleManager.java139
-rw-r--r--src/com/android/tv/dvr/DvrStartRecordingReceiver.java34
-rw-r--r--src/com/android/tv/dvr/DvrStorageStatusManager.java35
-rw-r--r--src/com/android/tv/dvr/DvrUiHelper.java450
-rw-r--r--src/com/android/tv/dvr/DvrWatchedPositionManager.java4
-rw-r--r--src/com/android/tv/dvr/EpisodicProgramLoadTask.java382
-rw-r--r--src/com/android/tv/dvr/IdGenerator.java50
-rw-r--r--src/com/android/tv/dvr/InputTaskScheduler.java431
-rw-r--r--src/com/android/tv/dvr/RecordedProgram.java868
-rw-r--r--src/com/android/tv/dvr/RecordingTask.java519
-rw-r--r--src/com/android/tv/dvr/ScheduledProgramReaper.java67
-rw-r--r--src/com/android/tv/dvr/ScheduledRecording.java887
-rw-r--r--src/com/android/tv/dvr/Scheduler.java283
-rw-r--r--src/com/android/tv/dvr/SeriesInfo.java76
-rw-r--r--src/com/android/tv/dvr/SeriesRecording.java755
-rw-r--r--src/com/android/tv/dvr/SeriesRecordingScheduler.java579
-rw-r--r--src/com/android/tv/dvr/WritableDvrDataManager.java6
-rw-r--r--src/com/android/tv/dvr/data/IdGenerator.java50
-rw-r--r--src/com/android/tv/dvr/data/RecordedProgram.java845
-rw-r--r--src/com/android/tv/dvr/data/ScheduledRecording.java882
-rw-r--r--src/com/android/tv/dvr/data/SeasonEpisodeNumber.java72
-rw-r--r--src/com/android/tv/dvr/data/SeriesInfo.java76
-rw-r--r--src/com/android/tv/dvr/data/SeriesRecording.java755
-rw-r--r--src/com/android/tv/dvr/provider/AsyncDvrDbTask.java4
-rw-r--r--src/com/android/tv/dvr/provider/DvrDatabaseHelper.java4
-rw-r--r--src/com/android/tv/dvr/provider/DvrDbSync.java373
-rw-r--r--src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java329
-rw-r--r--src/com/android/tv/dvr/recorder/ConflictChecker.java280
-rw-r--r--src/com/android/tv/dvr/recorder/DvrRecordingService.java207
-rw-r--r--src/com/android/tv/dvr/recorder/DvrStartRecordingReceiver.java40
-rw-r--r--src/com/android/tv/dvr/recorder/InputTaskScheduler.java429
-rw-r--r--src/com/android/tv/dvr/recorder/RecordingScheduler.java329
-rw-r--r--src/com/android/tv/dvr/recorder/RecordingTask.java529
-rw-r--r--src/com/android/tv/dvr/recorder/ScheduledProgramReaper.java70
-rw-r--r--src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java563
-rw-r--r--src/com/android/tv/dvr/ui/ActionPresenterSelector.java138
-rw-r--r--src/com/android/tv/dvr/ui/BigArguments.java54
-rw-r--r--src/com/android/tv/dvr/ui/ChangeImageTransformWithScaledParent.java79
-rw-r--r--src/com/android/tv/dvr/ui/CurrentRecordingDetailsFragment.java59
-rw-r--r--src/com/android/tv/dvr/ui/DetailsContent.java207
-rw-r--r--src/com/android/tv/dvr/ui/DetailsContentPresenter.java300
-rw-r--r--src/com/android/tv/dvr/ui/DetailsViewBackgroundHelper.java92
-rw-r--r--src/com/android/tv/dvr/ui/DvrActivity.java35
-rw-r--r--src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java26
-rw-r--r--src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java26
-rw-r--r--src/com/android/tv/dvr/ui/DvrBrowseFragment.java601
-rw-r--r--src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java25
-rw-r--r--src/com/android/tv/dvr/ui/DvrConflictFragment.java48
-rw-r--r--src/com/android/tv/dvr/ui/DvrDetailsActivity.java98
-rw-r--r--src/com/android/tv/dvr/ui/DvrDetailsFragment.java344
-rw-r--r--src/com/android/tv/dvr/ui/DvrForgetStorageErrorFragment.java87
-rw-r--r--src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java116
-rw-r--r--src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java39
-rw-r--r--src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java101
-rw-r--r--src/com/android/tv/dvr/ui/DvrItemPresenter.java80
-rw-r--r--src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java67
-rw-r--r--src/com/android/tv/dvr/ui/DvrPlaybackCardPresenter.java82
-rw-r--r--src/com/android/tv/dvr/ui/DvrPlaybackControlHelper.java313
-rw-r--r--src/com/android/tv/dvr/ui/DvrPlaybackOverlayFragment.java304
-rw-r--r--src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java262
-rw-r--r--src/com/android/tv/dvr/ui/DvrScheduleFragment.java36
-rw-r--r--src/com/android/tv/dvr/ui/DvrSchedulesActivity.java104
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java5
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java253
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java62
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java20
-rw-r--r--src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java366
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java29
-rw-r--r--src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java20
-rw-r--r--src/com/android/tv/dvr/ui/DvrUiHelper.java649
-rw-r--r--src/com/android/tv/dvr/ui/FadeBackground.java70
-rw-r--r--src/com/android/tv/dvr/ui/FullScheduleCardHolder.java29
-rw-r--r--src/com/android/tv/dvr/ui/FullSchedulesCardPresenter.java84
-rw-r--r--src/com/android/tv/dvr/ui/HalfSizedDialogFragment.java117
-rw-r--r--src/com/android/tv/dvr/ui/PrioritySettingsFragment.java251
-rw-r--r--src/com/android/tv/dvr/ui/RecordedProgramDetailsFragment.java170
-rw-r--r--src/com/android/tv/dvr/ui/RecordedProgramPresenter.java182
-rw-r--r--src/com/android/tv/dvr/ui/RecordingCardView.java185
-rw-r--r--src/com/android/tv/dvr/ui/RecordingDetailsFragment.java87
-rw-r--r--src/com/android/tv/dvr/ui/ScheduledRecordingDetailsFragment.java97
-rw-r--r--src/com/android/tv/dvr/ui/ScheduledRecordingPresenter.java177
-rw-r--r--src/com/android/tv/dvr/ui/SeriesDeletionFragment.java252
-rw-r--r--src/com/android/tv/dvr/ui/SeriesRecordingDetailsFragment.java375
-rw-r--r--src/com/android/tv/dvr/ui/SeriesRecordingPresenter.java234
-rw-r--r--src/com/android/tv/dvr/ui/SeriesSettingsFragment.java397
-rw-r--r--src/com/android/tv/dvr/ui/SortedArrayAdapter.java90
-rw-r--r--src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java82
-rw-r--r--src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java134
-rw-r--r--src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java120
-rw-r--r--src/com/android/tv/dvr/ui/browse/DetailsContent.java317
-rw-r--r--src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java319
-rw-r--r--src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java92
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java52
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java665
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrDetailsActivity.java154
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java307
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java140
-rw-r--r--src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java34
-rw-r--r--src/com/android/tv/dvr/ui/browse/FullScheduleCardHolder.java29
-rw-r--r--src/com/android/tv/dvr/ui/browse/FullSchedulesCardPresenter.java84
-rw-r--r--src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java149
-rw-r--r--src/com/android/tv/dvr/ui/browse/RecordedProgramPresenter.java142
-rw-r--r--src/com/android/tv/dvr/ui/browse/RecordingCardView.java290
-rw-r--r--src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java51
-rw-r--r--src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java97
-rw-r--r--src/com/android/tv/dvr/ui/browse/ScheduledRecordingPresenter.java138
-rw-r--r--src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java354
-rw-r--r--src/com/android/tv/dvr/ui/browse/SeriesRecordingPresenter.java216
-rw-r--r--src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java5
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java116
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java5
-rw-r--r--src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java72
-rw-r--r--src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java9
-rw-r--r--src/com/android/tv/dvr/ui/list/ScheduleRow.java8
-rw-r--r--src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java4
-rw-r--r--src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java50
-rw-r--r--src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java20
-rw-r--r--src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java26
-rw-r--r--src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java24
-rw-r--r--src/com/android/tv/dvr/ui/list/SeriesScheduleRowPresenter.java17
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java94
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackCardPresenter.java45
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java373
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackMediaSessionHelper.java335
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java494
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java154
-rw-r--r--src/com/android/tv/dvr/ui/playback/DvrPlayer.java583
-rw-r--r--src/com/android/tv/experiments/ExperimentFlag.java32
-rw-r--r--src/com/android/tv/experiments/Experiments.java9
-rw-r--r--src/com/android/tv/guide/GenreListAdapter.java23
-rw-r--r--src/com/android/tv/guide/GuideUtils.java110
-rw-r--r--src/com/android/tv/guide/ProgramGrid.java270
-rw-r--r--src/com/android/tv/guide/ProgramGuide.java265
-rw-r--r--src/com/android/tv/guide/ProgramItemView.java33
-rw-r--r--src/com/android/tv/guide/ProgramListAdapter.java36
-rw-r--r--src/com/android/tv/guide/ProgramManager.java656
-rw-r--r--src/com/android/tv/guide/ProgramRow.java33
-rw-r--r--src/com/android/tv/guide/ProgramTableAdapter.java172
-rw-r--r--src/com/android/tv/guide/TimeListAdapter.java35
-rw-r--r--src/com/android/tv/license/License.java112
-rw-r--r--src/com/android/tv/license/LicenseDialogFragment.java97
-rw-r--r--src/com/android/tv/license/LicenseSideFragment.java80
-rw-r--r--src/com/android/tv/license/LicenseUtils.java12
-rw-r--r--src/com/android/tv/license/Licenses.java122
-rw-r--r--src/com/android/tv/menu/ActionCardView.java6
-rw-r--r--src/com/android/tv/menu/AppLinkCardView.java286
-rw-r--r--src/com/android/tv/menu/BaseCardView.java86
-rw-r--r--src/com/android/tv/menu/ChannelCardView.java140
-rw-r--r--src/com/android/tv/menu/ChannelsPosterPrefetcher.java9
-rw-r--r--src/com/android/tv/menu/ChannelsRow.java10
-rw-r--r--src/com/android/tv/menu/ChannelsRowAdapter.java198
-rw-r--r--src/com/android/tv/menu/ChannelsRowItem.java101
-rw-r--r--src/com/android/tv/menu/ItemListRowView.java20
-rw-r--r--src/com/android/tv/menu/Menu.java43
-rw-r--r--src/com/android/tv/menu/MenuAction.java69
-rw-r--r--src/com/android/tv/menu/MenuLayoutManager.java54
-rw-r--r--src/com/android/tv/menu/MenuRow.java5
-rw-r--r--src/com/android/tv/menu/MenuRowFactory.java33
-rw-r--r--src/com/android/tv/menu/MenuUpdater.java48
-rw-r--r--src/com/android/tv/menu/OptionsRowAdapter.java50
-rw-r--r--src/com/android/tv/menu/PartnerOptionsRowAdapter.java3
-rw-r--r--src/com/android/tv/menu/PipOptionsRowAdapter.java137
-rw-r--r--src/com/android/tv/menu/PlayControlsButton.java24
-rw-r--r--src/com/android/tv/menu/PlayControlsRowView.java194
-rw-r--r--src/com/android/tv/menu/PlaybackProgressBar.java168
-rw-r--r--src/com/android/tv/menu/SimpleCardView.java4
-rw-r--r--src/com/android/tv/menu/TvOptionsRowAdapter.java138
-rw-r--r--src/com/android/tv/onboarding/SetupSourcesFragment.java2
-rw-r--r--src/com/android/tv/parental/ContentRatingSystem.java9
-rw-r--r--src/com/android/tv/parental/ContentRatingsManager.java19
-rw-r--r--src/com/android/tv/parental/ParentalControlSettings.java33
-rw-r--r--src/com/android/tv/perf/EventNames.java56
-rw-r--r--src/com/android/tv/perf/PerformanceMonitor.java99
-rw-r--r--src/com/android/tv/perf/StubPerformanceMonitor.java65
-rw-r--r--src/com/android/tv/perf/TimerEvent.java20
-rw-r--r--src/com/android/tv/receiver/BootCompletedReceiver.java27
-rw-r--r--src/com/android/tv/receiver/GlobalKeyReceiver.java52
-rw-r--r--src/com/android/tv/receiver/PackageIntentsReceiver.java12
-rw-r--r--src/com/android/tv/recommendation/ChannelPreviewUpdater.java323
-rw-r--r--src/com/android/tv/recommendation/NotificationService.java11
-rw-r--r--src/com/android/tv/recommendation/RecommendationDataManager.java6
-rw-r--r--src/com/android/tv/recommendation/RecordedProgramPreviewUpdater.java176
-rw-r--r--src/com/android/tv/search/DataManagerSearch.java4
-rw-r--r--src/com/android/tv/search/LocalSearchProvider.java105
-rw-r--r--src/com/android/tv/search/SearchInterface.java4
-rw-r--r--src/com/android/tv/search/TvProviderSearch.java10
-rw-r--r--src/com/android/tv/tuner/ChannelScanFileParser.java4
-rw-r--r--src/com/android/tv/tuner/DvbTunerHal.java179
-rw-r--r--src/com/android/tv/tuner/TunerHal.java129
-rw-r--r--src/com/android/tv/tuner/TunerInputController.java338
-rw-r--r--src/com/android/tv/tuner/TunerPreferences.java196
-rw-r--r--src/com/android/tv/tuner/UsbTunerHal.java174
-rw-r--r--src/com/android/tv/tuner/cc/CaptionTrackRenderer.java4
-rw-r--r--src/com/android/tv/tuner/cc/Cea708Parser.java14
-rw-r--r--src/com/android/tv/tuner/data/PsipData.java133
-rw-r--r--src/com/android/tv/tuner/data/TunerChannel.java163
-rw-r--r--src/com/android/tv/tuner/exoplayer/Cea708TextTrackRenderer.java29
-rw-r--r--src/com/android/tv/tuner/exoplayer/ExoPlayerExtractorsFactory.java41
-rw-r--r--src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java378
-rw-r--r--src/com/android/tv/tuner/exoplayer/FileSampleExtractor.java14
-rw-r--r--src/com/android/tv/tuner/exoplayer/MpegTsPlayer.java89
-rw-r--r--src/com/android/tv/tuner/exoplayer/MpegTsRendererBuilder.java20
-rw-r--r--src/com/android/tv/tuner/exoplayer/ac3/Ac3PassthroughTrackRenderer.java540
-rw-r--r--src/com/android/tv/tuner/exoplayer/ac3/Ac3TrackRenderer.java94
-rw-r--r--src/com/android/tv/tuner/exoplayer/ac3/AudioClock.java107
-rw-r--r--src/com/android/tv/tuner/exoplayer/ac3/AudioTrackMonitor.java121
-rw-r--r--src/com/android/tv/tuner/exoplayer/ac3/AudioTrackWrapper.java164
-rw-r--r--src/com/android/tv/tuner/exoplayer/audio/AudioClock.java107
-rw-r--r--src/com/android/tv/tuner/exoplayer/audio/AudioDecoder.java70
-rw-r--r--src/com/android/tv/tuner/exoplayer/audio/AudioTrackMonitor.java129
-rw-r--r--src/com/android/tv/tuner/exoplayer/audio/AudioTrackWrapper.java176
-rw-r--r--src/com/android/tv/tuner/exoplayer/audio/MediaCodecAudioDecoder.java235
-rw-r--r--src/com/android/tv/tuner/exoplayer/audio/MpegTsDefaultAudioTrackRenderer.java735
-rw-r--r--src/com/android/tv/tuner/exoplayer/audio/MpegTsMediaCodecAudioTrackRenderer.java94
-rw-r--r--src/com/android/tv/tuner/exoplayer/buffer/BufferManager.java280
-rw-r--r--src/com/android/tv/tuner/exoplayer/buffer/DvrStorageManager.java209
-rw-r--r--src/com/android/tv/tuner/exoplayer/buffer/RecordingSampleBuffer.java23
-rw-r--r--src/com/android/tv/tuner/exoplayer/buffer/SampleChunk.java24
-rw-r--r--src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java115
-rw-r--r--src/com/android/tv/tuner/exoplayer/buffer/SampleQueue.java1
-rw-r--r--src/com/android/tv/tuner/exoplayer/buffer/SimpleSampleBuffer.java8
-rw-r--r--src/com/android/tv/tuner/exoplayer/buffer/TrickplayStorageManager.java85
-rw-r--r--src/com/android/tv/tuner/exoplayer/ffmpeg/FfmpegDecoderClient.java249
-rw-r--r--src/com/android/tv/tuner/exoplayer/ffmpeg/FfmpegDecoderService.java205
-rw-r--r--src/com/android/tv/tuner/exoplayer/ffmpeg/IFfmpegDecoder.aidl29
-rw-r--r--src/com/android/tv/tuner/setup/ConnectionTypeFragment.java19
-rw-r--r--src/com/android/tv/tuner/setup/PostalCodeFragment.java178
-rw-r--r--src/com/android/tv/tuner/setup/ScanFragment.java72
-rw-r--r--src/com/android/tv/tuner/setup/ScanResultFragment.java17
-rw-r--r--src/com/android/tv/tuner/setup/TunerSetupActivity.java375
-rw-r--r--src/com/android/tv/tuner/setup/WelcomeFragment.java54
-rw-r--r--src/com/android/tv/tuner/source/FileTsStreamer.java24
-rw-r--r--src/com/android/tv/tuner/source/TsDataSourceManager.java16
-rw-r--r--src/com/android/tv/tuner/source/TunerTsStreamer.java79
-rw-r--r--src/com/android/tv/tuner/source/TunerTsStreamerManager.java25
-rw-r--r--src/com/android/tv/tuner/ts/SectionParser.java569
-rw-r--r--src/com/android/tv/tuner/ts/TsParser.java74
-rw-r--r--src/com/android/tv/tuner/tvinput/ChannelDataManager.java54
-rw-r--r--src/com/android/tv/tuner/tvinput/EventDetector.java101
-rw-r--r--src/com/android/tv/tuner/tvinput/FileSourceEventDetector.java45
-rw-r--r--src/com/android/tv/tuner/tvinput/TunerDebug.java4
-rw-r--r--src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java116
-rw-r--r--src/com/android/tv/tuner/tvinput/TunerSession.java38
-rw-r--r--src/com/android/tv/tuner/tvinput/TunerSessionWorker.java457
-rw-r--r--src/com/android/tv/tuner/tvinput/TunerStorageCleanUpService.java8
-rw-r--r--src/com/android/tv/tuner/tvinput/TunerTvInputService.java35
-rw-r--r--src/com/android/tv/tuner/util/PostalCodeUtils.java138
-rw-r--r--src/com/android/tv/tuner/util/StringUtils.java38
-rw-r--r--src/com/android/tv/tuner/util/SystemPropertiesProxy.java16
-rw-r--r--src/com/android/tv/tuner/util/TunerInputInfoUtils.java87
-rw-r--r--src/com/android/tv/ui/AppLayerTvView.java14
-rw-r--r--src/com/android/tv/ui/BlockScreenView.java137
-rw-r--r--src/com/android/tv/ui/ChannelBannerView.java189
-rw-r--r--src/com/android/tv/ui/KeypadChannelSwitchView.java2
-rw-r--r--src/com/android/tv/ui/SelectInputView.java74
-rw-r--r--src/com/android/tv/ui/TunableTvView.java644
-rw-r--r--src/com/android/tv/ui/TvOverlayManager.java231
-rw-r--r--src/com/android/tv/ui/TvTransitionManager.java2
-rw-r--r--src/com/android/tv/ui/TvViewUiManager.java408
-rw-r--r--src/com/android/tv/ui/sidepanel/ActionItem.java20
-rw-r--r--src/com/android/tv/ui/sidepanel/ClosedCaptionFragment.java108
-rw-r--r--src/com/android/tv/ui/sidepanel/CompoundButtonItem.java21
-rw-r--r--src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java116
-rw-r--r--src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java45
-rw-r--r--src/com/android/tv/ui/sidepanel/Item.java12
-rw-r--r--src/com/android/tv/ui/sidepanel/PipInputSelectorFragment.java170
-rw-r--r--src/com/android/tv/ui/sidepanel/SettingsFragment.java137
-rw-r--r--src/com/android/tv/ui/sidepanel/SideFragment.java158
-rw-r--r--src/com/android/tv/ui/sidepanel/SideFragmentManager.java38
-rw-r--r--src/com/android/tv/ui/sidepanel/SimpleActionItem.java34
-rw-r--r--src/com/android/tv/ui/sidepanel/SimpleItem.java34
-rw-r--r--src/com/android/tv/ui/sidepanel/SubMenuItem.java13
-rw-r--r--src/com/android/tv/ui/sidepanel/SwitchItem.java5
-rw-r--r--src/com/android/tv/ui/sidepanel/parentalcontrols/ParentalControlsFragment.java13
-rw-r--r--src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java42
-rw-r--r--src/com/android/tv/ui/sidepanel/parentalcontrols/SubRatingsFragment.java32
-rw-r--r--src/com/android/tv/util/AsyncDbTask.java4
-rw-r--r--src/com/android/tv/util/BitmapUtils.java10
-rw-r--r--src/com/android/tv/util/Debug.java60
-rw-r--r--src/com/android/tv/util/DurationTimer.java91
-rw-r--r--src/com/android/tv/util/ImageLoader.java3
-rw-r--r--src/com/android/tv/util/LocationUtils.java25
-rw-r--r--src/com/android/tv/util/NetworkTrafficTags.java64
-rw-r--r--src/com/android/tv/util/OnboardingUtils.java41
-rw-r--r--src/com/android/tv/util/Partner.java181
-rw-r--r--src/com/android/tv/util/PermissionUtils.java5
-rw-r--r--src/com/android/tv/util/PipInputManager.java432
-rw-r--r--src/com/android/tv/util/RecurringRunner.java9
-rw-r--r--src/com/android/tv/util/SearchManagerHelper.java61
-rw-r--r--src/com/android/tv/util/SetupUtils.java25
-rw-r--r--src/com/android/tv/util/StringUtils.java38
-rw-r--r--src/com/android/tv/util/TimeShiftUtils.java4
-rw-r--r--src/com/android/tv/util/TvInputManagerHelper.java358
-rw-r--r--src/com/android/tv/util/TvProviderUriMatcher.java72
-rw-r--r--src/com/android/tv/util/TvSettings.java160
-rw-r--r--src/com/android/tv/util/TvTrackInfoUtils.java37
-rw-r--r--src/com/android/tv/util/TvUriMatcher.java80
-rw-r--r--src/com/android/tv/util/Utils.java100
-rw-r--r--src/com/android/tv/util/ViewCache.java100
-rw-r--r--tests/OWNERS2
-rw-r--r--tests/common/Android.mk2
-rw-r--r--tests/common/OWNERS2
-rw-r--r--tests/common/res/drawable-xhdpi/ch_1000_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_1000_logo.png)bin1041 -> 1041 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_100_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_100_logo.png)bin1128 -> 1128 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_101_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_101_logo.png)bin921 -> 921 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_102_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_102_logo.png)bin1224 -> 1224 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_103_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_103_logo.png)bin971 -> 971 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_104_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_104_logo.png)bin952 -> 952 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_105_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_105_logo.png)bin977 -> 977 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_106_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_106_logo.png)bin884 -> 884 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_107_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_107_logo.png)bin910 -> 910 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_108_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_108_logo.png)bin848 -> 848 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_109_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_109_logo.png)bin842 -> 842 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_10_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_10_logo.png)bin936 -> 936 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_110_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_110_logo.png)bin1155 -> 1155 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_111_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_111_logo.png)bin915 -> 915 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_112_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_112_logo.png)bin843 -> 843 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_113_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_113_logo.png)bin1064 -> 1064 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_114_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_114_logo.png)bin861 -> 861 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_115_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_115_logo.png)bin995 -> 995 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_116_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_116_logo.png)bin1086 -> 1086 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_117_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_117_logo.png)bin917 -> 917 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_118_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_118_logo.png)bin1131 -> 1131 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_119_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_119_logo.png)bin875 -> 875 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_11_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_11_logo.png)bin932 -> 932 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_120_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_120_logo.png)bin1113 -> 1113 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_121_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_121_logo.png)bin663 -> 663 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_122_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_122_logo.png)bin845 -> 845 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_123_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_123_logo.png)bin1090 -> 1090 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_124_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_124_logo.png)bin1033 -> 1033 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_125_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_125_logo.png)bin880 -> 880 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_126_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_126_logo.png)bin1051 -> 1051 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_127_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_127_logo.png)bin1044 -> 1044 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_128_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_128_logo.png)bin1051 -> 1051 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_129_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_129_logo.png)bin983 -> 983 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_12_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_12_logo.png)bin1014 -> 1014 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_130_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_130_logo.png)bin891 -> 891 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_131_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_131_logo.png)bin975 -> 975 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_132_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_132_logo.png)bin1076 -> 1076 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_133_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_133_logo.png)bin971 -> 971 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_134_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_134_logo.png)bin1191 -> 1191 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_135_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_135_logo.png)bin1143 -> 1143 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_136_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_136_logo.png)bin1057 -> 1057 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_137_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_137_logo.png)bin1007 -> 1007 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_138_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_138_logo.png)bin995 -> 995 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_139_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_139_logo.png)bin1137 -> 1137 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_13_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_13_logo.png)bin896 -> 896 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_140_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_140_logo.png)bin1010 -> 1010 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_141_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_141_logo.png)bin970 -> 970 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_142_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_142_logo.png)bin1103 -> 1103 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_143_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_143_logo.png)bin1206 -> 1206 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_144_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_144_logo.png)bin1023 -> 1023 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_145_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_145_logo.png)bin1037 -> 1037 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_146_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_146_logo.png)bin994 -> 994 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_147_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_147_logo.png)bin828 -> 828 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_148_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_148_logo.png)bin1009 -> 1009 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_149_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_149_logo.png)bin882 -> 882 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_14_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_14_logo.png)bin1193 -> 1193 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_150_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_150_logo.png)bin1314 -> 1314 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_151_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_151_logo.png)bin931 -> 931 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_152_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_152_logo.png)bin1030 -> 1030 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_153_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_153_logo.png)bin1245 -> 1245 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_154_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_154_logo.png)bin1017 -> 1017 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_155_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_155_logo.png)bin1317 -> 1317 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_156_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_156_logo.png)bin1080 -> 1080 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_157_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_157_logo.png)bin1126 -> 1126 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_158_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_158_logo.png)bin1223 -> 1223 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_159_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_159_logo.png)bin1362 -> 1362 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_15_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_15_logo.png)bin1123 -> 1123 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_160_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_160_logo.png)bin1059 -> 1059 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_161_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_161_logo.png)bin1074 -> 1074 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_162_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_162_logo.png)bin1015 -> 1015 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_163_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_163_logo.png)bin1093 -> 1093 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_164_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_164_logo.png)bin1073 -> 1073 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_165_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_165_logo.png)bin1001 -> 1001 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_166_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_166_logo.png)bin1276 -> 1276 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_167_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_167_logo.png)bin1184 -> 1184 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_168_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_168_logo.png)bin963 -> 963 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_169_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_169_logo.png)bin1121 -> 1121 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_16_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_16_logo.png)bin877 -> 877 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_170_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_170_logo.png)bin957 -> 957 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_171_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_171_logo.png)bin978 -> 978 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_172_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_172_logo.png)bin939 -> 939 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_173_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_173_logo.png)bin906 -> 906 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_174_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_174_logo.png)bin875 -> 875 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_175_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_175_logo.png)bin974 -> 974 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_176_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_176_logo.png)bin1146 -> 1146 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_177_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_177_logo.png)bin951 -> 951 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_178_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_178_logo.png)bin1224 -> 1224 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_179_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_179_logo.png)bin948 -> 948 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_17_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_17_logo.png)bin956 -> 956 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_180_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_180_logo.png)bin980 -> 980 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_181_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_181_logo.png)bin903 -> 903 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_182_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_182_logo.png)bin854 -> 854 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_183_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_183_logo.png)bin908 -> 908 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_184_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_184_logo.png)bin804 -> 804 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_185_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_185_logo.png)bin840 -> 840 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_186_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_186_logo.png)bin1238 -> 1238 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_187_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_187_logo.png)bin1137 -> 1137 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_188_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_188_logo.png)bin883 -> 883 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_189_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_189_logo.png)bin1127 -> 1127 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_18_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_18_logo.png)bin903 -> 903 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_190_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_190_logo.png)bin977 -> 977 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_191_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_191_logo.png)bin984 -> 984 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_192_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_192_logo.png)bin1131 -> 1131 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_193_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_193_logo.png)bin1050 -> 1050 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_194_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_194_logo.png)bin1164 -> 1164 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_195_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_195_logo.png)bin918 -> 918 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_196_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_196_logo.png)bin1124 -> 1124 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_197_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_197_logo.png)bin723 -> 723 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_198_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_198_logo.png)bin929 -> 929 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_199_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_199_logo.png)bin1072 -> 1072 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_19_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_19_logo.png)bin1011 -> 1011 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_1_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_1_logo.png)bin1009 -> 1009 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_200_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_200_logo.png)bin1019 -> 1019 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_201_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_201_logo.png)bin923 -> 923 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_202_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_202_logo.png)bin1029 -> 1029 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_203_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_203_logo.png)bin1107 -> 1107 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_204_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_204_logo.png)bin1148 -> 1148 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_205_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_205_logo.png)bin954 -> 954 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_206_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_206_logo.png)bin940 -> 940 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_207_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_207_logo.png)bin1062 -> 1062 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_208_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_208_logo.png)bin1108 -> 1108 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_209_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_209_logo.png)bin1062 -> 1062 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_20_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_20_logo.png)bin973 -> 973 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_210_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_210_logo.png)bin1230 -> 1230 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_211_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_211_logo.png)bin1048 -> 1048 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_212_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_212_logo.png)bin962 -> 962 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_213_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_213_logo.png)bin1026 -> 1026 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_214_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_214_logo.png)bin888 -> 888 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_215_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_215_logo.png)bin1121 -> 1121 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_216_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_216_logo.png)bin1038 -> 1038 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_217_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_217_logo.png)bin1058 -> 1058 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_218_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_218_logo.png)bin1124 -> 1124 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_219_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_219_logo.png)bin1277 -> 1277 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_21_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_21_logo.png)bin833 -> 833 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_220_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_220_logo.png)bin1100 -> 1100 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_221_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_221_logo.png)bin972 -> 972 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_222_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_222_logo.png)bin943 -> 943 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_223_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_223_logo.png)bin850 -> 850 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_224_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_224_logo.png)bin967 -> 967 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_225_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_225_logo.png)bin898 -> 898 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_226_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_226_logo.png)bin1287 -> 1287 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_227_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_227_logo.png)bin1013 -> 1013 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_228_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_228_logo.png)bin999 -> 999 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_229_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_229_logo.png)bin1209 -> 1209 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_22_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_22_logo.png)bin814 -> 814 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_230_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_230_logo.png)bin1073 -> 1073 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_231_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_231_logo.png)bin1371 -> 1371 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_232_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_232_logo.png)bin1038 -> 1038 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_233_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_233_logo.png)bin1234 -> 1234 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_234_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_234_logo.png)bin1122 -> 1122 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_235_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_235_logo.png)bin1351 -> 1351 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_236_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_236_logo.png)bin1089 -> 1089 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_237_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_237_logo.png)bin1143 -> 1143 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_238_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_238_logo.png)bin1028 -> 1028 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_239_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_239_logo.png)bin1116 -> 1116 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_23_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_23_logo.png)bin905 -> 905 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_240_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_240_logo.png)bin1101 -> 1101 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_241_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_241_logo.png)bin959 -> 959 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_242_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_242_logo.png)bin1238 -> 1238 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_243_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_243_logo.png)bin1137 -> 1137 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_244_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_244_logo.png)bin849 -> 849 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_245_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_245_logo.png)bin1058 -> 1058 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_246_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_246_logo.png)bin991 -> 991 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_247_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_247_logo.png)bin991 -> 991 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_248_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_248_logo.png)bin1034 -> 1034 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_249_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_249_logo.png)bin942 -> 942 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_24_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_24_logo.png)bin1073 -> 1073 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_250_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_250_logo.png)bin955 -> 955 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_251_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_251_logo.png)bin966 -> 966 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_252_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_252_logo.png)bin1048 -> 1048 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_253_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_253_logo.png)bin1084 -> 1084 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_254_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_254_logo.png)bin1231 -> 1231 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_255_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_255_logo.png)bin917 -> 917 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_256_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_256_logo.png)bin999 -> 999 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_257_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_257_logo.png)bin963 -> 963 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_258_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_258_logo.png)bin968 -> 968 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_259_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_259_logo.png)bin970 -> 970 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_25_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_25_logo.png)bin994 -> 994 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_260_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_260_logo.png)bin858 -> 858 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_261_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_261_logo.png)bin809 -> 809 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_262_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_262_logo.png)bin1179 -> 1179 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_263_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_263_logo.png)bin1170 -> 1170 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_264_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_264_logo.png)bin914 -> 914 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_265_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_265_logo.png)bin1154 -> 1154 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_266_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_266_logo.png)bin947 -> 947 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_267_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_267_logo.png)bin986 -> 986 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_268_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_268_logo.png)bin1103 -> 1103 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_269_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_269_logo.png)bin1075 -> 1075 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_26_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_26_logo.png)bin1193 -> 1193 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_270_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_270_logo.png)bin1143 -> 1143 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_271_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_271_logo.png)bin872 -> 872 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_272_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_272_logo.png)bin1057 -> 1057 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_273_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_273_logo.png)bin748 -> 748 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_274_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_274_logo.png)bin896 -> 896 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_275_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_275_logo.png)bin1095 -> 1095 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_276_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_276_logo.png)bin1061 -> 1061 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_277_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_277_logo.png)bin847 -> 847 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_278_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_278_logo.png)bin1079 -> 1079 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_279_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_279_logo.png)bin1008 -> 1008 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_27_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_27_logo.png)bin887 -> 887 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_280_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_280_logo.png)bin1142 -> 1142 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_281_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_281_logo.png)bin980 -> 980 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_282_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_282_logo.png)bin833 -> 833 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_283_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_283_logo.png)bin1080 -> 1080 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_284_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_284_logo.png)bin1082 -> 1082 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_285_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_285_logo.png)bin1064 -> 1064 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_286_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_286_logo.png)bin1254 -> 1254 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_287_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_287_logo.png)bin1137 -> 1137 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_288_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_288_logo.png)bin1013 -> 1013 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_289_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_289_logo.png)bin1058 -> 1058 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_28_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_28_logo.png)bin928 -> 928 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_290_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_290_logo.png)bin1002 -> 1002 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_291_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_291_logo.png)bin1121 -> 1121 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_292_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_292_logo.png)bin946 -> 946 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_293_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_293_logo.png)bin1160 -> 1160 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_294_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_294_logo.png)bin1133 -> 1133 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_295_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_295_logo.png)bin1303 -> 1303 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_296_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_296_logo.png)bin1085 -> 1085 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_297_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_297_logo.png)bin1060 -> 1060 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_298_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_298_logo.png)bin1028 -> 1028 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_299_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_299_logo.png)bin842 -> 842 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_29_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_29_logo.png)bin886 -> 886 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_2_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_2_logo.png)bin907 -> 907 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_300_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_300_logo.png)bin934 -> 934 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_301_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_301_logo.png)bin887 -> 887 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_302_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_302_logo.png)bin1338 -> 1338 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_303_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_303_logo.png)bin1055 -> 1055 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_304_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_304_logo.png)bin1045 -> 1045 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_305_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_305_logo.png)bin1282 -> 1282 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_306_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_306_logo.png)bin1027 -> 1027 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_307_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_307_logo.png)bin1272 -> 1272 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_308_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_308_logo.png)bin1115 -> 1115 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_309_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_309_logo.png)bin1324 -> 1324 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_30_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_30_logo.png)bin894 -> 894 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_310_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_310_logo.png)bin1222 -> 1222 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_311_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_311_logo.png)bin1303 -> 1303 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_312_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_312_logo.png)bin1057 -> 1057 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_313_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_313_logo.png)bin1085 -> 1085 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_314_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_314_logo.png)bin990 -> 990 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_315_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_315_logo.png)bin1109 -> 1109 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_316_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_316_logo.png)bin1109 -> 1109 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_317_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_317_logo.png)bin968 -> 968 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_318_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_318_logo.png)bin1206 -> 1206 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_319_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_319_logo.png)bin1113 -> 1113 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_31_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_31_logo.png)bin858 -> 858 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_320_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_320_logo.png)bin979 -> 979 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_321_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_321_logo.png)bin1092 -> 1092 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_322_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_322_logo.png)bin939 -> 939 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_323_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_323_logo.png)bin1017 -> 1017 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_324_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_324_logo.png)bin1008 -> 1008 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_325_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_325_logo.png)bin953 -> 953 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_326_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_326_logo.png)bin966 -> 966 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_327_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_327_logo.png)bin1000 -> 1000 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_328_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_328_logo.png)bin1205 -> 1205 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_329_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_329_logo.png)bin1073 -> 1073 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_32_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_32_logo.png)bin781 -> 781 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_330_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_330_logo.png)bin1201 -> 1201 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_331_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_331_logo.png)bin899 -> 899 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_332_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_332_logo.png)bin946 -> 946 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_333_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_333_logo.png)bin863 -> 863 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_334_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_334_logo.png)bin857 -> 857 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_335_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_335_logo.png)bin913 -> 913 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_336_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_336_logo.png)bin805 -> 805 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_337_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_337_logo.png)bin773 -> 773 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_338_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_338_logo.png)bin1167 -> 1167 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_339_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_339_logo.png)bin1110 -> 1110 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_33_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_33_logo.png)bin708 -> 708 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_340_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_340_logo.png)bin937 -> 937 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_341_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_341_logo.png)bin1070 -> 1070 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_342_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_342_logo.png)bin984 -> 984 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_343_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_343_logo.png)bin1010 -> 1010 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_344_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_344_logo.png)bin1091 -> 1091 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_345_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_345_logo.png)bin996 -> 996 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_346_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_346_logo.png)bin1243 -> 1243 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_347_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_347_logo.png)bin920 -> 920 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_348_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_348_logo.png)bin1103 -> 1103 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_349_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_349_logo.png)bin770 -> 770 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_34_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_34_logo.png)bin1137 -> 1137 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_350_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_350_logo.png)bin961 -> 961 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_351_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_351_logo.png)bin1147 -> 1147 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_352_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_352_logo.png)bin1036 -> 1036 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_353_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_353_logo.png)bin920 -> 920 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_354_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_354_logo.png)bin1075 -> 1075 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_355_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_355_logo.png)bin1010 -> 1010 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_356_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_356_logo.png)bin1176 -> 1176 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_357_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_357_logo.png)bin997 -> 997 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_358_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_358_logo.png)bin910 -> 910 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_359_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_359_logo.png)bin1102 -> 1102 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_35_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_35_logo.png)bin1038 -> 1038 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_360_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_360_logo.png)bin1119 -> 1119 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_361_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_361_logo.png)bin1025 -> 1025 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_362_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_362_logo.png)bin1264 -> 1264 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_363_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_363_logo.png)bin1099 -> 1099 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_364_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_364_logo.png)bin1032 -> 1032 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_365_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_365_logo.png)bin1014 -> 1014 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_366_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_366_logo.png)bin967 -> 967 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_367_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_367_logo.png)bin1061 -> 1061 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_368_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_368_logo.png)bin1023 -> 1023 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_369_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_369_logo.png)bin1178 -> 1178 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_36_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_36_logo.png)bin847 -> 847 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_370_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_370_logo.png)bin1148 -> 1148 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_371_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_371_logo.png)bin1249 -> 1249 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_372_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_372_logo.png)bin1137 -> 1137 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_373_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_373_logo.png)bin999 -> 999 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_374_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_374_logo.png)bin989 -> 989 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_375_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_375_logo.png)bin900 -> 900 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_376_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_376_logo.png)bin1031 -> 1031 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_377_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_377_logo.png)bin886 -> 886 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_378_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_378_logo.png)bin1334 -> 1334 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_379_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_379_logo.png)bin1099 -> 1099 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_37_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_37_logo.png)bin1060 -> 1060 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_380_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_380_logo.png)bin1009 -> 1009 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_381_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_381_logo.png)bin1223 -> 1223 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_382_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_382_logo.png)bin1072 -> 1072 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_383_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_383_logo.png)bin1249 -> 1249 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_384_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_384_logo.png)bin1083 -> 1083 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_385_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_385_logo.png)bin1344 -> 1344 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_386_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_386_logo.png)bin1244 -> 1244 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_387_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_387_logo.png)bin1380 -> 1380 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_388_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_388_logo.png)bin981 -> 981 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_389_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_389_logo.png)bin1197 -> 1197 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_38_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_38_logo.png)bin938 -> 938 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_390_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_390_logo.png)bin986 -> 986 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_391_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_391_logo.png)bin1084 -> 1084 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_392_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_392_logo.png)bin1118 -> 1118 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_393_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_393_logo.png)bin981 -> 981 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_394_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_394_logo.png)bin1231 -> 1231 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_395_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_395_logo.png)bin1243 -> 1243 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_396_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_396_logo.png)bin995 -> 995 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_397_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_397_logo.png)bin1118 -> 1118 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_398_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_398_logo.png)bin1014 -> 1014 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_399_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_399_logo.png)bin1049 -> 1049 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_39_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_39_logo.png)bin1014 -> 1014 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_3_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_3_logo.png)bin1160 -> 1160 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_400_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_400_logo.png)bin974 -> 974 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_401_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_401_logo.png)bin862 -> 862 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_402_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_402_logo.png)bin945 -> 945 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_403_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_403_logo.png)bin1004 -> 1004 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_404_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_404_logo.png)bin1106 -> 1106 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_405_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_405_logo.png)bin1051 -> 1051 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_406_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_406_logo.png)bin1184 -> 1184 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_407_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_407_logo.png)bin910 -> 910 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_408_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_408_logo.png)bin992 -> 992 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_409_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_409_logo.png)bin988 -> 988 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_40_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_40_logo.png)bin1078 -> 1078 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_410_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_410_logo.png)bin915 -> 915 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_411_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_411_logo.png)bin842 -> 842 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_412_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_412_logo.png)bin814 -> 814 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_413_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_413_logo.png)bin817 -> 817 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_414_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_414_logo.png)bin1120 -> 1120 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_415_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_415_logo.png)bin1116 -> 1116 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_416_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_416_logo.png)bin923 -> 923 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_417_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_417_logo.png)bin1044 -> 1044 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_418_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_418_logo.png)bin946 -> 946 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_419_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_419_logo.png)bin1045 -> 1045 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_41_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_41_logo.png)bin857 -> 857 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_420_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_420_logo.png)bin1056 -> 1056 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_421_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_421_logo.png)bin1003 -> 1003 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_422_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_422_logo.png)bin1154 -> 1154 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_423_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_423_logo.png)bin921 -> 921 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_424_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_424_logo.png)bin1069 -> 1069 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_425_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_425_logo.png)bin744 -> 744 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_426_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_426_logo.png)bin923 -> 923 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_427_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_427_logo.png)bin1113 -> 1113 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_428_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_428_logo.png)bin1073 -> 1073 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_429_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_429_logo.png)bin940 -> 940 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_42_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_42_logo.png)bin1135 -> 1135 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_430_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_430_logo.png)bin1072 -> 1072 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_431_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_431_logo.png)bin1059 -> 1059 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_432_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_432_logo.png)bin1149 -> 1149 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_433_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_433_logo.png)bin933 -> 933 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_434_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_434_logo.png)bin867 -> 867 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_435_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_435_logo.png)bin1055 -> 1055 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_436_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_436_logo.png)bin1039 -> 1039 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_437_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_437_logo.png)bin1012 -> 1012 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_438_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_438_logo.png)bin1241 -> 1241 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_439_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_439_logo.png)bin1134 -> 1134 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_43_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_43_logo.png)bin810 -> 810 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_440_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_440_logo.png)bin987 -> 987 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_441_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_441_logo.png)bin905 -> 905 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_442_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_442_logo.png)bin906 -> 906 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_443_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_443_logo.png)bin1071 -> 1071 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_444_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_444_logo.png)bin871 -> 871 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_445_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_445_logo.png)bin1073 -> 1073 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_446_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_446_logo.png)bin1083 -> 1083 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_447_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_447_logo.png)bin1196 -> 1196 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_448_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_448_logo.png)bin1077 -> 1077 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_449_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_449_logo.png)bin1012 -> 1012 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_44_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_44_logo.png)bin966 -> 966 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_450_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_450_logo.png)bin1066 -> 1066 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_451_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_451_logo.png)bin845 -> 845 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_452_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_452_logo.png)bin1028 -> 1028 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_453_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_453_logo.png)bin946 -> 946 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_454_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_454_logo.png)bin1228 -> 1228 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_455_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_455_logo.png)bin1035 -> 1035 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_456_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_456_logo.png)bin1061 -> 1061 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_457_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_457_logo.png)bin1162 -> 1162 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_458_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_458_logo.png)bin1067 -> 1067 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_459_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_459_logo.png)bin1384 -> 1384 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_45_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_45_logo.png)bin674 -> 674 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_460_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_460_logo.png)bin1087 -> 1087 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_461_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_461_logo.png)bin1234 -> 1234 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_462_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_462_logo.png)bin1212 -> 1212 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_463_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_463_logo.png)bin1360 -> 1360 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_464_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_464_logo.png)bin1024 -> 1024 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_465_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_465_logo.png)bin1159 -> 1159 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_466_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_466_logo.png)bin973 -> 973 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_467_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_467_logo.png)bin1079 -> 1079 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_468_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_468_logo.png)bin1113 -> 1113 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_469_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_469_logo.png)bin1011 -> 1011 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_46_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_46_logo.png)bin815 -> 815 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_470_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_470_logo.png)bin1271 -> 1271 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_471_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_471_logo.png)bin1096 -> 1096 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_472_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_472_logo.png)bin925 -> 925 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_473_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_473_logo.png)bin1104 -> 1104 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_474_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_474_logo.png)bin892 -> 892 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_475_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_475_logo.png)bin1065 -> 1065 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_476_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_476_logo.png)bin1012 -> 1012 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_477_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_477_logo.png)bin833 -> 833 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_478_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_478_logo.png)bin936 -> 936 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_479_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_479_logo.png)bin991 -> 991 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_47_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_47_logo.png)bin1054 -> 1054 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_480_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_480_logo.png)bin1193 -> 1193 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_481_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_481_logo.png)bin1001 -> 1001 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_482_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_482_logo.png)bin1242 -> 1242 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_483_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_483_logo.png)bin981 -> 981 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_484_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_484_logo.png)bin870 -> 870 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_485_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_485_logo.png)bin992 -> 992 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_486_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_486_logo.png)bin899 -> 899 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_487_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_487_logo.png)bin930 -> 930 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_488_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_488_logo.png)bin790 -> 790 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_489_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_489_logo.png)bin846 -> 846 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_48_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_48_logo.png)bin1008 -> 1008 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_490_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_490_logo.png)bin1228 -> 1228 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_491_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_491_logo.png)bin1125 -> 1125 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_492_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_492_logo.png)bin940 -> 940 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_493_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_493_logo.png)bin1151 -> 1151 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_494_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_494_logo.png)bin866 -> 866 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_495_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_495_logo.png)bin1072 -> 1072 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_496_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_496_logo.png)bin1155 -> 1155 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_497_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_497_logo.png)bin945 -> 945 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_498_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_498_logo.png)bin1241 -> 1241 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_499_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_499_logo.png)bin873 -> 873 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_49_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_49_logo.png)bin872 -> 872 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_4_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_4_logo.png)bin852 -> 852 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_500_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_500_logo.png)bin1022 -> 1022 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_501_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_501_logo.png)bin745 -> 745 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_502_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_502_logo.png)bin944 -> 944 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_503_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_503_logo.png)bin1198 -> 1198 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_504_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_504_logo.png)bin1087 -> 1087 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_505_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_505_logo.png)bin928 -> 928 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_506_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_506_logo.png)bin1104 -> 1104 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_507_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_507_logo.png)bin1088 -> 1088 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_508_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_508_logo.png)bin1109 -> 1109 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_509_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_509_logo.png)bin973 -> 973 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_50_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_50_logo.png)bin992 -> 992 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_510_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_510_logo.png)bin935 -> 935 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_511_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_511_logo.png)bin981 -> 981 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_512_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_512_logo.png)bin1078 -> 1078 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_513_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_513_logo.png)bin1065 -> 1065 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_514_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_514_logo.png)bin1132 -> 1132 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_515_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_515_logo.png)bin1066 -> 1066 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_516_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_516_logo.png)bin1061 -> 1061 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_517_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_517_logo.png)bin1005 -> 1005 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_518_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_518_logo.png)bin975 -> 975 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_519_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_519_logo.png)bin1143 -> 1143 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_51_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_51_logo.png)bin1003 -> 1003 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_520_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_520_logo.png)bin1064 -> 1064 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_521_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_521_logo.png)bin1123 -> 1123 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_522_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_522_logo.png)bin1086 -> 1086 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_523_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_523_logo.png)bin1308 -> 1308 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_524_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_524_logo.png)bin1129 -> 1129 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_525_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_525_logo.png)bin1021 -> 1021 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_526_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_526_logo.png)bin1020 -> 1020 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_527_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_527_logo.png)bin879 -> 879 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_528_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_528_logo.png)bin1043 -> 1043 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_529_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_529_logo.png)bin961 -> 961 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_52_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_52_logo.png)bin1083 -> 1083 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_530_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_530_logo.png)bin1332 -> 1332 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_531_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_531_logo.png)bin1071 -> 1071 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_532_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_532_logo.png)bin1071 -> 1071 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_533_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_533_logo.png)bin1211 -> 1211 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_534_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_534_logo.png)bin1058 -> 1058 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_535_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_535_logo.png)bin1380 -> 1380 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_536_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_536_logo.png)bin1124 -> 1124 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_537_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_537_logo.png)bin1298 -> 1298 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_538_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_538_logo.png)bin1273 -> 1273 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_539_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_539_logo.png)bin1391 -> 1391 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_53_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_53_logo.png)bin938 -> 938 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_540_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_540_logo.png)bin1086 -> 1086 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_541_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_541_logo.png)bin1127 -> 1127 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_542_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_542_logo.png)bin1026 -> 1026 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_543_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_543_logo.png)bin1113 -> 1113 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_544_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_544_logo.png)bin1059 -> 1059 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_545_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_545_logo.png)bin949 -> 949 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_546_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_546_logo.png)bin1343 -> 1343 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_547_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_547_logo.png)bin1138 -> 1138 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_548_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_548_logo.png)bin975 -> 975 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_549_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_549_logo.png)bin1144 -> 1144 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_54_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_54_logo.png)bin808 -> 808 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_550_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_550_logo.png)bin923 -> 923 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_551_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_551_logo.png)bin953 -> 953 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_552_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_552_logo.png)bin1005 -> 1005 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_553_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_553_logo.png)bin918 -> 918 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_554_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_554_logo.png)bin892 -> 892 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_555_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_555_logo.png)bin903 -> 903 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_556_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_556_logo.png)bin1172 -> 1172 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_557_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_557_logo.png)bin1005 -> 1005 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_558_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_558_logo.png)bin1241 -> 1241 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_559_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_559_logo.png)bin963 -> 963 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_55_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_55_logo.png)bin951 -> 951 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_560_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_560_logo.png)bin1011 -> 1011 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_561_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_561_logo.png)bin968 -> 968 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_562_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_562_logo.png)bin962 -> 962 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_563_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_563_logo.png)bin982 -> 982 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_564_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_564_logo.png)bin854 -> 854 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_565_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_565_logo.png)bin827 -> 827 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_566_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_566_logo.png)bin1186 -> 1186 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_567_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_567_logo.png)bin1145 -> 1145 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_568_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_568_logo.png)bin984 -> 984 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_569_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_569_logo.png)bin1134 -> 1134 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_56_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_56_logo.png)bin967 -> 967 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_570_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_570_logo.png)bin992 -> 992 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_571_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_571_logo.png)bin1012 -> 1012 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_572_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_572_logo.png)bin1138 -> 1138 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_573_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_573_logo.png)bin995 -> 995 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_574_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_574_logo.png)bin1169 -> 1169 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_575_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_575_logo.png)bin853 -> 853 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_576_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_576_logo.png)bin1148 -> 1148 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_577_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_577_logo.png)bin684 -> 684 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_578_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_578_logo.png)bin932 -> 932 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_579_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_579_logo.png)bin1159 -> 1159 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_57_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_57_logo.png)bin981 -> 981 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_580_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_580_logo.png)bin1107 -> 1107 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_581_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_581_logo.png)bin939 -> 939 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_582_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_582_logo.png)bin1093 -> 1093 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_583_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_583_logo.png)bin1066 -> 1066 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_584_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_584_logo.png)bin1134 -> 1134 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_585_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_585_logo.png)bin960 -> 960 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_586_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_586_logo.png)bin925 -> 925 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_587_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_587_logo.png)bin1079 -> 1079 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_588_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_588_logo.png)bin1053 -> 1053 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_589_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_589_logo.png)bin1081 -> 1081 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_58_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_58_logo.png)bin1193 -> 1193 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_590_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_590_logo.png)bin1258 -> 1258 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_591_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_591_logo.png)bin1137 -> 1137 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_592_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_592_logo.png)bin1072 -> 1072 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_593_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_593_logo.png)bin1071 -> 1071 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_594_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_594_logo.png)bin988 -> 988 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_595_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_595_logo.png)bin1106 -> 1106 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_596_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_596_logo.png)bin1089 -> 1089 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_597_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_597_logo.png)bin1132 -> 1132 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_598_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_598_logo.png)bin1164 -> 1164 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_599_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_599_logo.png)bin1257 -> 1257 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_59_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_59_logo.png)bin1097 -> 1097 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_5_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_5_logo.png)bin1137 -> 1137 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_600_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_600_logo.png)bin1107 -> 1107 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_601_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_601_logo.png)bin1059 -> 1059 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_602_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_602_logo.png)bin1078 -> 1078 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_603_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_603_logo.png)bin925 -> 925 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_604_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_604_logo.png)bin961 -> 961 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_605_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_605_logo.png)bin977 -> 977 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_606_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_606_logo.png)bin1217 -> 1217 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_607_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_607_logo.png)bin1094 -> 1094 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_608_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_608_logo.png)bin1050 -> 1050 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_609_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_609_logo.png)bin1273 -> 1273 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_60_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_60_logo.png)bin958 -> 958 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_610_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_610_logo.png)bin1009 -> 1009 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_611_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_611_logo.png)bin1320 -> 1320 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_612_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_612_logo.png)bin1076 -> 1076 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_613_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_613_logo.png)bin1300 -> 1300 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_614_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_614_logo.png)bin1185 -> 1185 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_615_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_615_logo.png)bin1360 -> 1360 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_616_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_616_logo.png)bin985 -> 985 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_617_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_617_logo.png)bin1113 -> 1113 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_618_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_618_logo.png)bin1026 -> 1026 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_619_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_619_logo.png)bin1031 -> 1031 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_61_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_61_logo.png)bin898 -> 898 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_620_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_620_logo.png)bin1127 -> 1127 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_621_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_621_logo.png)bin975 -> 975 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_622_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_622_logo.png)bin1268 -> 1268 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_623_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_623_logo.png)bin1233 -> 1233 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_624_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_624_logo.png)bin954 -> 954 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_625_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_625_logo.png)bin1064 -> 1064 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_626_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_626_logo.png)bin931 -> 931 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_627_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_627_logo.png)bin1068 -> 1068 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_628_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_628_logo.png)bin994 -> 994 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_629_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_629_logo.png)bin911 -> 911 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_62_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_62_logo.png)bin926 -> 926 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_630_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_630_logo.png)bin974 -> 974 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_631_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_631_logo.png)bin1006 -> 1006 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_632_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_632_logo.png)bin1207 -> 1207 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_633_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_633_logo.png)bin1019 -> 1019 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_634_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_634_logo.png)bin1185 -> 1185 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_635_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_635_logo.png)bin1005 -> 1005 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_636_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_636_logo.png)bin950 -> 950 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_637_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_637_logo.png)bin942 -> 942 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_638_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_638_logo.png)bin977 -> 977 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_639_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_639_logo.png)bin982 -> 982 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_63_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_63_logo.png)bin1070 -> 1070 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_640_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_640_logo.png)bin861 -> 861 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_641_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_641_logo.png)bin811 -> 811 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_642_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_642_logo.png)bin1230 -> 1230 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_643_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_643_logo.png)bin1172 -> 1172 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_644_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_644_logo.png)bin883 -> 883 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_645_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_645_logo.png)bin1078 -> 1078 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_646_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_646_logo.png)bin878 -> 878 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_647_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_647_logo.png)bin1026 -> 1026 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_648_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_648_logo.png)bin1161 -> 1161 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_649_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_649_logo.png)bin1068 -> 1068 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_64_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_64_logo.png)bin976 -> 976 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_650_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_650_logo.png)bin1263 -> 1263 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_651_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_651_logo.png)bin910 -> 910 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_652_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_652_logo.png)bin1138 -> 1138 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_653_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_653_logo.png)bin777 -> 777 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_654_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_654_logo.png)bin894 -> 894 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_655_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_655_logo.png)bin1052 -> 1052 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_656_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_656_logo.png)bin1049 -> 1049 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_657_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_657_logo.png)bin937 -> 937 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_658_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_658_logo.png)bin1120 -> 1120 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_659_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_659_logo.png)bin1134 -> 1134 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_65_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_65_logo.png)bin1048 -> 1048 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_660_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_660_logo.png)bin1107 -> 1107 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_661_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_661_logo.png)bin929 -> 929 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_662_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_662_logo.png)bin887 -> 887 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_663_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_663_logo.png)bin1039 -> 1039 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_664_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_664_logo.png)bin1033 -> 1033 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_665_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_665_logo.png)bin1036 -> 1036 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_666_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_666_logo.png)bin1134 -> 1134 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_667_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_667_logo.png)bin1087 -> 1087 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_668_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_668_logo.png)bin1032 -> 1032 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_669_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_669_logo.png)bin1029 -> 1029 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_66_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_66_logo.png)bin1023 -> 1023 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_670_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_670_logo.png)bin974 -> 974 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_671_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_671_logo.png)bin1103 -> 1103 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_672_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_672_logo.png)bin1016 -> 1016 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_673_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_673_logo.png)bin1157 -> 1157 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_674_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_674_logo.png)bin1118 -> 1118 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_675_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_675_logo.png)bin1288 -> 1288 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_676_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_676_logo.png)bin1064 -> 1064 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_677_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_677_logo.png)bin1012 -> 1012 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_678_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_678_logo.png)bin1081 -> 1081 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_679_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_679_logo.png)bin898 -> 898 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_67_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_67_logo.png)bin1208 -> 1208 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_680_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_680_logo.png)bin1061 -> 1061 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_681_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_681_logo.png)bin901 -> 901 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_682_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_682_logo.png)bin1340 -> 1340 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_683_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_683_logo.png)bin1123 -> 1123 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_684_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_684_logo.png)bin1045 -> 1045 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_685_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_685_logo.png)bin1220 -> 1220 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_686_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_686_logo.png)bin1042 -> 1042 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_687_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_687_logo.png)bin1417 -> 1417 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_688_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_688_logo.png)bin1052 -> 1052 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_689_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_689_logo.png)bin1331 -> 1331 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_68_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_68_logo.png)bin1106 -> 1106 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_690_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_690_logo.png)bin1253 -> 1253 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_691_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_691_logo.png)bin1359 -> 1359 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_692_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_692_logo.png)bin1079 -> 1079 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_693_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_693_logo.png)bin1169 -> 1169 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_694_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_694_logo.png)bin1025 -> 1025 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_695_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_695_logo.png)bin1136 -> 1136 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_696_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_696_logo.png)bin1078 -> 1078 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_697_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_697_logo.png)bin1014 -> 1014 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_698_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_698_logo.png)bin1366 -> 1366 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_699_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_699_logo.png)bin1191 -> 1191 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_69_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_69_logo.png)bin1035 -> 1035 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_6_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_6_logo.png)bin1002 -> 1002 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_700_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_700_logo.png)bin910 -> 910 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_701_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_701_logo.png)bin1088 -> 1088 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_702_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_702_logo.png)bin967 -> 967 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_703_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_703_logo.png)bin1079 -> 1079 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_704_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_704_logo.png)bin986 -> 986 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_705_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_705_logo.png)bin926 -> 926 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_706_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_706_logo.png)bin952 -> 952 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_707_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_707_logo.png)bin928 -> 928 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_708_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_708_logo.png)bin1089 -> 1089 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_709_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_709_logo.png)bin1062 -> 1062 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_70_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_70_logo.png)bin996 -> 996 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_710_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_710_logo.png)bin1152 -> 1152 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_711_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_711_logo.png)bin855 -> 855 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_712_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_712_logo.png)bin944 -> 944 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_713_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_713_logo.png)bin952 -> 952 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_714_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_714_logo.png)bin861 -> 861 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_715_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_715_logo.png)bin918 -> 918 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_716_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_716_logo.png)bin827 -> 827 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_717_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_717_logo.png)bin736 -> 736 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_718_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_718_logo.png)bin1183 -> 1183 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_719_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_719_logo.png)bin1115 -> 1115 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_71_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_71_logo.png)bin770 -> 770 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_720_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_720_logo.png)bin927 -> 927 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_721_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_721_logo.png)bin1080 -> 1080 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_722_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_722_logo.png)bin909 -> 909 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_723_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_723_logo.png)bin1002 -> 1002 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_724_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_724_logo.png)bin1110 -> 1110 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_725_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_725_logo.png)bin1037 -> 1037 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_726_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_726_logo.png)bin1195 -> 1195 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_727_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_727_logo.png)bin814 -> 814 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_728_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_728_logo.png)bin1129 -> 1129 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_729_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_729_logo.png)bin743 -> 743 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_72_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_72_logo.png)bin919 -> 919 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_730_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_730_logo.png)bin921 -> 921 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_731_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_731_logo.png)bin1122 -> 1122 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_732_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_732_logo.png)bin1054 -> 1054 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_733_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_733_logo.png)bin865 -> 865 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_734_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_734_logo.png)bin1052 -> 1052 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_735_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_735_logo.png)bin1086 -> 1086 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_736_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_736_logo.png)bin1135 -> 1135 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_737_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_737_logo.png)bin911 -> 911 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_738_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_738_logo.png)bin936 -> 936 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_739_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_739_logo.png)bin1081 -> 1081 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_73_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_73_logo.png)bin861 -> 861 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_740_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_740_logo.png)bin1011 -> 1011 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_741_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_741_logo.png)bin982 -> 982 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_742_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_742_logo.png)bin1149 -> 1149 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_743_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_743_logo.png)bin1119 -> 1119 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_744_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_744_logo.png)bin944 -> 944 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_745_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_745_logo.png)bin967 -> 967 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_746_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_746_logo.png)bin958 -> 958 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_747_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_747_logo.png)bin1035 -> 1035 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_748_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_748_logo.png)bin1023 -> 1023 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_749_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_749_logo.png)bin1105 -> 1105 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_74_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_74_logo.png)bin1126 -> 1126 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_750_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_750_logo.png)bin1147 -> 1147 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_751_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_751_logo.png)bin1249 -> 1249 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_752_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_752_logo.png)bin1117 -> 1117 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_753_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_753_logo.png)bin1070 -> 1070 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_754_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_754_logo.png)bin1040 -> 1040 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_755_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_755_logo.png)bin837 -> 837 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_756_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_756_logo.png)bin1032 -> 1032 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_757_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_757_logo.png)bin879 -> 879 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_758_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_758_logo.png)bin1220 -> 1220 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_759_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_759_logo.png)bin1088 -> 1088 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_75_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_75_logo.png)bin993 -> 993 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_760_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_760_logo.png)bin1047 -> 1047 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_761_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_761_logo.png)bin1201 -> 1201 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_762_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_762_logo.png)bin1033 -> 1033 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_763_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_763_logo.png)bin1294 -> 1294 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_764_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_764_logo.png)bin1059 -> 1059 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_765_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_765_logo.png)bin1271 -> 1271 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_766_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_766_logo.png)bin1153 -> 1153 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_767_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_767_logo.png)bin1309 -> 1309 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_768_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_768_logo.png)bin1081 -> 1081 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_769_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_769_logo.png)bin1162 -> 1162 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_76_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_76_logo.png)bin977 -> 977 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_770_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_770_logo.png)bin897 -> 897 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_771_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_771_logo.png)bin990 -> 990 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_772_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_772_logo.png)bin1034 -> 1034 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_773_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_773_logo.png)bin933 -> 933 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_774_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_774_logo.png)bin1208 -> 1208 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_775_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_775_logo.png)bin1064 -> 1064 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_776_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_776_logo.png)bin912 -> 912 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_777_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_777_logo.png)bin943 -> 943 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_778_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_778_logo.png)bin924 -> 924 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_779_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_779_logo.png)bin1025 -> 1025 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_77_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_77_logo.png)bin1091 -> 1091 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_780_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_780_logo.png)bin1033 -> 1033 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_781_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_781_logo.png)bin904 -> 904 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_782_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_782_logo.png)bin899 -> 899 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_783_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_783_logo.png)bin1013 -> 1013 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_784_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_784_logo.png)bin1153 -> 1153 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_785_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_785_logo.png)bin1052 -> 1052 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_786_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_786_logo.png)bin1264 -> 1264 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_787_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_787_logo.png)bin910 -> 910 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_788_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_788_logo.png)bin931 -> 931 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_789_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_789_logo.png)bin983 -> 983 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_78_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_78_logo.png)bin969 -> 969 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_790_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_790_logo.png)bin943 -> 943 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_791_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_791_logo.png)bin864 -> 864 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_792_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_792_logo.png)bin838 -> 838 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_793_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_793_logo.png)bin843 -> 843 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_794_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_794_logo.png)bin1175 -> 1175 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_795_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_795_logo.png)bin1087 -> 1087 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_796_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_796_logo.png)bin934 -> 934 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_797_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_797_logo.png)bin1075 -> 1075 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_798_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_798_logo.png)bin986 -> 986 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_799_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_799_logo.png)bin1010 -> 1010 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_79_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_79_logo.png)bin1300 -> 1300 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_7_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_7_logo.png)bin1196 -> 1196 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_800_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_800_logo.png)bin1135 -> 1135 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_801_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_801_logo.png)bin1043 -> 1043 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_802_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_802_logo.png)bin1254 -> 1254 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_803_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_803_logo.png)bin931 -> 931 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_804_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_804_logo.png)bin1145 -> 1145 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_805_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_805_logo.png)bin778 -> 778 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_806_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_806_logo.png)bin964 -> 964 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_807_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_807_logo.png)bin1157 -> 1157 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_808_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_808_logo.png)bin1047 -> 1047 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_809_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_809_logo.png)bin982 -> 982 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_80_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_80_logo.png)bin1035 -> 1035 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_810_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_810_logo.png)bin1079 -> 1079 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_811_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_811_logo.png)bin960 -> 960 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_812_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_812_logo.png)bin1154 -> 1154 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_813_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_813_logo.png)bin1006 -> 1006 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_814_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_814_logo.png)bin849 -> 849 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_815_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_815_logo.png)bin1054 -> 1054 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_816_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_816_logo.png)bin1093 -> 1093 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_817_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_817_logo.png)bin1031 -> 1031 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_818_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_818_logo.png)bin1164 -> 1164 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_819_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_819_logo.png)bin1132 -> 1132 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_81_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_81_logo.png)bin1191 -> 1191 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_820_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_820_logo.png)bin1066 -> 1066 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_821_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_821_logo.png)bin1012 -> 1012 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_822_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_822_logo.png)bin947 -> 947 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_823_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_823_logo.png)bin1151 -> 1151 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_824_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_824_logo.png)bin984 -> 984 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_825_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_825_logo.png)bin1086 -> 1086 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_826_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_826_logo.png)bin1161 -> 1161 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_827_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_827_logo.png)bin1283 -> 1283 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_828_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_828_logo.png)bin1100 -> 1100 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_829_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_829_logo.png)bin1100 -> 1100 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_82_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_82_logo.png)bin1151 -> 1151 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_830_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_830_logo.png)bin1034 -> 1034 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_831_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_831_logo.png)bin885 -> 885 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_832_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_832_logo.png)bin1056 -> 1056 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_833_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_833_logo.png)bin924 -> 924 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_834_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_834_logo.png)bin1339 -> 1339 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_835_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_835_logo.png)bin1111 -> 1111 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_836_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_836_logo.png)bin1075 -> 1075 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_837_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_837_logo.png)bin1251 -> 1251 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_838_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_838_logo.png)bin1026 -> 1026 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_839_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_839_logo.png)bin1448 -> 1448 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_83_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_83_logo.png)bin1315 -> 1315 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_840_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_840_logo.png)bin1102 -> 1102 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_841_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_841_logo.png)bin1254 -> 1254 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_842_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_842_logo.png)bin1209 -> 1209 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_843_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_843_logo.png)bin1346 -> 1346 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_844_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_844_logo.png)bin985 -> 985 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_845_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_845_logo.png)bin1095 -> 1095 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_846_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_846_logo.png)bin1056 -> 1056 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_847_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_847_logo.png)bin1008 -> 1008 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_848_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_848_logo.png)bin1057 -> 1057 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_849_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_849_logo.png)bin1018 -> 1018 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_84_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_84_logo.png)bin991 -> 991 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_850_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_850_logo.png)bin1347 -> 1347 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_851_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_851_logo.png)bin1196 -> 1196 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_852_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_852_logo.png)bin941 -> 941 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_853_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_853_logo.png)bin1156 -> 1156 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_854_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_854_logo.png)bin986 -> 986 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_855_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_855_logo.png)bin1071 -> 1071 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_856_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_856_logo.png)bin1074 -> 1074 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_857_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_857_logo.png)bin942 -> 942 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_858_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_858_logo.png)bin920 -> 920 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_859_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_859_logo.png)bin1046 -> 1046 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_85_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_85_logo.png)bin1104 -> 1104 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_860_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_860_logo.png)bin1210 -> 1210 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_861_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_861_logo.png)bin1032 -> 1032 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_862_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_862_logo.png)bin1263 -> 1263 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_863_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_863_logo.png)bin1015 -> 1015 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_864_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_864_logo.png)bin989 -> 989 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_865_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_865_logo.png)bin1014 -> 1014 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_866_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_866_logo.png)bin923 -> 923 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_867_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_867_logo.png)bin961 -> 961 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_868_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_868_logo.png)bin824 -> 824 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_869_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_869_logo.png)bin875 -> 875 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_86_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_86_logo.png)bin975 -> 975 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_870_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_870_logo.png)bin1125 -> 1125 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_871_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_871_logo.png)bin1121 -> 1121 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_872_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_872_logo.png)bin937 -> 937 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_873_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_873_logo.png)bin1131 -> 1131 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_874_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_874_logo.png)bin944 -> 944 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_875_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_875_logo.png)bin1026 -> 1026 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_876_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_876_logo.png)bin1149 -> 1149 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_877_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_877_logo.png)bin977 -> 977 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_878_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_878_logo.png)bin1075 -> 1075 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_879_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_879_logo.png)bin941 -> 941 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_87_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_87_logo.png)bin959 -> 959 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_880_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_880_logo.png)bin1081 -> 1081 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_881_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_881_logo.png)bin679 -> 679 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_882_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_882_logo.png)bin883 -> 883 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_883_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_883_logo.png)bin1127 -> 1127 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_884_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_884_logo.png)bin1028 -> 1028 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_885_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_885_logo.png)bin904 -> 904 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_886_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_886_logo.png)bin1046 -> 1046 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_887_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_887_logo.png)bin1040 -> 1040 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_888_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_888_logo.png)bin1030 -> 1030 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_889_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_889_logo.png)bin961 -> 961 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_88_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_88_logo.png)bin982 -> 982 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_890_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_890_logo.png)bin954 -> 954 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_891_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_891_logo.png)bin1070 -> 1070 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_892_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_892_logo.png)bin1055 -> 1055 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_893_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_893_logo.png)bin1092 -> 1092 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_894_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_894_logo.png)bin1237 -> 1237 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_895_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_895_logo.png)bin1100 -> 1100 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_896_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_896_logo.png)bin1095 -> 1095 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_897_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_897_logo.png)bin1040 -> 1040 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_898_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_898_logo.png)bin959 -> 959 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_899_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_899_logo.png)bin1099 -> 1099 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_89_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_89_logo.png)bin939 -> 939 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_8_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_8_logo.png)bin914 -> 914 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_900_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_900_logo.png)bin1021 -> 1021 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_901_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_901_logo.png)bin1121 -> 1121 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_902_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_902_logo.png)bin1157 -> 1157 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_903_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_903_logo.png)bin1307 -> 1307 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_904_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_904_logo.png)bin1151 -> 1151 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_905_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_905_logo.png)bin1106 -> 1106 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_906_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_906_logo.png)bin1102 -> 1102 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_907_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_907_logo.png)bin900 -> 900 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_908_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_908_logo.png)bin1054 -> 1054 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_909_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_909_logo.png)bin928 -> 928 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_90_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_90_logo.png)bin1252 -> 1252 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_910_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_910_logo.png)bin1225 -> 1225 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_911_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_911_logo.png)bin1016 -> 1016 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_912_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_912_logo.png)bin1002 -> 1002 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_913_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_913_logo.png)bin1245 -> 1245 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_914_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_914_logo.png)bin1030 -> 1030 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_915_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_915_logo.png)bin1384 -> 1384 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_916_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_916_logo.png)bin1095 -> 1095 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_917_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_917_logo.png)bin1259 -> 1259 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_918_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_918_logo.png)bin1229 -> 1229 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_919_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_919_logo.png)bin1311 -> 1311 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_91_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_91_logo.png)bin1121 -> 1121 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_920_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_920_logo.png)bin1011 -> 1011 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_921_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_921_logo.png)bin1133 -> 1133 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_922_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_922_logo.png)bin913 -> 913 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_923_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_923_logo.png)bin1119 -> 1119 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_924_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_924_logo.png)bin1104 -> 1104 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_925_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_925_logo.png)bin1027 -> 1027 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_926_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_926_logo.png)bin1346 -> 1346 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_927_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_927_logo.png)bin1126 -> 1126 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_928_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_928_logo.png)bin989 -> 989 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_929_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_929_logo.png)bin1088 -> 1088 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_92_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_92_logo.png)bin907 -> 907 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_930_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_930_logo.png)bin1017 -> 1017 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_931_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_931_logo.png)bin1008 -> 1008 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_932_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_932_logo.png)bin1047 -> 1047 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_933_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_933_logo.png)bin908 -> 908 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_934_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_934_logo.png)bin912 -> 912 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_935_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_935_logo.png)bin1041 -> 1041 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_936_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_936_logo.png)bin1219 -> 1219 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_937_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_937_logo.png)bin1065 -> 1065 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_938_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_938_logo.png)bin1194 -> 1194 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_939_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_939_logo.png)bin908 -> 908 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_93_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_93_logo.png)bin1077 -> 1077 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_940_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_940_logo.png)bin1009 -> 1009 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_941_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_941_logo.png)bin913 -> 913 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_942_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_942_logo.png)bin947 -> 947 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_943_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_943_logo.png)bin971 -> 971 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_944_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_944_logo.png)bin795 -> 795 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_945_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_945_logo.png)bin850 -> 850 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_946_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_946_logo.png)bin1255 -> 1255 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_947_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_947_logo.png)bin1135 -> 1135 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_948_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_948_logo.png)bin942 -> 942 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_949_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_949_logo.png)bin1091 -> 1091 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_94_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_94_logo.png)bin913 -> 913 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_950_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_950_logo.png)bin997 -> 997 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_951_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_951_logo.png)bin1060 -> 1060 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_952_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_952_logo.png)bin1153 -> 1153 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_953_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_953_logo.png)bin1057 -> 1057 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_954_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_954_logo.png)bin1233 -> 1233 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_955_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_955_logo.png)bin901 -> 901 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_956_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_956_logo.png)bin1177 -> 1177 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_957_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_957_logo.png)bin751 -> 751 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_958_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_958_logo.png)bin965 -> 965 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_959_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_959_logo.png)bin1125 -> 1125 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_95_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_95_logo.png)bin1048 -> 1048 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_960_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_960_logo.png)bin1102 -> 1102 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_961_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_961_logo.png)bin943 -> 943 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_962_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_962_logo.png)bin1107 -> 1107 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_963_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_963_logo.png)bin1138 -> 1138 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_964_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_964_logo.png)bin1173 -> 1173 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_965_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_965_logo.png)bin1024 -> 1024 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_966_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_966_logo.png)bin904 -> 904 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_967_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_967_logo.png)bin1020 -> 1020 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_968_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_968_logo.png)bin1074 -> 1074 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_969_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_969_logo.png)bin1022 -> 1022 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_96_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_96_logo.png)bin989 -> 989 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_970_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_970_logo.png)bin1164 -> 1164 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_971_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_971_logo.png)bin1103 -> 1103 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_972_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_972_logo.png)bin1054 -> 1054 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_973_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_973_logo.png)bin1044 -> 1044 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_974_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_974_logo.png)bin966 -> 966 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_975_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_975_logo.png)bin1098 -> 1098 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_976_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_976_logo.png)bin1068 -> 1068 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_977_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_977_logo.png)bin1062 -> 1062 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_978_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_978_logo.png)bin1157 -> 1157 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_979_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_979_logo.png)bin1234 -> 1234 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_97_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_97_logo.png)bin861 -> 861 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_980_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_980_logo.png)bin1188 -> 1188 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_981_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_981_logo.png)bin1069 -> 1069 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_982_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_982_logo.png)bin1087 -> 1087 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_983_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_983_logo.png)bin920 -> 920 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_984_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_984_logo.png)bin1041 -> 1041 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_985_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_985_logo.png)bin984 -> 984 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_986_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_986_logo.png)bin1346 -> 1346 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_987_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_987_logo.png)bin1091 -> 1091 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_988_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_988_logo.png)bin1001 -> 1001 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_989_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_989_logo.png)bin1201 -> 1201 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_98_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_98_logo.png)bin902 -> 902 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_990_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_990_logo.png)bin1027 -> 1027 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_991_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_991_logo.png)bin1334 -> 1334 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_992_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_992_logo.png)bin1055 -> 1055 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_993_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_993_logo.png)bin1252 -> 1252 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_994_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_994_logo.png)bin1168 -> 1168 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_995_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_995_logo.png)bin1305 -> 1305 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_996_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_996_logo.png)bin1047 -> 1047 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_997_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_997_logo.png)bin1104 -> 1104 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_998_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_998_logo.png)bin996 -> 996 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_999_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_999_logo.png)bin999 -> 999 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_99_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_99_logo.png)bin900 -> 900 bytes
-rw-r--r--tests/common/res/drawable-xhdpi/ch_9_logo.png (renamed from tests/input/res/drawable-xhdpi/ch_9_logo.png)bin1031 -> 1031 bytes
-rw-r--r--tests/common/src/com/android/tv/testing/ChannelInfo.java22
-rw-r--r--tests/common/src/com/android/tv/testing/Utils.java38
-rw-r--r--tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java2
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/Constants.java3
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java11
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java11
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java16
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java7
-rw-r--r--tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java63
-rw-r--r--tests/func/Android.mk2
-rw-r--r--tests/func/OWNERS2
-rw-r--r--tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java4
-rw-r--r--tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java2
-rw-r--r--tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java54
-rw-r--r--tests/func/src/com/android/tv/tests/ui/ProgramGuidePerformanceTest.java59
-rw-r--r--tests/func/src/com/android/tv/tests/ui/dvr/DvrLibraryTest.java219
-rw-r--r--tests/func/src/com/android/tv/tests/ui/sidepanel/CustomizeChannelListFragmentTest.java117
-rw-r--r--tests/input/OWNERS2
-rw-r--r--tests/input/res/values/strings.xml1
-rw-r--r--tests/input/src/com/android/tv/testinput/TestTvInputService.java15
-rw-r--r--tests/input/src/com/android/tv/testinput/TestTvInputSetupActivity.java19
-rw-r--r--tests/input/src/com/android/tv/testinput/instrument/TestSetupInstrumentation.java2
-rw-r--r--tests/jank/Android.mk2
-rw-r--r--tests/jank/OWNERS2
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/ChannelZappingJankTest.java14
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/LiveChannelsTestCase.java48
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/MenuJankTest.java16
-rw-r--r--tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java30
-rw-r--r--tests/unit/Android.mk4
-rw-r--r--tests/unit/AndroidManifest.xml2
-rw-r--r--tests/unit/OWNERS2
-rw-r--r--tests/unit/src/com/android/tv/BaseMainActivityTestCase.java63
-rw-r--r--tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java26
-rw-r--r--tests/unit/src/com/android/tv/FeaturesTest.java10
-rw-r--r--tests/unit/src/com/android/tv/MainActivityTest.java27
-rw-r--r--tests/unit/src/com/android/tv/TimeShiftManagerTest.java13
-rw-r--r--tests/unit/src/com/android/tv/common/TvContentRatingCacheTest.java172
-rw-r--r--tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java101
-rw-r--r--tests/unit/src/com/android/tv/data/ChannelNumberTest.java23
-rw-r--r--tests/unit/src/com/android/tv/data/ChannelTest.java38
-rw-r--r--tests/unit/src/com/android/tv/data/GenreItemTest.java17
-rw-r--r--tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java55
-rw-r--r--tests/unit/src/com/android/tv/data/ProgramTest.java23
-rw-r--r--tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java27
-rw-r--r--tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java73
-rw-r--r--tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java33
-rw-r--r--tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java17
-rw-r--r--tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java14
-rw-r--r--tests/unit/src/com/android/tv/dvr/DvrDbSyncTest.java121
-rw-r--r--tests/unit/src/com/android/tv/dvr/DvrRecordingServiceTest.java68
-rw-r--r--tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java159
-rw-r--r--tests/unit/src/com/android/tv/dvr/EpisodicProgramLoadTaskTest.java76
-rw-r--r--tests/unit/src/com/android/tv/dvr/InputTaskSchedulerTest.java221
-rw-r--r--tests/unit/src/com/android/tv/dvr/RecordingTaskTest.java166
-rw-r--r--tests/unit/src/com/android/tv/dvr/ScheduledProgramReaperTest.java114
-rw-r--r--tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java23
-rw-r--r--tests/unit/src/com/android/tv/dvr/SchedulerTest.java107
-rw-r--r--tests/unit/src/com/android/tv/dvr/SeriesRecordingSchedulerTest.java111
-rw-r--r--tests/unit/src/com/android/tv/dvr/SeriesRecordingTest.java125
-rw-r--r--tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java133
-rw-r--r--tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java143
-rw-r--r--tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java83
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/DvrRecordingServiceTest.java183
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java231
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java149
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java137
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java125
-rw-r--r--tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java129
-rw-r--r--tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java67
-rw-r--r--tests/unit/src/com/android/tv/experiments/ExperimentsTest.java53
-rw-r--r--tests/unit/src/com/android/tv/menu/MenuTest.java20
-rw-r--r--tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java83
-rw-r--r--tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java22
-rw-r--r--tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java30
-rw-r--r--tests/unit/src/com/android/tv/recommendation/FavoriteChannelEvaluatorTest.java16
-rw-r--r--tests/unit/src/com/android/tv/recommendation/RecentChannelEvaluatorTest.java15
-rw-r--r--tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java1
-rw-r--r--tests/unit/src/com/android/tv/recommendation/RecommenderTest.java27
-rw-r--r--tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java35
-rw-r--r--tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java132
-rw-r--r--tests/unit/src/com/android/tv/tests/TvActivityTest.java23
-rw-r--r--tests/unit/src/com/android/tv/util/ImageCacheTest.java14
-rw-r--r--tests/unit/src/com/android/tv/util/MockApplicationSingletons.java154
-rw-r--r--tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java14
-rw-r--r--tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java10
-rw-r--r--tests/unit/src/com/android/tv/util/TestUtils.java27
-rw-r--r--tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java141
-rw-r--r--tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java15
-rw-r--r--tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java36
-rw-r--r--tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java21
-rw-r--r--tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java11
-rw-r--r--usbtuner-res/animator/setup_before_entry.xml32
-rw-r--r--usbtuner-res/animator/setup_before_exit.xml34
-rw-r--r--usbtuner-res/animator/setup_entry.xml35
-rw-r--r--usbtuner-res/animator/setup_exit.xml35
-rw-r--r--usbtuner-res/drawable-xhdpi/ic_setup_antenna.pngbin1264 -> 0 bytes
-rw-r--r--usbtuner-res/drawable/ut_selector_background.xml28
-rw-r--r--usbtuner-res/layout/ut_activity_playback.xml31
-rw-r--r--usbtuner-res/layout/ut_guidance.xml48
-rw-r--r--usbtuner-res/layout/ut_guidedactions.xml41
-rw-r--r--usbtuner-res/raw/ut_euro_dvbt_all287
-rw-r--r--usbtuner-res/raw/ut_kr_all1
-rw-r--r--usbtuner-res/raw/ut_kr_atsc_center_frequencies_8vsb1
-rw-r--r--usbtuner-res/raw/ut_us_all2
-rw-r--r--usbtuner-res/raw/ut_us_atsc_center_frequencies_8vsb1
-rw-r--r--usbtuner-res/raw/ut_us_cable_standard_center_frequencies_qam2561
-rw-r--r--usbtuner-res/values-af/strings.xml23
-rw-r--r--usbtuner-res/values-am/strings.xml23
-rw-r--r--usbtuner-res/values-ar/strings.xml23
-rw-r--r--usbtuner-res/values-az-rAZ/strings.xml90
-rw-r--r--usbtuner-res/values-az/strings.xml87
-rw-r--r--usbtuner-res/values-bg/strings.xml23
-rw-r--r--usbtuner-res/values-bn-rBD/strings.xml90
-rw-r--r--usbtuner-res/values-bn/strings.xml87
-rw-r--r--usbtuner-res/values-ca/strings.xml23
-rw-r--r--usbtuner-res/values-cs/strings.xml23
-rw-r--r--usbtuner-res/values-da/strings.xml35
-rw-r--r--usbtuner-res/values-de/strings.xml23
-rw-r--r--usbtuner-res/values-el/strings.xml23
-rw-r--r--usbtuner-res/values-en-rAU/strings.xml23
-rw-r--r--usbtuner-res/values-en-rGB/strings.xml23
-rw-r--r--usbtuner-res/values-en-rIN/strings.xml23
-rw-r--r--usbtuner-res/values-es-rUS/strings.xml23
-rw-r--r--usbtuner-res/values-es/strings.xml27
-rw-r--r--usbtuner-res/values-et-rEE/strings.xml90
-rw-r--r--usbtuner-res/values-et/strings.xml87
-rw-r--r--usbtuner-res/values-eu-rES/strings.xml90
-rw-r--r--usbtuner-res/values-eu/strings.xml87
-rw-r--r--usbtuner-res/values-fa/strings.xml23
-rw-r--r--usbtuner-res/values-fi/strings.xml23
-rw-r--r--usbtuner-res/values-fr-rCA/strings.xml23
-rw-r--r--usbtuner-res/values-fr/strings.xml23
-rw-r--r--usbtuner-res/values-gl-rES/strings.xml90
-rw-r--r--usbtuner-res/values-gl/strings.xml87
-rw-r--r--usbtuner-res/values-hi/strings.xml25
-rw-r--r--usbtuner-res/values-hr/strings.xml23
-rw-r--r--usbtuner-res/values-hu/strings.xml23
-rw-r--r--usbtuner-res/values-hy-rAM/strings.xml90
-rw-r--r--usbtuner-res/values-hy/strings.xml87
-rw-r--r--usbtuner-res/values-in/strings.xml25
-rw-r--r--usbtuner-res/values-is-rIS/strings.xml90
-rw-r--r--usbtuner-res/values-is/strings.xml87
-rw-r--r--usbtuner-res/values-it/strings.xml23
-rw-r--r--usbtuner-res/values-iw/strings.xml23
-rw-r--r--usbtuner-res/values-ja/strings.xml23
-rw-r--r--usbtuner-res/values-ka-rGE/strings.xml90
-rw-r--r--usbtuner-res/values-ka/strings.xml87
-rw-r--r--usbtuner-res/values-kk-rKZ/strings.xml90
-rw-r--r--usbtuner-res/values-kk/strings.xml87
-rw-r--r--usbtuner-res/values-km-rKH/strings.xml90
-rw-r--r--usbtuner-res/values-km/strings.xml87
-rw-r--r--usbtuner-res/values-kn-rIN/strings.xml90
-rw-r--r--usbtuner-res/values-kn/strings.xml87
-rw-r--r--usbtuner-res/values-ko/strings.xml25
-rw-r--r--usbtuner-res/values-ky-rKG/strings.xml90
-rw-r--r--usbtuner-res/values-ky/strings.xml87
-rw-r--r--usbtuner-res/values-lo-rLA/strings.xml90
-rw-r--r--usbtuner-res/values-lo/strings.xml87
-rw-r--r--usbtuner-res/values-lt/strings.xml23
-rw-r--r--usbtuner-res/values-lv/strings.xml23
-rw-r--r--usbtuner-res/values-mk-rMK/strings.xml90
-rw-r--r--usbtuner-res/values-mk/strings.xml87
-rw-r--r--usbtuner-res/values-ml-rIN/strings.xml90
-rw-r--r--usbtuner-res/values-ml/strings.xml87
-rw-r--r--usbtuner-res/values-mn-rMN/strings.xml90
-rw-r--r--usbtuner-res/values-mn/strings.xml87
-rw-r--r--usbtuner-res/values-mr-rIN/strings.xml90
-rw-r--r--usbtuner-res/values-mr/strings.xml87
-rw-r--r--usbtuner-res/values-ms-rMY/strings.xml90
-rw-r--r--usbtuner-res/values-ms/strings.xml87
-rw-r--r--usbtuner-res/values-my-rMM/strings.xml90
-rw-r--r--usbtuner-res/values-my/strings.xml87
-rw-r--r--usbtuner-res/values-nb/strings.xml23
-rw-r--r--usbtuner-res/values-ne-rNP/strings.xml90
-rw-r--r--usbtuner-res/values-ne/strings.xml87
-rw-r--r--usbtuner-res/values-nl/strings.xml23
-rw-r--r--usbtuner-res/values-pl/strings.xml23
-rw-r--r--usbtuner-res/values-pt-rPT/strings.xml29
-rw-r--r--usbtuner-res/values-pt/strings.xml23
-rw-r--r--usbtuner-res/values-ro/strings.xml23
-rw-r--r--usbtuner-res/values-ru/strings.xml23
-rw-r--r--usbtuner-res/values-si-rLK/strings.xml90
-rw-r--r--usbtuner-res/values-si/strings.xml87
-rw-r--r--usbtuner-res/values-sk/strings.xml23
-rw-r--r--usbtuner-res/values-sl/strings.xml23
-rw-r--r--usbtuner-res/values-sr/strings.xml23
-rw-r--r--usbtuner-res/values-sv/strings.xml23
-rw-r--r--usbtuner-res/values-sw/strings.xml23
-rw-r--r--usbtuner-res/values-ta-rIN/strings.xml90
-rw-r--r--usbtuner-res/values-ta/strings.xml87
-rw-r--r--usbtuner-res/values-te-rIN/strings.xml90
-rw-r--r--usbtuner-res/values-te/strings.xml87
-rw-r--r--usbtuner-res/values-th/strings.xml23
-rw-r--r--usbtuner-res/values-tl/strings.xml23
-rw-r--r--usbtuner-res/values-tr/strings.xml23
-rw-r--r--usbtuner-res/values-uk/strings.xml23
-rw-r--r--usbtuner-res/values-ur-rPK/strings.xml90
-rw-r--r--usbtuner-res/values-ur/strings.xml87
-rw-r--r--usbtuner-res/values-uz-rUZ/strings.xml90
-rw-r--r--usbtuner-res/values-uz/strings.xml87
-rw-r--r--usbtuner-res/values-vi/strings.xml23
-rw-r--r--usbtuner-res/values-zh-rCN/strings.xml23
-rw-r--r--usbtuner-res/values-zh-rHK/strings.xml23
-rw-r--r--usbtuner-res/values-zh-rTW/strings.xml23
-rw-r--r--usbtuner-res/values-zu/strings.xml23
-rw-r--r--usbtuner-res/values/colors.xml6
-rw-r--r--usbtuner-res/values/dimens.xml34
-rw-r--r--usbtuner-res/values/integers.xml5
-rw-r--r--usbtuner-res/values/strings.xml72
-rw-r--r--usbtuner-res/values/styles.xml120
-rw-r--r--version.mk6
1979 files changed, 56405 insertions, 39410 deletions
diff --git a/Android.mk b/Android.mk
index 18468adc..7970f6f1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -18,6 +18,7 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+
LOCAL_MODULE_TAGS := optional
include $(LOCAL_PATH)/version.mk
@@ -28,6 +29,8 @@ LOCAL_SRC_FILES := \
LOCAL_PACKAGE_NAME := LiveTv
+
+
# It is required for com.android.providers.tv.permission.ALL_EPG_DATA
LOCAL_PRIVILEGED_MODULE := true
@@ -40,29 +43,40 @@ LOCAL_RESOURCE_DIR := \
ifdef TARGET_BUILD_APPS
LOCAL_RESOURCE_DIR += \
+ $(TOP)/prebuilts/sdk/current/support/compat/res \
$(TOP)/prebuilts/sdk/current/support/v17/leanback/res \
$(TOP)/prebuilts/sdk/current/support/v7/recyclerview/res
else # !TARGET_BUILD_APPS
LOCAL_RESOURCE_DIR += \
+ $(TOP)/frameworks/support/compat/res \
$(TOP)/frameworks/support/v17/leanback/res \
$(TOP)/frameworks/support/v7/recyclerview/res
endif
+LOCAL_SRC_FILES += \
+ src/com/android/tv/tuner/exoplayer/ffmpeg/IFfmpegDecoder.aidl
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-annotations \
- android-support-v4 \
+ android-support-compat \
+ android-support-core-ui \
android-support-v7-palette \
android-support-v7-recyclerview \
android-support-v17-leanback \
icu4j-usbtuner \
lib-exoplayer \
+ lib-exoplayer-v2 \
+ lib-exoplayer-v2-ext-ffmpeg \
+ prebuilt-support-tv-provider \
tv-common \
-LOCAL_JAVA_LIBRARIES := junit
+
+
+
LOCAL_JAVACFLAGS := -Xlint:deprecation -Xlint:unchecked
-LOCAL_AAPT_FLAGS := --auto-add-overlay \
+LOCAL_AAPT_FLAGS += --auto-add-overlay \
+ --extra-packages android.support.compat \
--extra-packages android.support.v7.recyclerview \
--extra-packages android.support.v17.leanback \
--extra-packages com.android.tv.common \
@@ -95,16 +109,19 @@ LOCAL_SDK_VERSION := system_current
include $(BUILD_STATIC_JAVA_LIBRARY)
+
#############################################################
# Pre-built dependency jars
#############################################################
-
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
lib-exoplayer:libs/exoplayer.jar \
+ lib-exoplayer-v2:libs/exoplayer_v2.jar \
+ lib-exoplayer-v2-ext-ffmpeg:libs/exoplayer_v2_ext_ffmpeg.jar \
+ prebuilt-support-tv-provider:../../../prebuilts/sdk/current/support/tv-provider/android-support-tv-provider.jar \
include $(BUILD_MULTI_PREBUILT)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1faa2ae3..8770301e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -20,12 +20,14 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_HDMI_CEC_ACTIVE_SOURCE" />
<uses-permission android:name="android.permission.GLOBAL_SEARCH" tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.MODIFY_PARENTAL_CONTROLS" />
+ <uses-permission android:name="android.permission.READ_CONTENT_RATING_SYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_TV_LISTINGS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- <uses-permission android:name="android.permission.MODIFY_PARENTAL_CONTROLS" />
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
<uses-permission android:name="com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA" />
@@ -45,8 +47,16 @@
<permission android:name="com.android.tv.permission.RECEIVE_INPUT_EVENT"
android:protectionLevel="signatureOrSystem"
android:label="@string/permlab_receiveInputEvent"
- android:description="@string/permdesc_receiveInputEvent" tools:ignore="SignatureOrSystemPermissions"/>
- <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="23"/>
+ android:description="@string/permdesc_receiveInputEvent"
+ tools:ignore="SignatureOrSystemPermissions"/>
+ <!-- Customizes Live TV with customization packages. -->
+ <permission android:name="com.android.tv.permission.CUSTOMIZE_TV_APP"
+ android:protectionLevel="signatureOrSystem"
+ android:label="@string/permlab_customizeTvApp"
+ android:description="@string/permdesc_customizeTvApp"
+ tools:ignore="SignatureOrSystemPermissions"/>
+
+ <uses-sdk android:targetSdkVersion="26" android:minSdkVersion="23"/>
<application android:label="@string/app_name"
android:name=".TvApplication"
@@ -113,17 +123,33 @@
android:launchMode="singleTop"
android:theme="@style/Theme.Setup.GuidedStep" />
- <activity android:name=".dvr.ui.DvrActivity"
+ <activity android:name=".dvr.ui.browse.DvrBrowseActivity"
android:configChanges="keyboard|keyboardHidden"
android:launchMode="singleTask"
- android:theme="@style/Theme.Leanback.Browse" />
+ android:theme="@style/Theme.Leanback.Browse">
+ <intent-filter>
+ <action android:name="android.media.tv.action.VIEW_RECORDING_SCHEDULES" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.dir/recorded_program" />
+ </intent-filter>
+ </activity>
- <activity android:name=".dvr.DvrPlaybackActivity"
+ <activity android:name=".dvr.ui.playback.DvrPlaybackActivity"
android:configChanges="keyboard|keyboardHidden|screenSize|smallestScreenSize|screenLayout|orientation"
android:launchMode="singleTask"
- android:theme="@style/Theme.Leanback" />
+ android:theme="@style/Theme.Leanback">
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.item/recorded_program" />
+ </intent-filter>
+ </activity>
- <activity android:name=".dvr.ui.DvrDetailsActivity"
+ <activity android:name=".dvr.ui.browse.DvrDetailsActivity"
android:configChanges="keyboard|keyboardHidden"
android:theme="@style/Theme.TV.Dvr.Browse.Details" />
@@ -138,7 +164,7 @@
<activity android:name=".dvr.ui.DvrSeriesScheduledDialogActivity"
android:theme="@style/Theme.TV.dialog.HalfSizedDialog"/>
- <activity android:name=".dvr.ui.DvrSchedulesActivity"
+ <activity android:name=".dvr.ui.list.DvrSchedulesActivity"
android:configChanges="keyboard|keyboardHidden"
android:theme="@style/Theme.Leanback.Details" />
@@ -151,6 +177,8 @@
<service android:name="com.android.tv.recommendation.NotificationService"
android:exported="false" />
+ <service android:name=".recommendation.ChannelPreviewUpdater$ChannelPreviewUpdateService"
+ android:permission="android.permission.BIND_JOB_SERVICE" />
<receiver android:name="com.android.tv.receiver.BootCompletedReceiver">
<intent-filter>
@@ -206,6 +234,13 @@
<meta-data android:name="android.media.tv.input"
android:resource="@xml/ut_tvinputservice" />
</service>
+ <service android:name=".tuner.exoplayer.ffmpeg.FfmpegDecoderService"
+ android:isolatedProcess="true"
+ android:process="com.android.tv.ffmpeg" >
+ <intent-filter>
+ <action android:name=".tuner.exoplayer.ffmpeg.IFfmpegDecoder" />
+ </intent-filter>
+ </service>
<provider android:name=".tuner.TunerPreferenceProvider"
android:authorities="com.android.tv.tuner.preferences"
android:process="com.android.tv.tuner"
@@ -222,24 +257,30 @@
</intent-filter>
</activity>
<!-- TunerInputController should be the same process with MainActivity to check status of MainActivity -->
- <receiver android:name=".tuner.TunerInputController"
+ <receiver android:name=".tuner.TunerInputController$IntentReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
<action android:name="com.android.tv.action.APPLICATION_FIRST_LAUNCHED" />
+ <action android:name="com.android.tv.action.NETWORK_TUNER_ATTACHED" />
+ <action android:name="com.android.tv.action.NETWORK_TUNER_DETACHED" />
</intent-filter>
</receiver>
<!-- DVR -->
- <service android:name=".dvr.DvrRecordingService" android:label="@string/dvr_service_name"/>
- <receiver android:name=".dvr.DvrStartRecordingReceiver"/>
+ <service android:name=".dvr.recorder.DvrRecordingService" android:label="@string/dvr_service_name" />
+ <receiver android:name=".dvr.recorder.DvrStartRecordingReceiver" />
<service android:name=".tuner.tvinput.TunerStorageCleanUpService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process="com.android.tv.tuner"
android:exported="true" />
+ <service android:name=".data.epg.EpgFetcher$EpgFetchService"
+ android:permission="android.permission.BIND_JOB_SERVICE" />
+
+
</application>
</manifest>
diff --git a/assets/licenses.html b/assets/licenses.html
deleted file mode 100644
index 000aacf6..00000000
--- a/assets/licenses.html
+++ /dev/null
@@ -1,298 +0,0 @@
-<!--
- ~ Copyright (C) 2015 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.
- -->
-
-<html><head><style> body { font-family: sans-serif; } pre { background-color: #eeeeee; padding: 1em; white-space: pre-wrap; } </style></head><body>
-<!-- START Live Channels licenses -->
-<h3>Notices for files:</h3>
-<ul>
- <li>protobuf</li>
-</ul>
-<pre>Copyright 2008, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Code generated by the Protocol Buffer compiler is owned by the owner
-of the input file used when generating it. This code is not
-standalone and requires a support library to be linked with it. This
-support library is itself covered by the above license.
-</pre>
-
-<!-- END Live Channels licenses -->
-<!-- START USB Tuner licenses -->
-<h3>Notices for files:</h3>
-<ul>
- <li>icu4j</li>
-</ul>
-<pre>Copyright (c) 1995-2013 International Business Machines Corporation and others
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, and/or sell copies of the
-Software, and to permit persons to whom the Software is furnished to do so,
-provided that the above copyright notice(s) and this permission notice appear
-in all copies of the Software and that both the above copyright notice(s) and
-this permission notice appear in supporting documentation.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
-NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
-LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
-DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall not be
-used in advertising or otherwise to promote the sale, use or other dealings in
-this Software without prior written authorization of the copyright holder.
-</pre>
-<h3>Notices for files:</h3>
-<ul>
- <li>ExoPlayer</li>
-</ul>
-<pre> Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
-</pre>
-<!-- END USB Tuner licenses -->
-
-</body></html> \ No newline at end of file
diff --git a/assets/whitelist.policy b/assets/whitelist.policy
new file mode 100644
index 00000000..33af781d
--- /dev/null
+++ b/assets/whitelist.policy
@@ -0,0 +1,39 @@
+clone: 1
+close: 1
+epoll_pwait: 1
+exit: 1
+faccessat: 1
+fstat64: 1
+fstatfs64: 1
+futex: 1
+getegid32: 1
+geteuid32: 1
+getgid32: 1
+getgroups32: 1
+getpriority: 1
+getsockopt: 1
+gettimeofday: 1
+getuid32: 1
+ioctl: 1
+madvise: 1
+mmap: 1
+mmap2: 1
+mprotect: 1
+munmap: 1
+open: 1
+openat: 1
+pread64: 1
+prctl: 1
+pselect6: 1
+read: 1
+readlinkat: 1
+rt_sigprocmask: 1
+rt_sigtimedwait: 1
+sched_yield: 1
+setpriority: 1
+setsockopt: 1
+set_thread_area: 1
+set_tid_address: 1
+sigaction: 1
+sigaltstack: 1
+write: 1 \ No newline at end of file
diff --git a/common/Android.mk b/common/Android.mk
index bd4d99bc..d632597f 100644
--- a/common/Android.mk
+++ b/common/Android.mk
@@ -10,17 +10,20 @@ LOCAL_MODULE_TAGS := optional
LOCAL_SDK_VERSION := system_current
LOCAL_RESOURCE_DIR := \
+ $(TOP)/prebuilts/sdk/current/support/compat/res \
$(TOP)/prebuilts/sdk/current/support/v7/recyclerview/res \
$(TOP)/prebuilts/sdk/current/support/v17/leanback/res \
$(LOCAL_PATH)/res \
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-annotations \
- android-support-v4 \
+ android-support-compat \
+ android-support-core-ui \
android-support-v7-recyclerview \
android-support-v17-leanback \
LOCAL_AAPT_FLAGS := --auto-add-overlay \
+ --extra-packages android.support.compat \
--extra-packages android.support.v7.recyclerview \
--extra-packages android.support.v17.leanback \
diff --git a/common/OWNERS b/common/OWNERS
new file mode 100644
index 00000000..4aa5fe52
--- /dev/null
+++ b/common/OWNERS
@@ -0,0 +1,2 @@
+nchalko@google.com
+shubang@google.com
diff --git a/common/res/drawable/setup_selector_background.xml b/common/res/drawable/setup_selector_background.xml
index 7351270b..b73c5813 100644
--- a/common/res/drawable/setup_selector_background.xml
+++ b/common/res/drawable/setup_selector_background.xml
@@ -17,8 +17,7 @@
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
- <!-- Note that android:start and android:end is not supported in L platform. -->
- <item android:id="@android:id/mask" android:left="24dp" android:right="24dp">
+ <item android:id="@android:id/mask">
<shape>
<solid android:color="@android:color/white"/>
<corners android:radius="2dp" />
diff --git a/common/res/layout/fragment_setup_multi_pane.xml b/common/res/layout/fragment_setup_multi_pane.xml
index 45aff132..e3ff8d83 100644
--- a/common/res/layout/fragment_setup_multi_pane.xml
+++ b/common/res/layout/fragment_setup_multi_pane.xml
@@ -40,11 +40,13 @@
android:clipChildren="false"
android:clipToPadding="false" />
<!-- TODO: Use button action list in GuidedStepFragment -->
- <FrameLayout
+ <LinearLayout
android:id="@+id/done_button_container"
android:layout_width="@dimen/setup_done_button_container_width"
android:layout_height="match_parent"
android:layout_gravity="end"
+ android:orientation="vertical"
+ android:paddingTop="190dp"
style="?attr/doneButtonContainerStyle"
android:transitionGroup="true"
android:transitionName="buttonDoneTransition">
@@ -54,7 +56,6 @@
android:layout_height="45dp"
android:layout_marginStart="24dp"
android:layout_marginEnd="40dp"
- android:layout_marginTop="190dp"
android:elevation="0dp"
android:focusable="true"
android:fontFamily="sans-serif-condensed"
@@ -65,5 +66,23 @@
android:text="@string/action_text_done"
android:textColor="#EEEEEE"
android:textSize="14sp" />
- </FrameLayout>
+ <TextView
+ android:id="@+id/button_skip"
+ android:layout_width="match_parent"
+ android:layout_height="45dp"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="40dp"
+ android:layout_marginTop="8dp"
+ android:elevation="0dp"
+ android:focusable="true"
+ android:fontFamily="sans-serif-condensed"
+ android:paddingEnd="12dp"
+ android:paddingStart="12dp"
+ android:background="@drawable/setup_action_button_done"
+ android:gravity="center_vertical|start"
+ android:visibility="gone"
+ android:text="@string/action_text_skip"
+ android:textColor="#EEEEEE"
+ android:textSize="14sp" />
+ </LinearLayout>
</FrameLayout>
diff --git a/common/res/values-af/strings.xml b/common/res/values-af/strings.xml
index 7a114849..ae7dbb60 100644
--- a/common/res/values-af/strings.xml
+++ b/common/res/values-af/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Klaar"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Slaan oor"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S.<xliff:g id="SEASON_NUMBER">%1$s</xliff:g> Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S.<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S.<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S.<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-am/strings.xml b/common/res/values-am/strings.xml
index 45a1b7cb..5c2f0964 100644
--- a/common/res/values-am/strings.xml
+++ b/common/res/values-am/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"ተከናውኗል"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"ዝለል"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"ም<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>፦ ክ.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ክ.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"ም<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>፦ ክፍል <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ክፍል <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ም<xliff:g id="SEASONNUMBER">%2$s</xliff:g>፦ ክፍል <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ክፍል <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ም<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ክፍል፦ <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ክፍል <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-ar/strings.xml b/common/res/values-ar/strings.xml
index bedd137b..1cb0daa7 100644
--- a/common/res/values-ar/strings.xml
+++ b/common/res/values-ar/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"تم"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"تخطي"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"الموسم <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: الحلقة <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"الحلقة <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"الموسم <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: الحلقة <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"الحلقة <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> الموسم رقم <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: الحلقة رقم <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> الحلقة رقم <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"‏<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;الموسم رقم <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: الحلقة <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"‏<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;الحلقة <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-az-rAZ/strings.xml b/common/res/values-az-rAZ/strings.xml
new file mode 100644
index 00000000..ca96c57b
--- /dev/null
+++ b/common/res/values-az-rAZ/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Hazırdır"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Keçin"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Epizod<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Fəsil<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Epizod. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Epizod. <xliff:g id="EPISODENUMBER">%2$s</xliff:g> &lt;i&gt;"</string>
+</resources>
diff --git a/common/res/values-az/strings.xml b/common/res/values-az/strings.xml
deleted file mode 100644
index c844cd60..00000000
--- a/common/res/values-az/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Hazırdır"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Epizod<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-bg/strings.xml b/common/res/values-bg/strings.xml
index 264a1118..607ad9d7 100644
--- a/common/res/values-bg/strings.xml
+++ b/common/res/values-bg/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Готово"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Пропускане"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Сезон <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: епизод <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Епизод <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Сезон <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Еп. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> – „<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>“"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Еп. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> – „<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>“"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"„<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“, сезон <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, епизод <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"„<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“, епизод <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"„<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“, &lt;i&gt;сез. <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, еп. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"„<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“, &lt;i&gt;еп. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-bn-rBD/strings.xml b/common/res/values-bn-rBD/strings.xml
new file mode 100644
index 00000000..73706be7
--- /dev/null
+++ b/common/res/values-bn-rBD/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"সম্পন্ন"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"এড়িয়ে যান"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"সিজন <xliff:g id="SEASON_NUMBER">%1$s</xliff:g> , পর্ব <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"পর্ব<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"সিঃ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: এপিঃ <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"এপিঃ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;সিজিন<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: পর্ব <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;পর্ব <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-bn/strings.xml b/common/res/values-bn/strings.xml
deleted file mode 100644
index 836a62a5..00000000
--- a/common/res/values-bn/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"সম্পন্ন"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"সিজন <xliff:g id="SEASON_NUMBER">%1$s</xliff:g> , পর্ব <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"পর্ব<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"সিঃ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: এপিঃ <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"এপিঃ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> সিজিন<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: পর্ব <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> পর্ব. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-ca/strings.xml b/common/res/values-ca/strings.xml
index 6382648e..4ef6c99b 100644
--- a/common/res/values-ca/strings.xml
+++ b/common/res/values-ca/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Fet"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Omet"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Temporada <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, episodi <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Episodi <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Temporada <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, episodi <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Episodi <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: temporada <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, episodi <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: episodi <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: &lt;i&gt;temp. <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: &lt;i&gt;ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-cs/strings.xml b/common/res/values-cs/strings.xml
index 0be8026c..a6aa1173 100644
--- a/common/res/values-cs/strings.xml
+++ b/common/res/values-cs/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Hotovo"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Přeskočit"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>E<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"E<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> – <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> – <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-da/strings.xml b/common/res/values-da/strings.xml
index 4685b818..3eeb51da 100644
--- a/common/res/values-da/strings.xml
+++ b/common/res/values-da/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Udført"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Spring over"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, afsn. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Afsn. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Afsnit <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>, <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Afsnit <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S. <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Afsn. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> afsn. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S. <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Afsn. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Afsn. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-de/strings.xml b/common/res/values-de/strings.xml
index a487ff8a..11e8b0da 100644
--- a/common/res/values-de/strings.xml
+++ b/common/res/values-de/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Fertig"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Überspringen"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: F<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Folge <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Staffel <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Folge <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>, <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Folge <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>, <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, Staffel <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Folge <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, Folge <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, &lt;i&gt;Staffel <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Folge <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, &lt;i&gt;Folge <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-el/strings.xml b/common/res/values-el/strings.xml
index dba894cb..60a73442 100644
--- a/common/res/values-el/strings.xml
+++ b/common/res/values-el/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Τέλος"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Παράβλεψη"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Σεζ. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Επ.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Επ.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Σεζ.<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Επ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Επ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Σεζόν<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Επ. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Επ. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Επ. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Επ. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-en-rAU/strings.xml b/common/res/values-en-rAU/strings.xml
index 0ea27edc..94d1c120 100644
--- a/common/res/values-en-rAU/strings.xml
+++ b/common/res/values-en-rAU/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Finished"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Skip"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-en-rGB/strings.xml b/common/res/values-en-rGB/strings.xml
index 0ea27edc..94d1c120 100644
--- a/common/res/values-en-rGB/strings.xml
+++ b/common/res/values-en-rGB/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Finished"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Skip"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-en-rIN/strings.xml b/common/res/values-en-rIN/strings.xml
index 0ea27edc..94d1c120 100644
--- a/common/res/values-en-rIN/strings.xml
+++ b/common/res/values-en-rIN/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Finished"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Skip"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-es-rUS/strings.xml b/common/res/values-es-rUS/strings.xml
index 87c881b8..3a15ff3a 100644
--- a/common/res/values-es-rUS/strings.xml
+++ b/common/res/values-es-rUS/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Listo"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Omitir"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Temporada <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: episodio <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Episodio <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Temporada <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, episodio <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Episodio <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: T<xliff:g id="SEASONNUMBER">%2$s</xliff:g>, episodio <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: episodio <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Temporada <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Episodio <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Episodio <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-es/strings.xml b/common/res/values-es/strings.xml
index 32536d93..0e7e5ef4 100644
--- a/common/res/values-es/strings.xml
+++ b/common/res/values-es/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Listo"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Saltar"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Temporada <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: episodio <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Episodio <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Temporada <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: episodio <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Episodio <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"Temporada <xliff:g id="SEASONNUMBER">%2$s</xliff:g> de <xliff:g id="PROGRAMNAME">%1$s</xliff:g>, episodio <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"Episodio <xliff:g id="EPISODENUMBER">%2$s</xliff:g> de <xliff:g id="PROGRAMNAME">%1$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"Temporada <xliff:g id="SEASONNUMBER">%2$s</xliff:g> de <xliff:g id="PROGRAMNAME">%1$s</xliff:g>: &lt;i&gt;episodio <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"&lt;i&gt;Episodio <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt; de <xliff:g id="PROGRAMNAME">%1$s</xliff:g>"</string>
</resources>
diff --git a/common/res/values-et-rEE/strings.xml b/common/res/values-et-rEE/strings.xml
new file mode 100644
index 00000000..baa39d7b
--- /dev/null
+++ b/common/res/values-et-rEE/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Valmis"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Jäta vahele"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. hooaeg: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. jagu"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. jagu"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. hooaeg: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. jagu – <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. jagu – <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;<xliff:g id="SEASONNUMBER">%2$s</xliff:g>. h.: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. jagu &lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt; <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. jagu &lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-et/strings.xml b/common/res/values-et/strings.xml
deleted file mode 100644
index 9052178a..00000000
--- a/common/res/values-et/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Valmis"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. hooaeg: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. jagu"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. jagu"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. hooaeg: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. jagu – <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. jagu – <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – <xliff:g id="SEASONNUMBER">%2$s</xliff:g>. hooaeg, <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. jagu"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. jagu"</string>
-</resources>
diff --git a/common/res/values-eu-rES/strings.xml b/common/res/values-eu-rES/strings.xml
new file mode 100644
index 00000000..90e82da1
--- /dev/null
+++ b/common/res/values-eu-rES/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Eginda"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Saltatu"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. denboraldiko <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. atala"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. atala"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. denboraldiko <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. atala: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. atala: <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;<xliff:g id="SEASONNUMBER">%2$s</xliff:g>. denboraldia: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. atala&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;<xliff:g id="EPISODENUMBER">%2$s</xliff:g>. atala&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-eu/strings.xml b/common/res/values-eu/strings.xml
deleted file mode 100644
index d7ab52a8..00000000
--- a/common/res/values-eu/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Eginda"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. denboraldiko <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. atala"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. atala"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. denboraldiko <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. atala: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. atala: <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, <xliff:g id="SEASONNUMBER">%2$s</xliff:g>. denboraldia: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. atala"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. atala"</string>
-</resources>
diff --git a/common/res/values-fa/strings.xml b/common/res/values-fa/strings.xml
index 67e9c4e6..55e7c488 100644
--- a/common/res/values-fa/strings.xml
+++ b/common/res/values-fa/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"تمام"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"رد شدن"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"فصل<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: قسمت<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"اپیزود <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"ف.<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ق. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ق. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> فصل <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: قسمت <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> قسمت <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"‏<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;فصل<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: قسمت <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"‏<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;قسمت <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-fi/strings.xml b/common/res/values-fi/strings.xml
index 8c6b99bf..274aeb5f 100644
--- a/common/res/values-fi/strings.xml
+++ b/common/res/values-fi/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Valmis"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Ohita"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Kausi <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, jakso <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Jakso <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Kausi <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, jakso <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Jakso <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> kausi <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, jakso <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> jakso <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;K<xliff:g id="SEASONNUMBER">%2$s</xliff:g>, J<xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;J<xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-fr-rCA/strings.xml b/common/res/values-fr-rCA/strings.xml
index ed5678e2..4f88b206 100644
--- a/common/res/values-fr-rCA/strings.xml
+++ b/common/res/values-fr-rCA/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Terminé"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Ignorer"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Saison <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, ép. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ép. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Saison <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, épisode <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>, « <xliff:g id="EPISODE_TITLE">%3$s</xliff:g> »"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Épisode <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>, « <xliff:g id="EPISODE_TITLE">%2$s</xliff:g> »"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, saison <xliff:g id="SEASONNUMBER">%2$s</xliff:g> : épisode <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, épisode <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S <xliff:g id="SEASONNUMBER">%2$s</xliff:g> : ép. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ép. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-fr/strings.xml b/common/res/values-fr/strings.xml
index b5b28104..95408bde 100644
--- a/common/res/values-fr/strings.xml
+++ b/common/res/values-fr/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"OK"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Passer"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Saison <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, épisode <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Épisode <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, ép. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> : <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ép. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> : <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – S <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, ép. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – Ép. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – &lt;i&gt; S <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, ép. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – &lt;i&gt;, ép. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-gl-rES/strings.xml b/common/res/values-gl-rES/strings.xml
new file mode 100644
index 00000000..dfcbdfc2
--- /dev/null
+++ b/common/res/values-gl-rES/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Feito"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Omitir"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"T <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"T<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;T<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-gl/strings.xml b/common/res/values-gl/strings.xml
deleted file mode 100644
index 356ac562..00000000
--- a/common/res/values-gl/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Feito"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"T <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"T<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> T<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-gu-rIN/strings.xml b/common/res/values-gu-rIN/strings.xml
new file mode 100644
index 00000000..701977fa
--- /dev/null
+++ b/common/res/values-gu-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"થઈ ગયું"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"છોડો"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"સિઝન<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: એપિસોડ<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"એપિસોડ<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"સિઝન<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: એપિસોડ <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"એપિસોડ<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g><xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;સિઝન<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ઍપિસોડ <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ઍપિસોડ <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-hi/strings.xml b/common/res/values-hi/strings.xml
index 27cae84d..7bed8f0c 100644
--- a/common/res/values-hi/strings.xml
+++ b/common/res/values-hi/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"हो गया"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"अभी नहीं"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"सीज़न<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: एपिसोड<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"एपिसोड <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"सीज़न<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: एपिसोड <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"एपिसोड <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> सीज़न<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: एपिसोड <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> एपिसोड <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;सीज़न<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: एपिसोड <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;एपिसोड <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-hr/strings.xml b/common/res/values-hr/strings.xml
index 66127784..7fad7d05 100644
--- a/common/res/values-hr/strings.xml
+++ b/common/res/values-hr/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Gotovo"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Preskoči"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> <xliff:g id="SEASONNUMBER">%2$s</xliff:g>. s.: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. ep."</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. ep."</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-hu/strings.xml b/common/res/values-hu/strings.xml
index 138ad857..7b5867e3 100644
--- a/common/res/values-hu/strings.xml
+++ b/common/res/values-hu/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Kész"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Kihagyás"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. évad, <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. rész"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. rész"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. évad, <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. rész: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. rész: <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – <xliff:g id="SEASONNUMBER">%2$s</xliff:g>. évad, <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. epizód"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. epizód"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – &lt;i&gt;<xliff:g id="SEASONNUMBER">%2$s</xliff:g>. évad <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. rész&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – &lt;i&gt;<xliff:g id="EPISODENUMBER">%2$s</xliff:g>. rész&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-hy-rAM/strings.xml b/common/res/values-hy-rAM/strings.xml
new file mode 100644
index 00000000..ed13be2d
--- /dev/null
+++ b/common/res/values-hy-rAM/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Պատրաստ է"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Բաց թողնել"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"Ե <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>՝ դրվ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Դրվ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"Ե<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>՝ դրվ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Դրվ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-hy/strings.xml b/common/res/values-hy/strings.xml
deleted file mode 100644
index aaa7470f..00000000
--- a/common/res/values-hy/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Պատրաստ է"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"Ե <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>՝ դրվ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Դրվ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"Ե<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>՝ դրվ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Դրվ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ե<xliff:g id="SEASONNUMBER">%2$s</xliff:g>՝ Դրվ. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Դրվ. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-in/strings.xml b/common/res/values-in/strings.xml
index da4b8203..89f4d532 100644
--- a/common/res/values-in/strings.xml
+++ b/common/res/values-in/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Selesai"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Lewati"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-is-rIS/strings.xml b/common/res/values-is-rIS/strings.xml
new file mode 100644
index 00000000..d68d8250
--- /dev/null
+++ b/common/res/values-is-rIS/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Lokið"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Sleppa"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"S.<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Þ.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. þáttur"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"S.<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Þ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Þ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Þ. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Þ. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-is/strings.xml b/common/res/values-is/strings.xml
deleted file mode 100644
index 47529403..00000000
--- a/common/res/values-is/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Lokið"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"S.<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Þ.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. þáttur"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"S.<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Þ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Þ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S.<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Þ. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Þ. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-it/strings.xml b/common/res/values-it/strings.xml
index f61e02f7..137d5458 100644
--- a/common/res/values-it/strings.xml
+++ b/common/res/values-it/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Fine"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Ignora"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Stagione <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, puntata <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Stag. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: punt. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Punt. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Stag. <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: punt. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Punt. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Stag. <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: punt. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Punt. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-iw/strings.xml b/common/res/values-iw/strings.xml
index 7ad220ad..fdc75ce1 100644
--- a/common/res/values-iw/strings.xml
+++ b/common/res/values-iw/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"סיום"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"דלג"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"עונה <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: פרק <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"פרק <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"עונה<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: פרק <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"פרק <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> עונה <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: פרק <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> פרק <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"‏<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;עונה <xliff:g id="SEASONNUMBER">%2$s</xliff:g> פרק <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"‏<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;פרק <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-ja/strings.xml b/common/res/values-ja/strings.xml
index 682fd0d8..e0aa93bb 100644
--- a/common/res/values-ja/strings.xml
+++ b/common/res/values-ja/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"完了"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"スキップ"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"シーズン <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: エピソード <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"エピソード <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"シーズン <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: エピソード <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>「<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>」"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"エピソード <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>「<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>」"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>、シーズン <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: エピソード <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>、エピソード <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-ka-rGE/strings.xml b/common/res/values-ka-rGE/strings.xml
new file mode 100644
index 00000000..f930c021
--- /dev/null
+++ b/common/res/values-ka-rGE/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"მზადაა"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"გამოტოვება"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"სეზ. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ეპ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ეპ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"სეზ. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, ეპ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> — <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ეპ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> — <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;სეზ.<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ეპიზ. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ეპიზ. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-ka/strings.xml b/common/res/values-ka/strings.xml
deleted file mode 100644
index 3c7062ff..00000000
--- a/common/res/values-ka/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"მზადაა"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"სეზ. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ეპ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ეპ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"სეზ. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, ეპ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> — <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ეპ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> — <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: სეზ. <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, ეპ. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: სეზ. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-kk-rKZ/strings.xml b/common/res/values-kk-rKZ/strings.xml
new file mode 100644
index 00000000..2aca092b
--- /dev/null
+++ b/common/res/values-kk-rKZ/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Орындалды"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Өткізіп жіберу"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-маусым, <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-серия"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-серия"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-маусым: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-серия, \"<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>\""</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-серия, \"<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>\""</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, &lt;i&gt;<xliff:g id="SEASONNUMBER">%2$s</xliff:g>-маусым: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>-серия&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, &lt;i&gt;<xliff:g id="EPISODENUMBER">%2$s</xliff:g>-серия&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-kk/strings.xml b/common/res/values-kk/strings.xml
deleted file mode 100644
index 12de7d34..00000000
--- a/common/res/values-kk/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Орындалды"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-маусым, <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-серия"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-серия"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-маусым: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-серия, \"<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>\""</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-серия, \"<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>\""</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, <xliff:g id="SEASONNUMBER">%2$s</xliff:g>-маусым, <xliff:g id="EPISODENUMBER">%3$s</xliff:g>-серия"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, <xliff:g id="EPISODENUMBER">%2$s</xliff:g>-серия"</string>
-</resources>
diff --git a/common/res/values-km-rKH/strings.xml b/common/res/values-km-rKH/strings.xml
new file mode 100644
index 00000000..252bd37a
--- /dev/null
+++ b/common/res/values-km-rKH/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"រួចរាល់"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"រំលង"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"រដូវកាល<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>៖ ភាគ<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ភាគ៖ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"រដូវកាលទី <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>៖ វគ្គ <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"វគ្គ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;រដូវកាល​ទី <xliff:g id="SEASONNUMBER">%2$s</xliff:g>៖ ភាគ​ទី <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ភាគ​ទី <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-km/strings.xml b/common/res/values-km/strings.xml
deleted file mode 100644
index b8353897..00000000
--- a/common/res/values-km/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"រួចរាល់"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"រដូវកាល<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>៖ ភាគ<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ភាគ៖ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"រដូវកាលទី <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>៖ វគ្គ <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"វគ្គ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> រដូវ<xliff:g id="SEASONNUMBER">%2$s</xliff:g>៖ ភាគ <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ភាគ <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-kn-rIN/strings.xml b/common/res/values-kn-rIN/strings.xml
new file mode 100644
index 00000000..6cfb5cab
--- /dev/null
+++ b/common/res/values-kn-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"ಮುಗಿದಿದೆ"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"ಸ್ಕಿಪ್‌ ಮಾಡಿ"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"ಕಾಲ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>ಭಾಗ<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ಭಾಗ<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"ಸೀ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ಸಂ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ಸಂ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ಸೀ<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ಸಂ. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ಸಂ. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-kn/strings.xml b/common/res/values-kn/strings.xml
deleted file mode 100644
index 7cb096b7..00000000
--- a/common/res/values-kn/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"ಮುಗಿದಿದೆ"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"ಕಾಲ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>ಭಾಗ<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ಭಾಗ<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"ಸೀ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ಸಂ. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ಸಂ. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ಸೀ<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ಸಂ. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ಸಂ. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-ko/strings.xml b/common/res/values-ko/strings.xml
index 923831f3..fe8a5c28 100644
--- a/common/res/values-ko/strings.xml
+++ b/common/res/values-ko/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"완료"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"건너뛰기"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"시즌 <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: 에피소드 <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"에피소드 <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"시즌 <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: 에피소드 <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> \'<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>\'"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"에피소드 <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> \'<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>\'"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> 시즌 <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: 에피소드 <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> 에피소드 <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;시즌 <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, 에피소드 <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;에피소드 <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-ky-rKG/strings.xml b/common/res/values-ky-rKG/strings.xml
new file mode 100644
index 00000000..b5b804d3
--- /dev/null
+++ b/common/res/values-ky-rKG/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Бүттү"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Өткөрүп жиберүү"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-мезгил: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-серия"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-серия"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"С<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g> <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-серия"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_TITLE">%2$s</xliff:g> <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-серия"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;М<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: С. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;С. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-ky/strings.xml b/common/res/values-ky/strings.xml
deleted file mode 100644
index 8bdfadde..00000000
--- a/common/res/values-ky/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Бүттү"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-мезгил: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-серия"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-серия"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"С<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g> <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-серия"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_TITLE">%2$s</xliff:g> <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-серия"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>-эпизод"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> <xliff:g id="EPISODENUMBER">%2$s</xliff:g>-эпизод"</string>
-</resources>
diff --git a/common/res/values-lo-rLA/strings.xml b/common/res/values-lo-rLA/strings.xml
new file mode 100644
index 00000000..c7ac4e21
--- /dev/null
+++ b/common/res/values-lo-rLA/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"ສຳເລັດແລ້ວ"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"ຂ້າມ"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-lo/strings.xml b/common/res/values-lo/strings.xml
deleted file mode 100644
index a6dad515..00000000
--- a/common/res/values-lo/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"ສຳເລັດແລ້ວ"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-lt/strings.xml b/common/res/values-lt/strings.xml
index 6d6c0ee8..2a38d45a 100644
--- a/common/res/values-lt/strings.xml
+++ b/common/res/values-lt/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Atlikta"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Praleisti"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g> sezonas: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> serija"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> serija"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g> sezonas: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> serija „<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>“"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> serija „<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>“"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"Programos „<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ <xliff:g id="SEASONNUMBER">%2$s</xliff:g> sezonas: <xliff:g id="EPISODENUMBER">%3$s</xliff:g> serija"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"Programos „<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ <xliff:g id="EPISODENUMBER">%2$s</xliff:g> serija"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"Programos „<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ &lt;i&gt;<xliff:g id="SEASONNUMBER">%2$s</xliff:g> sezonas: <xliff:g id="EPISODENUMBER">%3$s</xliff:g> serija&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"Programos „<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ &lt;i&gt;<xliff:g id="EPISODENUMBER">%2$s</xliff:g> serija&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-lv/strings.xml b/common/res/values-lv/strings.xml
index f0366a48..473b69fc 100644
--- a/common/res/values-lv/strings.xml
+++ b/common/res/values-lv/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Gatavs"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Izlaist"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. sez., <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. sēr."</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. sēr."</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. sezona: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. sērija “<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>”"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. sērija “<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>”"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: <xliff:g id="SEASONNUMBER">%2$s</xliff:g>. sezona, <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. sērija"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. sērija"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: &lt;i&gt;<xliff:g id="SEASONNUMBER">%2$s</xliff:g>. sezona, <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. sērija&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>: &lt;i&gt;<xliff:g id="EPISODENUMBER">%2$s</xliff:g>. sērija&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-mk-rMK/strings.xml b/common/res/values-mk-rMK/strings.xml
new file mode 100644
index 00000000..80603a1a
--- /dev/null
+++ b/common/res/values-mk-rMK/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Готово"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Прескокни"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"Сез.<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Еп.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Еп.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"Сез. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Еп. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Еп. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Сез.<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Еп. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Еп. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-mk/strings.xml b/common/res/values-mk/strings.xml
deleted file mode 100644
index 73045d3d..00000000
--- a/common/res/values-mk/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Готово"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"Сез.<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Еп.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Еп.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"Сез. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Еп. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Еп. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Сез.<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Еп.. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Еп. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-ml-rIN/strings.xml b/common/res/values-ml-rIN/strings.xml
new file mode 100644
index 00000000..abe8deda
--- /dev/null
+++ b/common/res/values-ml-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"പൂർത്തിയായി"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"ഒഴിവാക്കുക"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"സീസൺ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: എപ്പി.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"എപ്പി.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"സീസൺ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: എപ്പിസോഡ് <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"എപ്പിസോഡ് <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: എപ്പി. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;എപ്പി. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-ml/strings.xml b/common/res/values-ml/strings.xml
deleted file mode 100644
index 07727684..00000000
--- a/common/res/values-ml/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"പൂർത്തിയായി"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"സീസൺ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: എപ്പി.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"എപ്പി.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"സീസൺ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: എപ്പിസോഡ് <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"എപ്പിസോഡ് <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> സീരിയൽ<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: എപ്പിസോഡ് <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> എപ്പിസോഡ് <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-mn-rMN/strings.xml b/common/res/values-mn-rMN/strings.xml
new file mode 100644
index 00000000..aec6c268
--- /dev/null
+++ b/common/res/values-mn-rMN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Дууссан"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Алгасах"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"Бүлэг<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Цуврал.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Анги.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"Бүлэг<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Анги. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Анги. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Анги <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Анги <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-mn/strings.xml b/common/res/values-mn/strings.xml
deleted file mode 100644
index ff1552e0..00000000
--- a/common/res/values-mn/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Дууссан"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"Бүлэг<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Цуврал.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Анги.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"Бүлэг<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Анги. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Анги. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Бүлэг<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Анги. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Анги. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-mr-rIN/strings.xml b/common/res/values-mr-rIN/strings.xml
new file mode 100644
index 00000000..1084c7f1
--- /dev/null
+++ b/common/res/values-mr-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"पूर्ण झाले"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"वगळा"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"हंगाम<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: भाग<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"भाग<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"हंगाम<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: भाग. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"भाग. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: भाग <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;भाग <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-mr/strings.xml b/common/res/values-mr/strings.xml
deleted file mode 100644
index adc669ae..00000000
--- a/common/res/values-mr/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"पूर्ण झाले"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"हंगाम<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: भाग<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"भाग<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"हंगाम<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: भाग. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"भाग. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> सत्र<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: भाग <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> भाग <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-ms-rMY/strings.xml b/common/res/values-ms-rMY/strings.xml
new file mode 100644
index 00000000..14343683
--- /dev/null
+++ b/common/res/values-ms-rMY/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Selesai"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Langkau"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"M<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"M<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;M<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-ms/strings.xml b/common/res/values-ms/strings.xml
deleted file mode 100644
index 06eb6173..00000000
--- a/common/res/values-ms/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Selesai"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"M<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"M<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-my-rMM/strings.xml b/common/res/values-my-rMM/strings.xml
new file mode 100644
index 00000000..0e9b43cd
--- /dev/null
+++ b/common/res/values-my-rMM/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"ပြီးပါပြီ"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"ကျော်ရန်"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"အတွဲ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>− အပိုင်း<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"အပိုင်း <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"အတွဲ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>− အပိုင်း <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"အပိုင်း <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;အတွဲ<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: အပိုင်း <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;အပိုင်း <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-my/strings.xml b/common/res/values-my/strings.xml
deleted file mode 100644
index 977c4315..00000000
--- a/common/res/values-my/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"ပြီးပါပြီ"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"အတွဲ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>− အပိုင်း<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"အပိုင်း <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"အတွဲ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>− အပိုင်း <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"အပိုင်း <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> အတွဲ<xliff:g id="SEASONNUMBER">%2$s</xliff:g>− အပိုင်း <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> အပိုင်း <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-nb/strings.xml b/common/res/values-nb/strings.xml
index 8344a76b..61d36076 100644
--- a/common/res/values-nb/strings.xml
+++ b/common/res/values-nb/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Ferdig"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Hopp over"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Sesong <xliff:g id="SEASON_NUMBER">%1$s</xliff:g> episode <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Episode <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Sesong <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: episode <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> – <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Episode <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> – <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Sesong <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Episode <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Episode <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Episode <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Episode <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-ne-rNP/strings.xml b/common/res/values-ne-rNP/strings.xml
new file mode 100644
index 00000000..064fc63b
--- /dev/null
+++ b/common/res/values-ne-rNP/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"सम्पन्न भयो"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"छाड्नुहोस्"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"सिजन <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: एपिसोड <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"एपिसोड <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"सिजन <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: एपिसोड <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"एपिसोड <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: एपिसोड <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;एपिसोड <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-ne/strings.xml b/common/res/values-ne/strings.xml
deleted file mode 100644
index 4f3d24c1..00000000
--- a/common/res/values-ne/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"सम्पन्न भयो"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"सिजन <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: एपिसोड <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"एपिसोड <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"सिजन <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: एपिसोड <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"एपिसोड <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> सिजन <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: एपिसोड <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> एपिसोड <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-nl/strings.xml b/common/res/values-nl/strings.xml
index 4e5a1011..3b601618 100644
--- a/common/res/values-nl/strings.xml
+++ b/common/res/values-nl/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Gereed"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Overslaan"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S <xliff:g id="SEASON_NUMBER">%1$s</xliff:g> afl. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Afl. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: afl. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Afl. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Afl. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Afl. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>, A<xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;A <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-pa-rIN/strings.xml b/common/res/values-pa-rIN/strings.xml
new file mode 100644
index 00000000..c32ca9b7
--- /dev/null
+++ b/common/res/values-pa-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"ਹੋ ਗਿਆ"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"ਛੱਡੋ"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"ਸੀਜ਼ਨ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ਐਪੀਸੋਡ<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ਐਪੀਸੋਡ<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"ਸੀਜ਼ਨ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ਐਪੀਸੋਡ <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ਐਪੀਸੋਡ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ਐਪੀਸੋਡ <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ਐਪੀਸੋਡ <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-pl/strings.xml b/common/res/values-pl/strings.xml
index 5161e3ba..baa6a78c 100644
--- a/common/res/values-pl/strings.xml
+++ b/common/res/values-pl/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Gotowe"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Pomiń"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Sez. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: odc. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Odc. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Sez. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, odc. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Odc. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – sez. <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, odc. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, odc. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;sez. <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: odc. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;odc. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-pt-rPT/strings.xml b/common/res/values-pt-rPT/strings.xml
index badaae27..9d22b24f 100644
--- a/common/res/values-pt-rPT/strings.xml
+++ b/common/res/values-pt-rPT/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Concluído"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Ignorar"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"T. <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"T<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> T<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;T<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-pt/strings.xml b/common/res/values-pt/strings.xml
index 0fc3e097..e5aed96d 100644
--- a/common/res/values-pt/strings.xml
+++ b/common/res/values-pt/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Concluído"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Pular"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"T<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"T<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> T<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;T <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-ro/strings.xml b/common/res/values-ro/strings.xml
index ae6fc497..370c71d8 100644
--- a/common/res/values-ro/strings.xml
+++ b/common/res/values-ro/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Terminat"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Omiteți"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Sezonul <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, episodul <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Episodul <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Sezonul <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, episodul <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Episodul <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>: <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, sezonul <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, episodul <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, episodul <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, &lt;i&gt;sezonul <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, episodul <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, &lt;i&gt;episodul <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-ru/strings.xml b/common/res/values-ru/strings.xml
index 53c341aa..afdbcd5a 100644
--- a/common/res/values-ru/strings.xml
+++ b/common/res/values-ru/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Готово"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Пропустить"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Сезон <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, серия <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Серия <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Сезон <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: серия <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>, \"<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>\""</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Серия <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>, \"<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>\""</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, сезон <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, серия <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, серия <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;сезон <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, серия <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;серия <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-si-rLK/strings.xml b/common/res/values-si-rLK/strings.xml
new file mode 100644
index 00000000..59d85a69
--- /dev/null
+++ b/common/res/values-si-rLK/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"නිමයි"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"මඟ හරින්න"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"වාරය<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>කථාංගය<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"කථාංගය <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"වාරය<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: කථාංගය <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"කථාංගය <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;වා<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: කථාංග. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;කථාංග. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-si/strings.xml b/common/res/values-si/strings.xml
deleted file mode 100644
index 85fc1f94..00000000
--- a/common/res/values-si/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"නිමයි"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"වාරය<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>කථාංගය<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"කථාංගය <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"වාරය<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: කථාංගය <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"කථාංගය <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> වාරය<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: කථාංගය. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> කථාංගය. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-sk/strings.xml b/common/res/values-sk/strings.xml
index 1d1a673f..4d6df3cb 100644
--- a/common/res/values-sk/strings.xml
+++ b/common/res/values-sk/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Hotovo"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Preskočiť"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"E<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> – <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> – <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> <xliff:g id="SEASONNUMBER">%2$s</xliff:g>. sezóna: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. epizóda"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. epizóda"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-sl/strings.xml b/common/res/values-sl/strings.xml
index 26ec614d..603d12de 100644
--- a/common/res/values-sl/strings.xml
+++ b/common/res/values-sl/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Končano"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Preskoči"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. sezona: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. epizoda"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. epizoda"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. sezona – <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. epizoda: <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. epizoda: <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – <xliff:g id="SEASONNUMBER">%2$s</xliff:g>. sezona: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. epizoda"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> – <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. epizoda"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;<xliff:g id="SEASONNUMBER">%2$s</xliff:g>. sezona: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>.epizoda&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;<xliff:g id="EPISODENUMBER">%2$s</xliff:g>.epizoda&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-sq-rAL/strings.xml b/common/res/values-sq-rAL/strings.xml
new file mode 100644
index 00000000..ac188984
--- /dev/null
+++ b/common/res/values-sq-rAL/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"U krye"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Kapërce"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-sr/strings.xml b/common/res/values-sr/strings.xml
index ef7f9ee5..b64eb7f7 100644
--- a/common/res/values-sr/strings.xml
+++ b/common/res/values-sr/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Готово"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Прескочи"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Серијал: <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Епизода: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. епизода"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. серијал: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. епизода, <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. епизода, <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> <xliff:g id="SEASONNUMBER">%2$s</xliff:g>. серијал: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. епизода"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. епизода"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;<xliff:g id="SEASONNUMBER">%2$s</xliff:g>. серијал: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. епизода&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt; <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. епозода&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-sv/strings.xml b/common/res/values-sv/strings.xml
index 9911a0de..14741001 100644
--- a/common/res/values-sv/strings.xml
+++ b/common/res/values-sv/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Klar"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Hoppa över"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Säsong <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>, avsnitt <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Avsnitt <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Säsong <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: avsnitt <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> – <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Avsnitt <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> – <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Säsong<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: avsnitt <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> avsnitt. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;säsong <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, avsnitt <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;avsnitt <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-sw/strings.xml b/common/res/values-sw/strings.xml
index 7d44cedf..0b6883f6 100644
--- a/common/res/values-sw/strings.xml
+++ b/common/res/values-sw/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Nimemaliza"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Ruka"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Msimu wa <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Kipindi cha <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Kipindi cha <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Msimu wa <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Kipindi cha <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Kipindi cha <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>Msimu wa <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Kipindi cha <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Kipindi cha <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Msimu wa <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Kipindi cha <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Kipindi cha <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-ta-rIN/strings.xml b/common/res/values-ta-rIN/strings.xml
new file mode 100644
index 00000000..7e3faa13
--- /dev/null
+++ b/common/res/values-ta-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"முடிந்தது"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"தவிர்"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"சீ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: எபி.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"எபி.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"சீ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: எபி. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"எபி. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;சீ<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: எபி. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;எபி. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-ta/strings.xml b/common/res/values-ta/strings.xml
deleted file mode 100644
index bc2eed62..00000000
--- a/common/res/values-ta/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"முடிந்தது"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"சீ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: எபி.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"எபி.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"சீ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: எபி. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"எபி. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> சீ<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: எபி. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> எபி. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-te-rIN/strings.xml b/common/res/values-te-rIN/strings.xml
new file mode 100644
index 00000000..066abcc5
--- /dev/null
+++ b/common/res/values-te-rIN/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"పూర్తయింది"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"దాటవేయి"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"సీ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ఎపి.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ఎపి.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"సీ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ఎపి. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ఎపి. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;సీ.<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ఎపి. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ఎపి. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-te/strings.xml b/common/res/values-te/strings.xml
deleted file mode 100644
index 80df229d..00000000
--- a/common/res/values-te/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"పూర్తయింది"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"సీ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ఎపి.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ఎపి.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"సీ<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ఎపి. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ఎపి. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> సీ<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ఎపి. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ఎపి. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-th/strings.xml b/common/res/values-th/strings.xml
index 5ff9f1ff..a9f94b70 100644
--- a/common/res/values-th/strings.xml
+++ b/common/res/values-th/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"เสร็จสิ้น"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"ข้าม"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"ซีซัน <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ตอนที่ <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ตอนที่ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"ซีซัน <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ตอนที่ <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ตอนที่ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ซีซัน <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ตอน <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ตอน <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ซีซัน <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ตอน <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;S"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ตอน <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-tl/strings.xml b/common/res/values-tl/strings.xml
index e6b8bbbc..24e13951 100644
--- a/common/res/values-tl/strings.xml
+++ b/common/res/values-tl/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Tapos Na"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Laktawan"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-tr/strings.xml b/common/res/values-tr/strings.xml
index c25c834f..56e375fc 100644
--- a/common/res/values-tr/strings.xml
+++ b/common/res/values-tr/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Bitti"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Atla"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Böl.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Böl.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>. Bölüm <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>. Bölüm <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> <xliff:g id="SEASONNUMBER">%2$s</xliff:g>.S: <xliff:g id="EPISODENUMBER">%3$s</xliff:g>. Böl."</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> <xliff:g id="EPISODENUMBER">%2$s</xliff:g>. Böl."</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Böl. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Böl. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-uk/strings.xml b/common/res/values-uk/strings.xml
index 9b67cf4a..10bfb267 100644
--- a/common/res/values-uk/strings.xml
+++ b/common/res/values-uk/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Готово"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Пропустити"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Сезон <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: серія <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Серія <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Сезон <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: серія <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> \"<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>\""</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Серія <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> \"<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>\""</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"\"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\": сезон <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, серія <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"\"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\": серія <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"\"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\": &lt;i&gt;сезон <xliff:g id="SEASONNUMBER">%2$s</xliff:g>, серія <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"\"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\": &lt;i&gt;серія <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-ur-rPK/strings.xml b/common/res/values-ur-rPK/strings.xml
new file mode 100644
index 00000000..9edebcf0
--- /dev/null
+++ b/common/res/values-ur-rPK/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"ہو گیا"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"نظر انداز کریں"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"سیزن<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ایپی سوڈ۔<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ایپی سوڈ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"سیزن <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ایپی سوڈ <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ایپی سوڈ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"‏<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;سیزن<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ایپی سوڈ <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"‏<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;ایپی سوڈ <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-ur/strings.xml b/common/res/values-ur/strings.xml
deleted file mode 100644
index b04fb3c3..00000000
--- a/common/res/values-ur/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"ہو گیا"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"سیزن<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ایپی سوڈ۔<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"ایپی سوڈ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"سیزن <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: ایپی سوڈ <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"ایپی سوڈ <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> سیزن <xliff:g id="SEASONNUMBER">%2$s</xliff:g>: ایپی سوڈ <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ایپی سوڈ <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
-</resources>
diff --git a/common/res/values-uz-rUZ/strings.xml b/common/res/values-uz-rUZ/strings.xml
new file mode 100644
index 00000000..1aef80d5
--- /dev/null
+++ b/common/res/values-uz-rUZ/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="action_text_done" msgid="298287050387266501">"Tayyor"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Tashlab ketish"</string>
+ <string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-fasl: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-qism"</string>
+ <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-qism"</string>
+ <string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-fasl: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-qism – “<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>”"</string>
+ <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-qism – “<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>”"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;<xliff:g id="SEASONNUMBER">%2$s</xliff:g>-fasl <xliff:g id="EPISODENUMBER">%3$s</xliff:g>-qism&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;<xliff:g id="EPISODENUMBER">%2$s</xliff:g>-qism&lt;/i&gt;"</string>
+</resources>
diff --git a/common/res/values-uz/strings.xml b/common/res/values-uz/strings.xml
deleted file mode 100644
index ffa1cf9c..00000000
--- a/common/res/values-uz/strings.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="action_text_done" msgid="298287050387266501">"Tayyor"</string>
- <string name="display_episode_number_format" msgid="6040735693510854344">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-fasl: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-qism"</string>
- <string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-qism"</string>
- <string name="display_episode_title_format" msgid="5041103178918130554">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-fasl: <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>-qism – “<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>”"</string>
- <string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>-qism – “<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>”"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, <xliff:g id="SEASONNUMBER">%2$s</xliff:g>-fasl <xliff:g id="EPISODENUMBER">%3$s</xliff:g>-qism"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>, <xliff:g id="EPISODENUMBER">%2$s</xliff:g>-qism"</string>
-</resources>
diff --git a/common/res/values-vi/strings.xml b/common/res/values-vi/strings.xml
index 2852bb10..b7f209b3 100644
--- a/common/res/values-vi/strings.xml
+++ b/common/res/values-vi/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Xong"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Bỏ qua"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"Phần<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Tập<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Tập<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"Phần <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Tập <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Tập <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> P<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Tập <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Tập <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Tập <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Tập <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-zh-rCN/strings.xml b/common/res/values-zh-rCN/strings.xml
index 25e13379..1eb99dbe 100644
--- a/common/res/values-zh-rCN/strings.xml
+++ b/common/res/values-zh-rCN/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"完成"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"跳过"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"第 <xliff:g id="SEASON_NUMBER">%1$s</xliff:g> 季:第 <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> 集"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"第 <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> 集"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"第 <xliff:g id="SEASON_NUMBER">%1$s</xliff:g> 季第 <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> 集:<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"第 <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> 集:<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》第 <xliff:g id="SEASONNUMBER">%2$s</xliff:g> 季:第 <xliff:g id="EPISODENUMBER">%3$s</xliff:g> 集"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》第 <xliff:g id="EPISODENUMBER">%2$s</xliff:g> 集"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》第 <xliff:g id="SEASONNUMBER">%2$s</xliff:g> 季:第 <xliff:g id="EPISODENUMBER">%3$s</xliff:g> 集&lt;i&gt;&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》第 <xliff:g id="EPISODENUMBER">%2$s</xliff:g> 集&lt;i&gt;&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-zh-rHK/strings.xml b/common/res/values-zh-rHK/strings.xml
index ed323c6a..346db42b 100644
--- a/common/res/values-zh-rHK/strings.xml
+++ b/common/res/values-zh-rHK/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"完成"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"略過"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"第 <xliff:g id="SEASON_NUMBER">%1$s</xliff:g> 季:第 <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> 集"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"第 <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> 集"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"第 <xliff:g id="SEASON_NUMBER">%1$s</xliff:g> 季:第 <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> 集 <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"第 <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> 集 <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》第 <xliff:g id="SEASONNUMBER">%2$s</xliff:g> 季:第 <xliff:g id="EPISODENUMBER">%3$s</xliff:g> 集"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》第 <xliff:g id="EPISODENUMBER">%2$s</xliff:g> 集"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》&lt;i&gt;第 <xliff:g id="SEASONNUMBER">%2$s</xliff:g> 季:第 <xliff:g id="EPISODENUMBER">%3$s</xliff:g> 集&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》&lt;i&gt;第 <xliff:g id="EPISODENUMBER">%2$s</xliff:g> 集&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-zh-rTW/strings.xml b/common/res/values-zh-rTW/strings.xml
index 25e13379..7cc3e3d3 100644
--- a/common/res/values-zh-rTW/strings.xml
+++ b/common/res/values-zh-rTW/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"完成"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"略過"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"第 <xliff:g id="SEASON_NUMBER">%1$s</xliff:g> 季:第 <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> 集"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"第 <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> 集"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"第 <xliff:g id="SEASON_NUMBER">%1$s</xliff:g> 季第 <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> 集:<xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"第 <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> 集:<xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》第 <xliff:g id="SEASONNUMBER">%2$s</xliff:g> 季:第 <xliff:g id="EPISODENUMBER">%3$s</xliff:g> 集"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》第 <xliff:g id="EPISODENUMBER">%2$s</xliff:g> 集"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》&lt;i&gt;第 <xliff:g id="SEASONNUMBER">%2$s</xliff:g> 季:第 <xliff:g id="EPISODENUMBER">%3$s</xliff:g> 集&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》&lt;i&gt;第 <xliff:g id="EPISODENUMBER">%2$s</xliff:g> 集&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values-zu/strings.xml b/common/res/values-zu/strings.xml
index 4574ac01..227a1919 100644
--- a/common/res/values-zu/strings.xml
+++ b/common/res/values-zu/strings.xml
@@ -18,10 +18,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done" msgid="298287050387266501">"Kwenziwe"</string>
+ <string name="action_text_skip" msgid="9158414021827546309">"Yeqa"</string>
<string name="display_episode_number_format" msgid="6040735693510854344">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep.<xliff:g id="EPISODE_NUMBER">%2$s</xliff:g>"</string>
<string name="display_episode_number_format_no_season_number" msgid="8393554269654325741">"Ep.<xliff:g id="EPISODE_NUMBER">%1$s</xliff:g>"</string>
<string name="display_episode_title_format" msgid="5041103178918130554">"S<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>: Ep. <xliff:g id="EPISODE_NUMBER">%2$s</xliff:g> <xliff:g id="EPISODE_TITLE">%3$s</xliff:g>"</string>
<string name="display_episode_title_format_no_season_number" msgid="4558449786705748989">"Ep. <xliff:g id="EPISODE_NUMBER">%1$s</xliff:g> <xliff:g id="EPISODE_TITLE">%2$s</xliff:g>"</string>
- <string name="program_title_with_episode_number" msgid="5708628769757639737">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>"</string>
- <string name="program_title_with_episode_number_no_season" msgid="8299170840696856426">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>"</string>
+ <string name="program_title_with_episode_number" msgid="2159336538427523610">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;S<xliff:g id="SEASONNUMBER">%2$s</xliff:g>: Ep. <xliff:g id="EPISODENUMBER">%3$s</xliff:g>&lt;/i&gt;"</string>
+ <string name="program_title_with_episode_number_no_season" msgid="6243727201916342169">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> &lt;i&gt;Ep. <xliff:g id="EPISODENUMBER">%2$s</xliff:g>&lt;/i&gt;"</string>
</resources>
diff --git a/common/res/values/dimens.xml b/common/res/values/dimens.xml
index 9d6e0e67..be534898 100644
--- a/common/res/values/dimens.xml
+++ b/common/res/values/dimens.xml
@@ -16,10 +16,6 @@
-->
<resources>
- <!-- Setup screen -->
- <dimen name="setup_fragment_enter_from">300dp</dimen>
- <dimen name="setup_fragment_enter_to">-300dp</dimen>
-
<!-- Guided step fragment -->
<dimen name="setup_guidedstep_guidance_section_width_2pane">600dp</dimen>
<dimen name="setup_guidedstep_guidance_section_width_3pane">476dp</dimen>
@@ -27,10 +23,7 @@
<dimen name="setup_guidedactions_selector_margin_start">24dp</dimen>
<dimen name="setup_guidedactions_selector_margin_end">24dp</dimen>
<dimen name="setup_guidedactions_selector_margin_top">220dp</dimen>
- <dimen name="setup_guidedactions_item_container_padding_start">40dp</dimen>
- <dimen name="setup_guidedactions_item_container_padding_end">40dp</dimen>
<dimen name="setup_guidedactions_vertical_padding">12dp</dimen>
- <dimen name="setup_guidedactions_vertical_spacing">5dp</dimen>
<item name="setup_guidedactions_width_weight" format="float" type="string">1</item>
<dimen name="setup_guidedactions_item_delimiter_padding">10dp</dimen>
diff --git a/common/res/values/strings.xml b/common/res/values/strings.xml
index e5b9b625..ec029136 100644
--- a/common/res/values/strings.xml
+++ b/common/res/values/strings.xml
@@ -17,16 +17,32 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_text_done">Done</string>
- <!-- The episode display format with season and episode number used in series details view. -->
+ <string name="action_text_skip">Skip</string>
+ <!-- The episode display format with season and episode number used in series details view.
+ "S" is an abbreviation for Season and "Ep." is an abbreviation for episode. ":" is used as a separator.
+ For example, "S1: Ep. 1"-->
<string name="display_episode_number_format">S<xliff:g id="season_number" example="1">%1$s</xliff:g>: Ep.<xliff:g id="episode_number" example="1">%2$s</xliff:g></string>
- <!-- The episode display format with episode number used in series details view. -->
+ <!-- The episode display format with episode number used in series details view.
+ "Ep." is an abbreviation for episode.
+ For example, "Ep. 1" -->
<string name="display_episode_number_format_no_season_number">Ep.<xliff:g id="episode_number" example="1">%1$s</xliff:g></string>
- <!-- The episode title format displayed on the info banner. For example, "S1: Ep. 1 Winter is coming". -->
+ <!-- The episode title format displayed on the info banner.
+ "S" is an abbreviation for Season and Ep. is an abbreviation for episode. ":" is used as a separator.
+ For example, "S1: Ep. 1 Winter is coming". -->
<string name="display_episode_title_format">S<xliff:g id="season_number" example="1">%1$s</xliff:g>: Ep. <xliff:g id="episode_number" example="1">%2$s</xliff:g> <xliff:g id="episode_title" example="Winter is Coming">%3$s</xliff:g></string>
- <!-- The episode title format displayed on the info banner when the season number is not available. For example, "Ep. 1807 Headline News". -->
+ <!-- The episode title format displayed on the info banner when the season number is not available.
+ "Ep." is an abbreviation for episode.
+ For example, "Ep. 1807 Headline News". -->
<string name="display_episode_title_format_no_season_number">Ep. <xliff:g id="episode_number" example="1807">%1$s</xliff:g> <xliff:g id="episode_title" example="Headline News">%2$s</xliff:g></string>
- <!-- Program title with season and episode number used in DVR card views. -->
- <string name="program_title_with_episode_number"><xliff:g id="programName" example="Big bang theory">%1$s</xliff:g> S<xliff:g id="seasonNumber" example="1">%2$s</xliff:g>: Ep. <xliff:g id="episodeNumber" example="12">%3$s</xliff:g></string>
- <!-- Program title with episode number used in DVR card views. -->
- <string name="program_title_with_episode_number_no_season"><xliff:g id="programName" example="Big bang theory">%1$s</xliff:g> Ep. <xliff:g id="episodeNumber" example="12">%2$s</xliff:g></string>
+ <!-- Program title with season and episode number used in DVR card views.
+ HTML tag <i> is a placeholder for styling episode number part.
+ "S" is an abbreviation for Season and "Ep." is an abbreviation for episode. ":" is used as a separator.
+ For example "Big bang theory <i>S1: Ep. 12</i>" -->
+ <string name="program_title_with_episode_number"><xliff:g id="programName" example="Big bang theory">%1$s</xliff:g> <![CDATA[<i>]]>S<xliff:g id="seasonNumber" example="1">%2$s</xliff:g>: Ep. <xliff:g id="episodeNumber" example="12">%3$s</xliff:g><![CDATA[</i>]]></string>
+ <!-- Program title with episode number used in DVR card views.
+ HTML tag <i> is a placeholder for styling episode number part.
+ "S" is an abbreviation for Season and "Ep." is an abbreviation for episode. ":" is used as a separator.
+ For example "Big bang theory <i>Ep. 12</i>"
+ -->
+ <string name="program_title_with_episode_number_no_season"><xliff:g id="programName" example="Big bang theory">%1$s</xliff:g> <![CDATA[<i>]]>Ep. <xliff:g id="episodeNumber" example="12">%2$s</xliff:g><![CDATA[</i>]]></string>
</resources>
diff --git a/common/res/values/styles.xml b/common/res/values/styles.xml
index 3c3c71c9..50ef08f1 100644
--- a/common/res/values/styles.xml
+++ b/common/res/values/styles.xml
@@ -57,15 +57,9 @@
<item name="android:textSize">16sp</item>
</style>
- <style name="Widget.Setup.GuidedActionsListStyle" parent="Widget.Leanback.GuidedActionsListStyle">
- <item name="android:elevation">0dp</item>
- </style>
-
<style name="Widget.Setup.GuidedActionItemContainerStyle" parent="Widget.Leanback.GuidedActionItemContainerStyle">
<item name="android:layout_height">64dp</item>
<item name="android:paddingBottom">@dimen/setup_guidedactions_vertical_padding</item>
- <item name="android:paddingEnd">@dimen/setup_guidedactions_item_container_padding_end</item>
- <item name="android:paddingStart">@dimen/setup_guidedactions_item_container_padding_start</item>
<item name="android:paddingTop">@dimen/setup_guidedactions_vertical_padding</item>
<item name="android:transitionGroup">true</item>
</style>
diff --git a/common/res/values/themes.xml b/common/res/values/themes.xml
index 598ae9a5..6016daf9 100644
--- a/common/res/values/themes.xml
+++ b/common/res/values/themes.xml
@@ -31,7 +31,6 @@
<item name="guidedActionItemDescriptionStyle">@style/Widget.Setup.GuidedActionItemDescriptionStyle</item>
<item name="guidedActionsBackground">@color/common_setup_action_background</item>
<item name="guidedActionsElevation">0dp</item>
- <item name="guidedActionsListStyle">@style/Widget.Setup.GuidedActionsListStyle</item>
<item name="guidedActionsSelectorDrawable">@drawable/setup_selector_background</item>
<item name="guidedStepBackground">@android:color/transparent</item>
<item name="setupCommonGuidanceBackground">@android:color/transparent</item>
diff --git a/common/src/com/android/tv/common/SharedPreferencesUtils.java b/common/src/com/android/tv/common/SharedPreferencesUtils.java
index fb3d9b56..140c4e6f 100644
--- a/common/src/com/android/tv/common/SharedPreferencesUtils.java
+++ b/common/src/com/android/tv/common/SharedPreferencesUtils.java
@@ -35,6 +35,11 @@ public final class SharedPreferencesUtils {
public static final String SHARED_PREF_RECURRING_RUNNER = "sharedPreferencesRecurringRunner";
public static final String SHARED_PREF_EPG = "epg_preferences";
public static final String SHARED_PREF_SERIES_RECORDINGS = "seriesRecordings";
+ /** No need to pre-initialize. It's used only on the worker thread. */
+ public static final String SHARED_PREF_CHANNEL_LOGO_URIS = "channelLogoUris";
+ /** Stores the UI related settings */
+ public static final String SHARED_PREF_UI_SETTINGS = "ui_settings";
+ public static final String SHARED_PREF_PREVIEW_PROGRAMS = "previewPrograms";
private static boolean sInitializeCalled;
@@ -63,6 +68,7 @@ public final class SharedPreferencesUtils {
context.getSharedPreferences(SHARED_PREF_EPG, Context.MODE_PRIVATE);
context.getSharedPreferences(SHARED_PREF_SERIES_RECORDINGS,
Context.MODE_PRIVATE);
+ context.getSharedPreferences(SHARED_PREF_UI_SETTINGS, Context.MODE_PRIVATE);
return null;
}
diff --git a/common/src/com/android/tv/common/TvCommonUtils.java b/common/src/com/android/tv/common/TvCommonUtils.java
index a88dd3a8..c391ad24 100644
--- a/common/src/com/android/tv/common/TvCommonUtils.java
+++ b/common/src/com/android/tv/common/TvCommonUtils.java
@@ -23,6 +23,8 @@ import android.media.tv.TvInputInfo;
* Util class for common use in TV app and inputs.
*/
public final class TvCommonUtils {
+ private static Boolean sRunningInTest;
+
private TvCommonUtils() { }
/**
@@ -58,12 +60,15 @@ public final class TvCommonUtils {
* the usual devices even the application is running in tests. We need to figure it out by
* checking whether the class in tv-tests-common module can be loaded or not.
*/
- public static boolean isRunningInTest() {
- try {
- Class.forName("com.android.tv.testing.Utils");
- return true;
- } catch (ClassNotFoundException e) {
- return false;
+ public static synchronized boolean isRunningInTest() {
+ if (sRunningInTest == null) {
+ try {
+ Class.forName("com.android.tv.testing.Utils");
+ sRunningInTest = true;
+ } catch (ClassNotFoundException e) {
+ sRunningInTest = false;
+ }
}
+ return sRunningInTest;
}
}
diff --git a/common/src/com/android/tv/common/TvContentRatingCache.java b/common/src/com/android/tv/common/TvContentRatingCache.java
index 5694cda7..8b3c06f1 100644
--- a/common/src/com/android/tv/common/TvContentRatingCache.java
+++ b/common/src/com/android/tv/common/TvContentRatingCache.java
@@ -43,6 +43,7 @@ public final class TvContentRatingCache implements MemoryManageable {
return INSTANCE;
}
+ // @GuardedBy("TvContentRatingCache.this")
private final Map<String, TvContentRating[]> mRatingsMultiMap = new ArrayMap<>();
/**
@@ -51,7 +52,7 @@ public final class TvContentRatingCache implements MemoryManageable {
* Returns {@code null} if the string is empty or contains no valid ratings.
*/
@Nullable
- public TvContentRating[] getRatings(String commaSeparatedRatings) {
+ public synchronized TvContentRating[] getRatings(String commaSeparatedRatings) {
if (TextUtils.isEmpty(commaSeparatedRatings)) {
return null;
}
@@ -136,7 +137,7 @@ public final class TvContentRatingCache implements MemoryManageable {
}
@Override
- public void performTrimMemory(int level) {
+ public synchronized void performTrimMemory(int level) {
mRatingsMultiMap.clear();
}
diff --git a/common/src/com/android/tv/common/feature/CommonFeatures.java b/common/src/com/android/tv/common/feature/CommonFeatures.java
index d47aa603..62c88ead 100644
--- a/common/src/com/android/tv/common/feature/CommonFeatures.java
+++ b/common/src/com/android/tv/common/feature/CommonFeatures.java
@@ -17,7 +17,6 @@
package com.android.tv.common.feature;
import static com.android.tv.common.feature.FeatureUtils.AND;
-import static com.android.tv.common.feature.FeatureUtils.OR;
import static com.android.tv.common.feature.TestableFeature.createTestableFeature;
/**
@@ -34,7 +33,7 @@ public class CommonFeatures {
* DVR API is introduced in N, it only works when app runs as a system app.
*/
public static final TestableFeature DVR = createTestableFeature(
- AND(OR(Sdk.N_PRE_2_OR_HIGHER, Sdk.AT_LEAST_N), SystemAppFeature.SYSTEM_APP_FEATURE));
+ AND(Sdk.AT_LEAST_N, SystemAppFeature.SYSTEM_APP_FEATURE));
/**
* ENABLE_RECORDING_REGARDLESS_OF_STORAGE_STATUS
diff --git a/common/src/com/android/tv/common/feature/Sdk.java b/common/src/com/android/tv/common/feature/Sdk.java
index 46a681f8..9f99a64f 100644
--- a/common/src/com/android/tv/common/feature/Sdk.java
+++ b/common/src/com/android/tv/common/feature/Sdk.java
@@ -18,50 +18,18 @@ package com.android.tv.common.feature;
import android.content.Context;
import android.os.Build;
-import android.support.v4.os.BuildCompat;
/**
* Holder for SDK version features
*/
public class Sdk {
-
- public static final Feature N_PRE_2_OR_HIGHER =
- new SdkPreviewVersionFeature(Build.VERSION_CODES.M, 2, true);
-
- private static class SdkPreviewVersionFeature implements Feature {
- private final int mVersionCode;
- private final int mPreviewCode;
- private final boolean mAllowHigherPreview;
-
- private SdkPreviewVersionFeature(int versionCode, int previewCode,
- boolean allowHigerPreview) {
- mVersionCode = versionCode;
- mPreviewCode = previewCode;
- mAllowHigherPreview = allowHigerPreview;
- }
-
- @Override
- public boolean isEnabled(Context context) {
- try {
- if (mAllowHigherPreview) {
- return Build.VERSION.SDK_INT == mVersionCode
- && Build.VERSION.PREVIEW_SDK_INT >= mPreviewCode;
- } else {
- return Build.VERSION.SDK_INT == mVersionCode
- && Build.VERSION.PREVIEW_SDK_INT == mPreviewCode;
+ public static final Feature AT_LEAST_N =
+ new Feature() {
+ @Override
+ public boolean isEnabled(Context context) {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
}
- } catch (NoSuchFieldError e) {
- return false;
- }
- }
- }
-
- public static final Feature AT_LEAST_N = new Feature() {
- @Override
- public boolean isEnabled(Context context) {
- return BuildCompat.isAtLeastN();
- }
- };
+ };
private Sdk() {}
}
diff --git a/common/src/com/android/tv/common/feature/SharedPreferencesFeature.java b/common/src/com/android/tv/common/feature/SharedPreferencesFeature.java
index a4a79b38..881f53d6 100644
--- a/common/src/com/android/tv/common/feature/SharedPreferencesFeature.java
+++ b/common/src/com/android/tv/common/feature/SharedPreferencesFeature.java
@@ -19,7 +19,6 @@ package com.android.tv.common.feature;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
-
import com.android.tv.common.SharedPreferencesUtils;
/**
diff --git a/common/src/com/android/tv/common/feature/TestableFeature.java b/common/src/com/android/tv/common/feature/TestableFeature.java
index a02877ec..d7e707a1 100644
--- a/common/src/com/android/tv/common/feature/TestableFeature.java
+++ b/common/src/com/android/tv/common/feature/TestableFeature.java
@@ -36,14 +36,29 @@ public class TestableFeature implements Feature {
private final Feature mDelegate;
private Boolean mTestValue = null;
+ /**
+ * Creates testable feature.
+ */
public static TestableFeature createTestableFeature(Feature delegate) {
return new TestableFeature(delegate);
}
+ /**
+ * Creates testable feature with initial value.
+ */
+ public static TestableFeature createTestableFeature(Feature delegate, Boolean initialValue) {
+ return new TestableFeature(delegate, initialValue);
+ }
+
private TestableFeature(Feature delegate) {
mDelegate = delegate;
}
+ private TestableFeature(Feature delegate, Boolean initialValue) {
+ mDelegate = delegate;
+ mTestValue = initialValue;
+ }
+
@VisibleForTesting
public void enableForTest() {
if (!TvCommonUtils.isRunningInTest()) {
diff --git a/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java b/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java
index bcaefec9..88159da9 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupGuidedStepFragment.java
@@ -72,9 +72,6 @@ public abstract class SetupGuidedStepFragment extends GuidedStepFragment {
}
// gridView Alignment
VerticalGridView gridView = getGuidedActionsStylist().getActionsGridView();
- // Workaround of b/28274171
- // TODO: Remove the following line once b/28274171 is resolved.
- gridView.setFocusable(true);
int offset = getResources().getDimensionPixelOffset(
R.dimen.setup_guidedactions_selector_margin_top);
gridView.setWindowAlignmentOffset(offset);
@@ -86,8 +83,6 @@ public abstract class SetupGuidedStepFragment extends GuidedStepFragment {
ViewGroup group = (ViewGroup) view.findViewById(R.id.content_frame);
group.setClipChildren(false);
group.setClipToPadding(false);
- // Workaround b/26205201
- view.findViewById(R.id.guidedactions_list2).setFocusable(false);
return view;
}
diff --git a/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java b/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
index 63247481..b9ad4657 100644
--- a/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
+++ b/common/src/com/android/tv/common/ui/setup/SetupMultiPaneFragment.java
@@ -34,6 +34,7 @@ public abstract class SetupMultiPaneFragment extends SetupFragment {
private static final boolean DEBUG = false;
public static final int ACTION_DONE = Integer.MAX_VALUE;
+ public static final int ACTION_SKIP = ACTION_DONE - 1;
private static final String CONTENT_FRAGMENT_TAG = "content_fragment";
@@ -53,7 +54,12 @@ public abstract class SetupMultiPaneFragment extends SetupFragment {
}
if (needsDoneButton()) {
setOnClickAction(view.findViewById(R.id.button_done), getActionCategory(), ACTION_DONE);
- } else {
+ }
+ if (needsSkipButton()) {
+ view.findViewById(R.id.button_skip).setVisibility(View.VISIBLE);
+ setOnClickAction(view.findViewById(R.id.button_skip), getActionCategory(), ACTION_SKIP);
+ }
+ if (!needsDoneButton() && !needsSkipButton()) {
View doneButtonContainer = view.findViewById(R.id.done_button_container);
// Use content view to check layout direction while view is being created.
if (getResources().getConfiguration().getLayoutDirection()
@@ -90,6 +96,10 @@ public abstract class SetupMultiPaneFragment extends SetupFragment {
return true;
}
+ protected boolean needsSkipButton() {
+ return false;
+ }
+
@Override
protected int[] getParentIdsForDelay() {
return new int[] {R.id.content_fragment, R.id.guidedactions_list};
@@ -99,4 +109,4 @@ public abstract class SetupMultiPaneFragment extends SetupFragment {
public int[] getSharedElementIds() {
return new int[] {R.id.action_fragment_background, R.id.done_button_container};
}
-}
+} \ No newline at end of file
diff --git a/icu/icu4j/main/classes/core/src/com/ibm/icu/text/SCSU.java b/icu/icu4j/main/classes/core/src/com/ibm/icu/text/SCSU.java
index b12b9260..39196fe3 100644
--- a/icu/icu4j/main/classes/core/src/com/ibm/icu/text/SCSU.java
+++ b/icu/icu4j/main/classes/core/src/com/ibm/icu/text/SCSU.java
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
/*
*******************************************************************************
* Copyright (C) 1996-2007, International Business Machines Corporation and *
diff --git a/icu/icu4j/main/classes/core/src/com/ibm/icu/text/UnicodeDecompressor.java b/icu/icu4j/main/classes/core/src/com/ibm/icu/text/UnicodeDecompressor.java
index e799ea14..6789469f 100644
--- a/icu/icu4j/main/classes/core/src/com/ibm/icu/text/UnicodeDecompressor.java
+++ b/icu/icu4j/main/classes/core/src/com/ibm/icu/text/UnicodeDecompressor.java
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
/*
*******************************************************************************
* Copyright (C) 1996-2016, International Business Machines Corporation and *
diff --git a/jni/Android.mk b/jni/Android.mk
index 684830c9..39923a15 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -1,12 +1,29 @@
+#
+# Copyright (C) 2017 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.
+#
+
LOCAL_PATH := $(call my-dir)
# --------------------------------------------------------------
include $(CLEAR_VARS)
-LOCAL_MODULE := libtunertvinput_jni
+LOCAL_MODULE := libtunertvinput_jni
LOCAL_SRC_FILES += tunertvinput_jni.cpp DvbManager.cpp
-LOCAL_SDK_VERSION := 21
+LOCAL_SDK_VERSION := 23
LOCAL_NDK_STL_VARIANT := stlport_static
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/jni/DvbManager.cpp b/jni/DvbManager.cpp
index aa4ed530..941a1fa7 100644
--- a/jni/DvbManager.cpp
+++ b/jni/DvbManager.cpp
@@ -42,6 +42,8 @@ DvbManager::DvbManager(JNIEnv *env, jobject)
mDemuxFd(-1),
mDvrFd(-1),
mPatFilterFd(-1),
+ mDvbApiVersion(DVB_API_VERSION_UNDEFINED),
+ mDeliverySystemType(-1),
mFeHasLock(false),
mHasPendingTune(false) {
jclass clazz = env->FindClass(
@@ -59,16 +61,26 @@ DvbManager::~DvbManager() {
}
bool DvbManager::isFeLocked() {
- struct pollfd pollFd;
- pollFd.fd = mFeFd;
- pollFd.events = POLLIN;
- pollFd.revents = 0;
- int poll_result = poll(&pollFd, NUM_POLLFDS, FE_POLL_TIMEOUT_MS);
- if (poll_result > 0 && (pollFd.revents & POLLIN)) {
- struct dvb_frontend_event kevent;
- memset(&kevent, 0, sizeof(kevent));
- if (ioctl(mFeFd, FE_GET_EVENT, &kevent) == 0) {
- return (kevent.status & FE_HAS_LOCK);
+ if (mDvbApiVersion == DVB_API_VERSION5) {
+ fe_status_t status;
+ if (ioctl(mFeFd, FE_READ_STATUS, &status) < 0) {
+ return false;
+ }
+ if (status & FE_HAS_LOCK) {
+ return true;
+ }
+ } else {
+ struct pollfd pollFd;
+ pollFd.fd = mFeFd;
+ pollFd.events = POLLIN;
+ pollFd.revents = 0;
+ int poll_result = poll(&pollFd, NUM_POLLFDS, FE_POLL_TIMEOUT_MS);
+ if (poll_result > 0 && (pollFd.revents & POLLIN)) {
+ struct dvb_frontend_event kevent;
+ memset(&kevent, 0, sizeof(kevent));
+ if (ioctl(mFeFd, FE_GET_EVENT, &kevent) == 0) {
+ return (kevent.status & FE_HAS_LOCK);
+ }
}
}
return false;
@@ -78,38 +90,111 @@ int DvbManager::tune(JNIEnv *env, jobject thiz,
const int frequency, const char *modulationStr, int timeout_ms) {
resetExceptFe();
- struct dvb_frontend_parameters feParams;
- memset(&feParams, 0, sizeof(struct dvb_frontend_parameters));
- feParams.frequency = frequency;
- if (strcmp(modulationStr, "8VSB") == 0) {
- feParams.u.vsb.modulation = VSB_8;
- } else if (strcmp(modulationStr, "QAM256") == 0) {
- feParams.u.vsb.modulation = QAM_256;
- } else {
- ALOGE("Unrecognized modulation mode : %s", modulationStr);
- return -1;
- }
-
- if (mHasPendingTune) {
- return -1;
- }
if (openDvbFe(env, thiz) != 0) {
return -1;
}
-
- feParams.inversion = INVERSION_AUTO;
- /* Check frontend capability */
- struct dvb_frontend_info feInfo;
- if (ioctl(mFeFd, FE_GET_INFO, &feInfo) != -1) {
- if (!(feInfo.caps & FE_CAN_INVERSION_AUTO)) {
- // FE can't do INVERSION_AUTO, trying INVERSION_OFF instead
- feParams.inversion = INVERSION_OFF;
+ if (mDvbApiVersion == DVB_API_VERSION_UNDEFINED) {
+ struct dtv_property testProps[1] = {
+ { .cmd = DTV_DELIVERY_SYSTEM }
+ };
+ struct dtv_properties feProp = {
+ .num = 1, .props = testProps
+ };
+ // On fugu, DVB_API_VERSION is 5 but it doesn't support FE_SET_PROPERTY. Checking the device
+ // support FE_GET_PROPERTY or not to determine the DVB API version is greater than 5 or not.
+ if (ioctl(mFeFd, FE_GET_PROPERTY, &feProp) == -1) {
+ ALOGD("FE_GET_PROPERTY failed, %s", strerror(errno));
+ mDvbApiVersion = DVB_API_VERSION3;
+ } else {
+ mDvbApiVersion = DVB_API_VERSION5;
}
}
- if (ioctl(mFeFd, FE_SET_FRONTEND, &feParams) != 0) {
- ALOGD("Can't set Frontend : %s", strerror(errno));
- return -1;
+ if (mDvbApiVersion == DVB_API_VERSION5) {
+ struct dtv_property deliverySystemProperty = {
+ .cmd = DTV_DELIVERY_SYSTEM, .u.data = SYS_ATSC
+ };
+ struct dtv_property frequencyProperty = {
+ .cmd = DTV_FREQUENCY, .u.data = frequency
+ };
+ struct dtv_property modulationProperty = { .cmd = DTV_MODULATION };
+ if (strncmp(modulationStr, "QAM", 3) == 0) {
+ modulationProperty.u.data = QAM_AUTO;
+ } else if (strcmp(modulationStr, "8VSB") == 0) {
+ modulationProperty.u.data = VSB_8;
+ } else {
+ ALOGE("Unrecognized modulation mode : %s", modulationStr);
+ return -1;
+ }
+ struct dtv_property tuneProperty = { .cmd = DTV_TUNE };
+
+ struct dtv_property props[] = {
+ deliverySystemProperty, frequencyProperty, modulationProperty, tuneProperty
+ };
+ struct dtv_properties dtvProperty = {
+ .num = 4, .props = props
+ };
+
+ if (mHasPendingTune) {
+ return -1;
+ }
+ if (ioctl(mFeFd, FE_SET_PROPERTY, &dtvProperty) != 0) {
+ ALOGD("Can't set Frontend : %s", strerror(errno));
+ return -1;
+ }
+ } else {
+ struct dvb_frontend_parameters feParams;
+ memset(&feParams, 0, sizeof(struct dvb_frontend_parameters));
+ feParams.frequency = frequency;
+ feParams.inversion = INVERSION_AUTO;
+ /* Check frontend capability */
+ struct dvb_frontend_info feInfo;
+ if (ioctl(mFeFd, FE_GET_INFO, &feInfo) != -1) {
+ if (!(feInfo.caps & FE_CAN_INVERSION_AUTO)) {
+ // FE can't do INVERSION_AUTO, trying INVERSION_OFF instead
+ feParams.inversion = INVERSION_OFF;
+ }
+ }
+ switch (feInfo.type) {
+ case FE_ATSC:
+ if (strcmp(modulationStr, "8VSB") == 0) {
+ feParams.u.vsb.modulation = VSB_8;
+ } else if (strncmp(modulationStr, "QAM", 3) == 0) {
+ feParams.u.vsb.modulation = QAM_AUTO;
+ } else {
+ ALOGE("Unrecognized modulation mode : %s", modulationStr);
+ return -1;
+ }
+ break;
+ case FE_OFDM:
+ if (strcmp(modulationStr, "8VSB") == 0) {
+ feParams.u.ofdm.constellation = VSB_8;
+ } else if (strcmp(modulationStr, "QAM16") == 0) {
+ feParams.u.ofdm.constellation = QAM_16;
+ } else if (strcmp(modulationStr, "QAM64") == 0) {
+ feParams.u.ofdm.constellation = QAM_64;
+ } else if (strcmp(modulationStr, "QAM256") == 0) {
+ feParams.u.ofdm.constellation = QAM_256;
+ } else if (strcmp(modulationStr, "QPSK") == 0) {
+ feParams.u.ofdm.constellation = QPSK;
+ } else {
+ ALOGE("Unrecognized modulation mode : %s", modulationStr);
+ return -1;
+ }
+ break;
+ default:
+ ALOGE("Unsupported delivery system.");
+ return -1;
+ }
+
+ if (mHasPendingTune) {
+ return -1;
+ }
+
+ if (ioctl(mFeFd, FE_SET_FRONTEND, &feParams) != 0) {
+ ALOGD("Can't set Frontend : %s", strerror(errno));
+ return -1;
+ }
}
int lockSuccessCount = 0;
@@ -238,6 +323,10 @@ int DvbManager::startTsPidFilter(JNIEnv *env, jobject thiz, int pid, int filterT
return -1;
}
+ if (mDvbApiVersion == DVB_API_VERSION5) {
+ ioctl(demuxFd, DMX_START, 0);
+ }
+
if (pid != PAT_PID) {
mPidFilters.insert(std::pair<int, int>(pid, demuxFd));
} else {
@@ -337,3 +426,75 @@ int DvbManager::readTsStream(JNIEnv *env, jobject thiz,
void DvbManager::setHasPendingTune(bool hasPendingTune) {
mHasPendingTune = hasPendingTune;
}
+
+int DvbManager::getDeliverySystemType(JNIEnv *env, jobject thiz) {
+ if (mDeliverySystemType != -1) {
+ return mDeliverySystemType;
+ }
+ if (mFeFd == -1) {
+ if ((mFeFd = openDvbFeFromSystemApi(env, thiz)) < 0) {
+ ALOGD("Can't open FE file : %s", strerror(errno));
+ return DELIVERY_SYSTEM_UNDEFINED;
+ }
+ }
+ struct dtv_property testProps[1] = {
+ { .cmd = DTV_DELIVERY_SYSTEM }
+ };
+ struct dtv_properties feProp = {
+ .num = 1, .props = testProps
+ };
+ mDeliverySystemType = DELIVERY_SYSTEM_UNDEFINED;
+ if (ioctl(mFeFd, FE_GET_PROPERTY, &feProp) == -1) {
+ mDvbApiVersion = DVB_API_VERSION3;
+ if (openDvbFe(env, thiz) == 0) {
+ struct dvb_frontend_info info;
+ if (ioctl(mFeFd, FE_GET_INFO, &info) == 0) {
+ switch (info.type) {
+ case FE_QPSK:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBS;
+ break;
+ case FE_QAM:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBC;
+ break;
+ case FE_OFDM:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBT;
+ break;
+ case FE_ATSC:
+ mDeliverySystemType = DELIVERY_SYSTEM_ATSC;
+ break;
+ default:
+ mDeliverySystemType = DELIVERY_SYSTEM_UNDEFINED;
+ break;
+ }
+ }
+ }
+ } else {
+ mDvbApiVersion = DVB_API_VERSION5;
+ switch (feProp.props[0].u.data) {
+ case SYS_DVBT:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBT;
+ break;
+ case SYS_DVBT2:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBT2;
+ break;
+ case SYS_DVBS:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBS;
+ break;
+ case SYS_DVBS2:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBS2;
+ break;
+ case SYS_DVBC_ANNEX_A:
+ case SYS_DVBC_ANNEX_B:
+ case SYS_DVBC_ANNEX_C:
+ mDeliverySystemType = DELIVERY_SYSTEM_DVBC;
+ break;
+ case SYS_ATSC:
+ mDeliverySystemType = DELIVERY_SYSTEM_ATSC;
+ break;
+ default:
+ mDeliverySystemType = DELIVERY_SYSTEM_UNDEFINED;
+ break;
+ }
+ }
+ return mDeliverySystemType;
+} \ No newline at end of file
diff --git a/jni/DvbManager.h b/jni/DvbManager.h
index 7475bd41..2252332c 100644
--- a/jni/DvbManager.h
+++ b/jni/DvbManager.h
@@ -31,6 +31,9 @@ class DvbManager {
static const int DVB_TUNE_STOP_DELAY_MS = 100 * 1000;
static const int FE_POLL_TIMEOUT_MS = 100;
static const int PAT_PID = 0;
+ static const int DVB_API_VERSION_UNDEFINED = -1;
+ static const int DVB_API_VERSION3 = 3;
+ static const int DVB_API_VERSION5 = 5;
static const int FILTER_TYPE_OTHER =
com_android_tv_tuner_TunerHal_FILTER_TYPE_OTHER;
@@ -41,10 +44,28 @@ class DvbManager {
static const int FILTER_TYPE_PCR =
com_android_tv_tuner_TunerHal_FILTER_TYPE_PCR;
+ static const int DELIVERY_SYSTEM_UNDEFINED =
+ com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_UNDEFINED;
+ static const int DELIVERY_SYSTEM_ATSC =
+ com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_ATSC;
+ static const int DELIVERY_SYSTEM_DVBC =
+ com_android_tv_tuner_TunerHal_DDELIVERY_SYSTEM_DVBC;
+ static const int DELIVERY_SYSTEM_DVBS =
+ com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBS;
+ static const int DELIVERY_SYSTEM_DVBS2 =
+ com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBS2;
+ static const int DELIVERY_SYSTEM_DVBT =
+ com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBT;
+ static const int DELIVERY_SYSTEM_DVBT2 =
+ com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBT2;
+
+
int mFeFd;
int mDemuxFd;
int mDvrFd;
int mPatFilterFd;
+ int mDvbApiVersion;
+ int mDeliverySystemType;
bool mFeHasLock;
// Flag for pending tune request. Used for canceling the current tune operation.
bool volatile mHasPendingTune;
@@ -65,6 +86,7 @@ public:
int startTsPidFilter(JNIEnv *env, jobject thiz, int pid, int filterType);
void closeAllDvbPidFilter();
void setHasPendingTune(bool hasPendingTune);
+ int getDeliverySystemType(JNIEnv *env, jobject thiz);
private:
int openDvbFe(JNIEnv *env, jobject thiz);
diff --git a/jni/minijail/Android.mk b/jni/minijail/Android.mk
new file mode 100644
index 00000000..940237db
--- /dev/null
+++ b/jni/minijail/Android.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2017 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# --------------------------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libminijail_jni
+LOCAL_SRC_FILES := minijail.cpp
+LOCAL_CXX_STL := none
+LOCAL_STATIC_LIBRARIES := libc++_static libminijail
+LOCAL_LDLIBS := -llog
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/jni/minijail/minijail.cpp b/jni/minijail/minijail.cpp
new file mode 100644
index 00000000..9eebc49b
--- /dev/null
+++ b/jni/minijail/minijail.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "minijail.h"
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <libminijail.h>
+#include <scoped_minijail.h>
+#include <android/log.h>
+
+#ifndef LOG_TAG
+#define LOG_TAG "minijail"
+#endif
+
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR , LOG_TAG, __VA_ARGS__)
+
+
+/*
+ * Class: com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService
+ * Method: nativeSetupMinijail
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_nativeSetupMinijail
+(JNIEnv *, jobject, jint policyFd) {
+ ScopedMinijail jail{minijail_new()};
+ if (!jail) {
+ ALOGE("Failed to create minijail");
+ }
+
+ minijail_no_new_privs(jail.get());
+ minijail_log_seccomp_filter_failures(jail.get());
+ minijail_use_seccomp_filter(jail.get());
+ minijail_set_seccomp_filter_tsync(jail.get());
+ // Transfer ownership of |policy_fd|.
+ minijail_parse_seccomp_filters_from_fd(jail.get(), policyFd);
+ minijail_enter(jail.get());
+ close(policyFd);
+}
+
+/*
+ * Class: com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService
+ * Method: nativeTestMinijail
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_nativeTestMinijail
+(JNIEnv *, jobject) {
+ kill(getpid(), SIGUSR1);
+} \ No newline at end of file
diff --git a/jni/minijail/minijail.h b/jni/minijail/minijail.h
new file mode 100644
index 00000000..cdf272c7
--- /dev/null
+++ b/jni/minijail/minijail.h
@@ -0,0 +1,44 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService */
+
+#ifndef _Included_com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService
+#define _Included_com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_DEBUG
+#define com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_DEBUG 0L
+#undef com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_MINIJAIL_SETUP_WAIT_TIMEOUT_MS
+#define com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_MINIJAIL_SETUP_WAIT_TIMEOUT_MS 5000LL
+/*
+ * Class: com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService
+ * Method: nativeSetupMinijail
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_nativeSetupMinijail
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService
+ * Method: nativeTestMinijail
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_nativeTestMinijail
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_FfmpegDecoder */
+
+#ifndef _Included_com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_FfmpegDecoder
+#define _Included_com_android_tv_tuner_exoplayer_ffmpeg_FfmpegDecoderService_FfmpegDecoder
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif \ No newline at end of file
diff --git a/jni/tunertvinput_jni.cpp b/jni/tunertvinput_jni.cpp
index bcbc4c29..5b1a1615 100644
--- a/jni/tunertvinput_jni.cpp
+++ b/jni/tunertvinput_jni.cpp
@@ -155,3 +155,21 @@ Java_com_android_tv_tuner_TunerHal_nativeSetHasPendingTune
it->second->setHasPendingTune(hasPendingTune);
}
}
+
+/*
+ * Class: com_android_tv_tuner_TunerHal
+ * Method: nativeGetDeliverySystemType
+ * Signature: (J)I
+ */
+JNIEXPORT int JNICALL
+Java_com_android_tv_tuner_TunerHal_nativeGetDeliverySystemType
+(JNIEnv *env, jobject thiz, jlong deviceId) {
+ std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
+ if (it != sDvbManagers.end()) {
+ return it->second->getDeliverySystemType(env, thiz);
+ } else {
+ DvbManager *dvbManager = new DvbManager(env, thiz);
+ sDvbManagers.insert(std::pair<jlong, DvbManager *>(deviceId, dvbManager));
+ return dvbManager->getDeliverySystemType(env, thiz);
+ }
+} \ No newline at end of file
diff --git a/jni/tunertvinput_jni.h b/jni/tunertvinput_jni.h
index 4ade29e4..fcd64d50 100644
--- a/jni/tunertvinput_jni.h
+++ b/jni/tunertvinput_jni.h
@@ -25,6 +25,20 @@ extern "C" {
#define com_android_tv_tuner_TunerHal_DEFAULT_VSB_TUNE_TIMEOUT_MS 2000L
#undef com_android_tv_tuner_TunerHal_DEFAULT_QAM_TUNE_TIMEOUT_MS
#define com_android_tv_tuner_TunerHal_DEFAULT_QAM_TUNE_TIMEOUT_MS 4000L
+#undef com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_UNDEFINED
+#define com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_UNDEFINED 0L
+#undef com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_ATSC
+#define com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_ATSC 1L
+#undef com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBC
+#define com_android_tv_tuner_TunerHal_DDELIVERY_SYSTEM_DVBC 2L
+#undef com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBS
+#define com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBS 3L
+#undef com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBS2
+#define com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBS2 4L
+#undef com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBT
+#define com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBT 5L
+#undef com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBT2
+#define com_android_tv_tuner_TunerHal_DELIVERY_SYSTEM_DVBT2 6L
/*
* Class: com_android_tv_tuner_TunerHal
* Method: nativeFinalize
@@ -81,6 +95,14 @@ JNIEXPORT jint JNICALL Java_com_android_tv_tuner_TunerHal_nativeWriteInBuffer
JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeSetHasPendingTune
(JNIEnv *, jobject, jlong, jboolean);
+/*
+ * Class: com_android_tv_tuner_TunerHal
+ * Method: nativeGetDeliverySystemType
+ * Signature: (J)I
+ */
+JNIEXPORT int JNICALL Java_com_android_tv_tuner_TunerHal_nativeGetDeliverySystemType
+ (JNIEnv *, jobject, jlong);
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/exoplayer_v2.jar b/libs/exoplayer_v2.jar
new file mode 100644
index 00000000..6cfcde9c
--- /dev/null
+++ b/libs/exoplayer_v2.jar
Binary files differ
diff --git a/libs/exoplayer_v2_ext_ffmpeg.jar b/libs/exoplayer_v2_ext_ffmpeg.jar
new file mode 100644
index 00000000..65117267
--- /dev/null
+++ b/libs/exoplayer_v2_ext_ffmpeg.jar
Binary files differ
diff --git a/proguard.flags b/proguard.flags
index 6ffed3e2..0edd14f3 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -38,6 +38,9 @@
long getSize();
void close();
}
+-keepclasseswithmembers class com.google.android.exoplayer2.ext.ffmpeg {
+ native <methods>;
+}
# Keep method which is used for reflection.
-keep @com.android.tv.common.annotation.UsedByReflection class * {*;}
@@ -53,3 +56,4 @@
# Grpc used by epg via reflection
-keep class io.grpc.internal.DnsNameResolverProvider
+
diff --git a/proto/channel.proto b/proto/channel.proto
index 982a1aa1..b4e67e07 100644
--- a/proto/channel.proto
+++ b/proto/channel.proto
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+syntax = 'proto2';
+
package com.android.tv.tuner.data;
option java_package = "com.android.tv.tuner.data";
@@ -45,12 +47,15 @@ message TunerChannelProto {
repeated AtscCaptionTrack caption_tracks = 20;
optional bool has_caption_track = 21;
optional AtscServiceType service_type = 22 [default = SERVICE_TYPE_ATSC_DIGITAL_TELEVISION];
+ optional bool recording_prohibited = 23;
+ optional string video_format = 24;
}
// Enum describing the types of tuner.
enum TunerType {
TYPE_TUNER = 0;
TYPE_FILE = 1;
+ TYPE_NETWORK = 2;
}
// Enum describing the types of video stream.
diff --git a/proto/track.proto b/proto/track.proto
index 62b8f271..fe60fed5 100644
--- a/proto/track.proto
+++ b/proto/track.proto
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+syntax = "proto2";
+
package com.android.tv.tuner.data;
option java_package = "com.android.tv.tuner.data";
diff --git a/res/drawable-xhdpi/cloud01.png b/res/drawable-xhdpi/cloud01.png
index 2bb6a2aa..75f81ce0 100644
--- a/res/drawable-xhdpi/cloud01.png
+++ b/res/drawable-xhdpi/cloud01.png
Binary files differ
diff --git a/res/drawable-xhdpi/cloud02.png b/res/drawable-xhdpi/cloud02.png
index 35c97466..25dc3bc5 100644
--- a/res/drawable-xhdpi/cloud02.png
+++ b/res/drawable-xhdpi/cloud02.png
Binary files differ
diff --git a/res/drawable-xhdpi/dvr_default_poster.png b/res/drawable-xhdpi/dvr_default_poster.png
index 683a693d..fd752afe 100644
--- a/res/drawable-xhdpi/dvr_default_poster.png
+++ b/res/drawable-xhdpi/dvr_default_poster.png
Binary files differ
diff --git a/res/drawable-xhdpi/dvr_default_program_art.png b/res/drawable-xhdpi/dvr_default_program_art.png
deleted file mode 100644
index 6a8d68ee..00000000
--- a/res/drawable-xhdpi/dvr_default_program_art.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_channel_guide.png b/res/drawable-xhdpi/ic_channel_guide.png
index 526b2f6e..8051202f 100644
--- a/res/drawable-xhdpi/ic_channel_guide.png
+++ b/res/drawable-xhdpi/ic_channel_guide.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_delete_32dp.png b/res/drawable-xhdpi/ic_delete_32dp.png
index b3e9754c..7393a653 100644
--- a/res/drawable-xhdpi/ic_delete_32dp.png
+++ b/res/drawable-xhdpi/ic_delete_32dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_developer_mode_tv_white_48dp.png b/res/drawable-xhdpi/ic_developer_mode_tv_white_48dp.png
index ab2949b7..594af851 100755..100644
--- a/res/drawable-xhdpi/ic_developer_mode_tv_white_48dp.png
+++ b/res/drawable-xhdpi/ic_developer_mode_tv_white_48dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dvr.png b/res/drawable-xhdpi/ic_dvr.png
index 347db044..512ae00d 100644
--- a/res/drawable-xhdpi/ic_dvr.png
+++ b/res/drawable-xhdpi/ic_dvr.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dvr_cancel.png b/res/drawable-xhdpi/ic_dvr_cancel.png
index bc761c70..6d6165e6 100644
--- a/res/drawable-xhdpi/ic_dvr_cancel.png
+++ b/res/drawable-xhdpi/ic_dvr_cancel.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dvr_cancel_32dp.png b/res/drawable-xhdpi/ic_dvr_cancel_32dp.png
index 339247ef..8c834685 100644
--- a/res/drawable-xhdpi/ic_dvr_cancel_32dp.png
+++ b/res/drawable-xhdpi/ic_dvr_cancel_32dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dvr_cancel_large.png b/res/drawable-xhdpi/ic_dvr_cancel_large.png
index f3686d05..4a1aed35 100644
--- a/res/drawable-xhdpi/ic_dvr_cancel_large.png
+++ b/res/drawable-xhdpi/ic_dvr_cancel_large.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dvr_delete.png b/res/drawable-xhdpi/ic_dvr_delete.png
index bcdca673..5054af97 100644
--- a/res/drawable-xhdpi/ic_dvr_delete.png
+++ b/res/drawable-xhdpi/ic_dvr_delete.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_error_recording.png b/res/drawable-xhdpi/ic_error_recording.png
deleted file mode 100644
index 5878c3b3..00000000
--- a/res/drawable-xhdpi/ic_error_recording.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_error_white_48dp.png b/res/drawable-xhdpi/ic_error_white_48dp.png
index e8e8ab5a..8c2cf1e5 100644
--- a/res/drawable-xhdpi/ic_error_white_48dp.png
+++ b/res/drawable-xhdpi/ic_error_white_48dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_fresh.png b/res/drawable-xhdpi/ic_fresh.png
deleted file mode 100644
index c1bc9583..00000000
--- a/res/drawable-xhdpi/ic_fresh.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_guide_lock.png b/res/drawable-xhdpi/ic_guide_lock.png
index e36bd12d..b0efff1c 100644
--- a/res/drawable-xhdpi/ic_guide_lock.png
+++ b/res/drawable-xhdpi/ic_guide_lock.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_s.png b/res/drawable-xhdpi/ic_launcher_s.png
index 8fe7fd59..552992d6 100644
--- a/res/drawable-xhdpi/ic_launcher_s.png
+++ b/res/drawable-xhdpi/ic_launcher_s.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_message_lock_no_permission.png b/res/drawable-xhdpi/ic_message_lock_no_permission.png
index bb996971..8fbd256c 100644
--- a/res/drawable-xhdpi/ic_message_lock_no_permission.png
+++ b/res/drawable-xhdpi/ic_message_lock_no_permission.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_message_lock_preview.png b/res/drawable-xhdpi/ic_message_lock_preview.png
index 69a5eedf..8a99c36d 100644
--- a/res/drawable-xhdpi/ic_message_lock_preview.png
+++ b/res/drawable-xhdpi/ic_message_lock_preview.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pip_option_input.png b/res/drawable-xhdpi/ic_pip_option_input.png
deleted file mode 100644
index 47c5006f..00000000
--- a/res/drawable-xhdpi/ic_pip_option_input.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pip_option_layout1.png b/res/drawable-xhdpi/ic_pip_option_layout1.png
deleted file mode 100644
index 14b2602a..00000000
--- a/res/drawable-xhdpi/ic_pip_option_layout1.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pip_option_layout2.png b/res/drawable-xhdpi/ic_pip_option_layout2.png
deleted file mode 100644
index e5d77278..00000000
--- a/res/drawable-xhdpi/ic_pip_option_layout2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pip_option_layout3.png b/res/drawable-xhdpi/ic_pip_option_layout3.png
deleted file mode 100644
index dfe110d0..00000000
--- a/res/drawable-xhdpi/ic_pip_option_layout3.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pip_option_layout4.png b/res/drawable-xhdpi/ic_pip_option_layout4.png
deleted file mode 100644
index 8ab5fa45..00000000
--- a/res/drawable-xhdpi/ic_pip_option_layout4.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pip_option_layout5.png b/res/drawable-xhdpi/ic_pip_option_layout5.png
deleted file mode 100644
index d6b53641..00000000
--- a/res/drawable-xhdpi/ic_pip_option_layout5.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pip_option_size.png b/res/drawable-xhdpi/ic_pip_option_size.png
deleted file mode 100644
index 96fb0b0c..00000000
--- a/res/drawable-xhdpi/ic_pip_option_size.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pip_option_swap.png b/res/drawable-xhdpi/ic_pip_option_swap.png
deleted file mode 100644
index fa2088ed..00000000
--- a/res/drawable-xhdpi/ic_pip_option_swap.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pip_option_swap_audio.png b/res/drawable-xhdpi/ic_pip_option_swap_audio.png
deleted file mode 100644
index a5f5431b..00000000
--- a/res/drawable-xhdpi/ic_pip_option_swap_audio.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_record_start.png b/res/drawable-xhdpi/ic_record_start.png
index 53e3f03f..bae336c3 100644
--- a/res/drawable-xhdpi/ic_record_start.png
+++ b/res/drawable-xhdpi/ic_record_start.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_recorded_program.png b/res/drawable-xhdpi/ic_recorded_program.png
deleted file mode 100644
index fe22714e..00000000
--- a/res/drawable-xhdpi/ic_recorded_program.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_related_actor.png b/res/drawable-xhdpi/ic_related_actor.png
deleted file mode 100644
index 9b726b93..00000000
--- a/res/drawable-xhdpi/ic_related_actor.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_related_search.png b/res/drawable-xhdpi/ic_related_search.png
deleted file mode 100644
index aa5cd0d2..00000000
--- a/res/drawable-xhdpi/ic_related_search.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_schedule_32dp.png b/res/drawable-xhdpi/ic_schedule_32dp.png
index b3e4bb5a..a665c6fa 100644
--- a/res/drawable-xhdpi/ic_schedule_32dp.png
+++ b/res/drawable-xhdpi/ic_schedule_32dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_scheduled_recording.png b/res/drawable-xhdpi/ic_scheduled_recording.png
index 520823a2..fbe2cd8a 100644
--- a/res/drawable-xhdpi/ic_scheduled_recording.png
+++ b/res/drawable-xhdpi/ic_scheduled_recording.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_scheduled_white.png b/res/drawable-xhdpi/ic_scheduled_white.png
index 49778def..40814e4b 100644
--- a/res/drawable-xhdpi/ic_scheduled_white.png
+++ b/res/drawable-xhdpi/ic_scheduled_white.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_setup_antenna.png b/res/drawable-xhdpi/ic_setup_antenna.png
deleted file mode 100644
index bb6d416e..00000000
--- a/res/drawable-xhdpi/ic_setup_antenna.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_setup_channels.png b/res/drawable-xhdpi/ic_setup_channels.png
index 03ff8501..fcfd596a 100644
--- a/res/drawable-xhdpi/ic_setup_channels.png
+++ b/res/drawable-xhdpi/ic_setup_channels.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_tvoption_multi_track.png b/res/drawable-xhdpi/ic_tvoption_multi_track.png
index d1aff333..e0a42e74 100644
--- a/res/drawable-xhdpi/ic_tvoption_multi_track.png
+++ b/res/drawable-xhdpi/ic_tvoption_multi_track.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_tvoption_pip.png b/res/drawable-xhdpi/ic_tvoption_pip.png
index 0f78d834..e5d77278 100644
--- a/res/drawable-xhdpi/ic_tvoption_pip.png
+++ b/res/drawable-xhdpi/ic_tvoption_pip.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_tvoption_pip_off.png b/res/drawable-xhdpi/ic_tvoption_pip_off.png
deleted file mode 100644
index 6001677b..00000000
--- a/res/drawable-xhdpi/ic_tvoption_pip_off.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_tvsidepanel_partial_locked.png b/res/drawable-xhdpi/ic_tvsidepanel_partial_locked.png
index 0997a2a4..18a12f4e 100644
--- a/res/drawable-xhdpi/ic_tvsidepanel_partial_locked.png
+++ b/res/drawable-xhdpi/ic_tvsidepanel_partial_locked.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_warning_gray600_36dp.png b/res/drawable-xhdpi/ic_warning_gray600_36dp.png
index 7c08b8f8..8a84d3b9 100644
--- a/res/drawable-xhdpi/ic_warning_gray600_36dp.png
+++ b/res/drawable-xhdpi/ic_warning_gray600_36dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_warning_white_12dp.png b/res/drawable-xhdpi/ic_warning_white_12dp.png
index 7123470a..91856a98 100644
--- a/res/drawable-xhdpi/ic_warning_white_12dp.png
+++ b/res/drawable-xhdpi/ic_warning_white_12dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_warning_white_18dp.png b/res/drawable-xhdpi/ic_warning_white_18dp.png
index 1e69e397..13d573e1 100644
--- a/res/drawable-xhdpi/ic_warning_white_18dp.png
+++ b/res/drawable-xhdpi/ic_warning_white_18dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_warning_white_32dp.png b/res/drawable-xhdpi/ic_warning_white_32dp.png
index f5267b5a..86f98771 100644
--- a/res/drawable-xhdpi/ic_warning_white_32dp.png
+++ b/res/drawable-xhdpi/ic_warning_white_32dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_warning_white_96dp.png b/res/drawable-xhdpi/ic_warning_white_96dp.png
index de684e4e..50d1f295 100644
--- a/res/drawable-xhdpi/ic_warning_white_96dp.png
+++ b/res/drawable-xhdpi/ic_warning_white_96dp.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_welcome_ripple_000.png b/res/drawable-xhdpi/ic_welcome_ripple_000.png
index c4aac06c..2ffb55dd 100644
--- a/res/drawable-xhdpi/ic_welcome_ripple_000.png
+++ b/res/drawable-xhdpi/ic_welcome_ripple_000.png
Binary files differ
diff --git a/res/drawable-xhdpi/tv_3a_00.png b/res/drawable-xhdpi/tv_3a_00.png
deleted file mode 100644
index ad8f256d..00000000
--- a/res/drawable-xhdpi/tv_3a_00.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_error.png b/res/drawable-xhdpi/tv_error.png
deleted file mode 100644
index 718f203b..00000000
--- a/res/drawable-xhdpi/tv_error.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tv_usb_antenna.png b/res/drawable-xhdpi/tv_usb_antenna.png
deleted file mode 100644
index ff6c5cc1..00000000
--- a/res/drawable-xhdpi/tv_usb_antenna.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/play_controls_time_indicator.xml b/res/drawable/play_controls_time_indicator.xml
index 16acb107..85fee1fb 100644
--- a/res/drawable/play_controls_time_indicator.xml
+++ b/res/drawable/play_controls_time_indicator.xml
@@ -17,7 +17,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
- <size android:width="@dimen/play_controls_time_indicator_width"
- android:height="@dimen/play_controls_time_indicator_height" />
<solid android:color="@color/play_controls_progress_time_indicator_color" />
</shape>
diff --git a/res/drawable/playback_progress_bar.xml b/res/drawable/playback_progress_bar.xml
new file mode 100644
index 00000000..2a70ec82
--- /dev/null
+++ b/res/drawable/playback_progress_bar.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2017 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.
+ -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@android:id/background">
+ <shape>
+ <solid android:color="@color/play_controls_progress_bar_background" />
+ </shape>
+ </item>
+ <item android:id="@android:id/secondaryProgress">
+ <shape>
+ <solid android:color="@color/play_controls_progress_bar_buffered" />
+ </shape>
+ </item>
+ <item android:id="@android:id/progress">
+ <shape>
+ <solid android:color="@color/play_controls_progress_bar_watched" />
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/res/drawable/priority_settings_action_item_selected.xml b/res/drawable/priority_settings_action_item_selected.xml
index a1ab18ae..3e017313 100644
--- a/res/drawable/priority_settings_action_item_selected.xml
+++ b/res/drawable/priority_settings_action_item_selected.xml
@@ -15,12 +15,8 @@
~ limitations under the License.
-->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:left="24dp" android:right="24dp">
- <shape>
- <solid android:color="#EEEEEE"/>
- <corners android:radius="2dp" />
- </shape>
- </item>
-</layer-list>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#EEEEEE"/>
+ <corners android:radius="2dp" />
+</shape>
diff --git a/res/drawable/setup_item_background.xml b/res/drawable/setup_item_background.xml
deleted file mode 100644
index fb3899aa..00000000
--- a/res/drawable/setup_item_background.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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.
- -->
-
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:enterFadeDuration="@android:integer/config_shortAnimTime"
- android:exitFadeDuration="@android:integer/config_shortAnimTime"
- android:color="?android:attr/colorControlHighlight">
- <item android:id="@android:id/mask">
- <shape android:shape="rectangle" >
- <solid android:color="@android:color/white" />
- <corners android:radius="2dp" />
- </shape>
- </item>
-</ripple>
diff --git a/res/layout/activity_dvr_playback.xml b/res/layout/activity_dvr_playback.xml
index 204001c7..02641d84 100644
--- a/res/layout/activity_dvr_playback.xml
+++ b/res/layout/activity_dvr_playback.xml
@@ -34,7 +34,11 @@
</FrameLayout>
<fragment android:id="@+id/dvr_playback_controls_fragment"
- android:name="com.android.tv.dvr.ui.DvrPlaybackOverlayFragment"
+ android:name="com.android.tv.dvr.ui.playback.DvrPlaybackOverlayFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <FrameLayout android:id="@+id/dvr_playback_side_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git a/res/layout/activity_dvr_schedules.xml b/res/layout/activity_dvr_schedules.xml
index 61e1f2a6..43b22866 100644
--- a/res/layout/activity_dvr_schedules.xml
+++ b/res/layout/activity_dvr_schedules.xml
@@ -16,6 +16,7 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/dvr_schedules"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/res/layout/activity_tv.xml b/res/layout/activity_tv.xml
index f766ae00..b6a0a3a3 100644
--- a/res/layout/activity_tv.xml
+++ b/res/layout/activity_tv.xml
@@ -23,33 +23,11 @@
android:foreground="@android:color/transparent"
android:keepScreenOn="true">
- <com.android.tv.ui.AppLayerTvView android:id="@+id/main_tv_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="start|center_vertical" />
-
<com.android.tv.ui.TunableTvView android:id="@+id/main_tunable_tv_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start|center_vertical" />
- <com.android.tv.ui.AppLayerTvView android:id="@+id/pip_tv_view"
- android:layout_marginLeft="@dimen/pipview_margin_horizontal"
- android:layout_marginRight="@dimen/pipview_margin_horizontal"
- android:layout_marginTop="@dimen/pipview_margin_top"
- android:layout_marginBottom="@dimen/pipview_margin_bottom"
- android:layout_width="@dimen/pipview_small_size_width"
- android:layout_height="@dimen/pipview_small_size_height" />
-
- <com.android.tv.ui.TunableTvView android:id="@+id/pip_tunable_tv_view"
- android:visibility="gone"
- android:layout_marginLeft="@dimen/pipview_margin_horizontal"
- android:layout_marginRight="@dimen/pipview_margin_horizontal"
- android:layout_marginTop="@dimen/pipview_margin_top"
- android:layout_marginBottom="@dimen/pipview_margin_bottom"
- android:layout_width="@dimen/pipview_small_size_width"
- android:layout_height="@dimen/pipview_small_size_height" />
-
<FrameLayout
android:id="@+id/scene_container"
android:layout_height="match_parent"
diff --git a/res/layout/block_screen.xml b/res/layout/block_screen.xml
index 6a04e966..c564efd0 100644
--- a/res/layout/block_screen.xml
+++ b/res/layout/block_screen.xml
@@ -16,12 +16,18 @@
-->
<com.android.tv.ui.BlockScreenView xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:gravity="center"
android:visibility="gone"
android:background="@android:color/black">
+
+ <ImageView
+ android:id="@+id/background_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="fitCenter"
+ android:visibility="gone" />
+
<!-- This layout is used for the animation -->
<LinearLayout
android:id="@+id/block_screen_container"
@@ -43,6 +49,7 @@
android:contentDescription="@null" />
<ImageView
android:id="@+id/block_screen_shrunken_icon"
+ android:src="@drawable/ic_message_lock_preview"
android:layout_width="@dimen/shrunken_tvview_block_icon_width"
android:layout_height="@dimen/shrunken_tvview_block_icon_height"
android:layout_gravity="center"
diff --git a/res/layout/dvr_details_description.xml b/res/layout/dvr_details_description.xml
index c5db470f..d55688ba 100644
--- a/res/layout/dvr_details_description.xml
+++ b/res/layout/dvr_details_description.xml
@@ -40,8 +40,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:background="?android:attr/selectableItemBackground"
- android:clickable="true">
+ android:background="?android:attr/selectableItemBackground">
<TextView android:id="@+id/dvr_details_description_body"
android:layout_width="wrap_content"
diff --git a/res/layout/dvr_main.xml b/res/layout/dvr_main.xml
index bac1cc91..6e18a834 100644
--- a/res/layout/dvr_main.xml
+++ b/res/layout/dvr_main.xml
@@ -16,6 +16,6 @@
-->
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dvr_frame"
- android:name="com.android.tv.dvr.ui.DvrBrowseFragment"
+ android:name="com.android.tv.dvr.ui.browse.DvrBrowseFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" /> \ No newline at end of file
diff --git a/res/layout/dvr_play.xml b/res/layout/dvr_play.xml
deleted file mode 100644
index 4df13686..00000000
--- a/res/layout/dvr_play.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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
- -->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="@string/no_program_information"
- android:id="@+id/placeHolderText" android:layout_gravity="center"/>
-</FrameLayout> \ No newline at end of file
diff --git a/res/layout/dvr_recording_card_view.xml b/res/layout/dvr_recording_card_view.xml
index d3808a31..53a7cf3d 100644
--- a/res/layout/dvr_recording_card_view.xml
+++ b/res/layout/dvr_recording_card_view.xml
@@ -16,12 +16,12 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tv="http://schemas.android.com/apk/res/com.android.tv"
- android:layout_width="@dimen/dvr_card_layout_width"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content">
<FrameLayout
- android:layout_width="@dimen/dvr_card_image_layout_width"
- android:layout_height="@dimen/dvr_card_image_layout_height"
+ android:layout_width="@dimen/dvr_library_card_image_layout_width"
+ android:layout_height="@dimen/dvr_library_card_image_layout_height"
android:layout_margin="2dp">
<ImageView android:id="@+id/image"
@@ -35,7 +35,7 @@
<ProgressBar android:id="@+id/recording_progress"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
- android:layout_height="@dimen/dvr_card_progress_height"
+ android:layout_height="@dimen/dvr_library_card_progress_height"
android:mirrorForRtl="false"
android:progressTint="@color/play_controls_progress_bar_watched"
android:progressDrawable="@drawable/progress_horizontal"
@@ -70,13 +70,30 @@
android:background="@color/dvr_card_info"
tv:layout_viewType="info">
- <TextView android:id="@+id/title"
+ <FrameLayout android:id="@+id/title_area"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="1dp"
- android:gravity="start"
- style="@style/dvr_card_view_title_text"
- tv:layout_viewType="main"/>
+ android:layout_height="@dimen/dvr_library_card_folded_title_height">
+
+ <TextView android:id="@+id/title_one_line"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="1dp"
+ android:gravity="start"
+ android:maxLines="1"
+ style="@style/dvr_card_view_title_text"
+ tv:layout_viewType="main"/>
+
+ <TextView android:id="@+id/title_two_lines"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="1dp"
+ android:gravity="start"
+ android:maxLines="2"
+ android:alpha="0"
+ style="@style/dvr_card_view_title_text"
+ tv:layout_viewType="main"/>
+
+ </FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
diff --git a/res/layout/dvr_schedules_item.xml b/res/layout/dvr_schedules_item.xml
index 1d97cb98..90e1123d 100644
--- a/res/layout/dvr_schedules_item.xml
+++ b/res/layout/dvr_schedules_item.xml
@@ -44,19 +44,23 @@
android:layout_height="match_parent"
android:alpha="0"/>
+ <!-- Make parent focusable in case when the info_container is not focusable.
+ As the actions are GONE when the row is not selected, if info_container is not
+ focusable, there are no focusable views in the row, which causes that the row can't be
+ selected by the DPAD. To avoid this case, the parent should be focusable. -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:focusable="true"
+ android:descendantFocusability="afterDescendants">
<LinearLayout android:id="@+id/info_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginEnd="@dimen/dvr_schedules_item_section_margin"
android:layout_weight="1"
- android:clickable="true"
- android:focusableInTouchMode="true"
- android:focusable="true">
+ android:clickable="true">
<TextView android:id="@+id/time"
android:layout_width="@dimen/dvr_schedules_item_time_width"
diff --git a/res/layout/guided_action_editable.xml b/res/layout/guided_action_editable.xml
new file mode 100644
index 00000000..84f56f8d
--- /dev/null
+++ b/res/layout/guided_action_editable.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2017 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.
+ -->
+
+<android.support.v17.leanback.widget.GuidedActionItemContainer
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/guidedactions_editable"
+ style="?attr/guidedActionItemContainerStyle"
+ android:layout_height="88dp">
+
+ <android.support.v17.leanback.widget.NonOverlappingLinearLayout
+ android:id="@+id/guidedactions_item_content"
+ style="?attr/guidedActionItemContentStyle" >
+
+ <EditText
+ android:id="@+id/guidedactions_item_title"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:textColor="@color/lb_guidedactions_item_unselected_text_color"
+ android:textSize="16sp" />
+
+ <android.support.v17.leanback.widget.GuidedActionEditText
+ android:id="@+id/guidedactions_item_description"
+ style="?attr/guidedActionItemDescriptionStyle" />
+
+ </android.support.v17.leanback.widget.NonOverlappingLinearLayout>
+
+</android.support.v17.leanback.widget.GuidedActionItemContainer> \ No newline at end of file
diff --git a/res/layout/input_banner.xml b/res/layout/input_banner.xml
index cd8770c8..f4035fcb 100644
--- a/res/layout/input_banner.xml
+++ b/res/layout/input_banner.xml
@@ -34,6 +34,7 @@
<TextView android:id="@+id/input_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:maxWidth="@dimen/input_banner_item_label_max_width"
android:fontFamily="@string/condensed_font"
android:textColor="@color/select_input_text_color_primary"
android:singleLine="true"
@@ -44,6 +45,7 @@
android:layout_marginStart="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:maxWidth="@dimen/input_banner_item_label_max_width"
android:fontFamily="@string/condensed_font"
android:textColor="@color/select_input_text_color_secondary"
android:singleLine="true"
diff --git a/res/layout/list_item_dvr_history.xml b/res/layout/list_item_dvr_history.xml
new file mode 100644
index 00000000..a9eb4c02
--- /dev/null
+++ b/res/layout/list_item_dvr_history.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2016 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="2dp" >
+
+ <TextView
+ android:id="@+id/state"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="0dp" />
+
+ <TextView
+ android:id="@+id/schedule_time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="0dp" />
+
+ <TextView
+ android:id="@+id/program_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="0dp" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="0dp"
+ android:text="@string/dvr_schedules_information_separator" />
+
+ <TextView
+ android:id="@+id/channel_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="4dp"
+ android:paddingEnd="0dp" />
+
+</LinearLayout>
diff --git a/res/layout/menu_card_action.xml b/res/layout/menu_card_action.xml
index f17c5b6a..e8114b52 100644
--- a/res/layout/menu_card_action.xml
+++ b/res/layout/menu_card_action.xml
@@ -19,50 +19,43 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/action_card_width"
android:layout_height="@dimen/action_card_height"
- android:orientation="vertical"
android:focusable="true"
android:background="@drawable/action_card_background">
- <LinearLayout
- android:orientation="vertical"
+ <TextView
+ android:id="@+id/action_card_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="@dimen/action_card_padding"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:layout_gravity="top">
+ android:layout_alignParentTop="true"
+ android:layout_marginStart="12dp"
+ android:layout_marginEnd="12dp"
+ android:layout_marginTop="6dp"
+ android:fontFamily="@string/condensed_font"
+ android:maxLines="1"
+ android:textColor="@color/action_card_label_color"
+ android:textSize="@dimen/action_card_label_font_size" />
- <TextView
- android:id="@+id/action_card_label"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="-6dp"
- android:singleLine="true"
- android:fontFamily="@string/condensed_font"
- android:textColor="@color/action_card_label_color"
- android:textSize="@dimen/action_card_label_font_size" />
-
- <TextView
- android:id="@+id/action_card_state"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="4dp"
- android:singleLine="true"
- android:fontFamily="@string/condensed_font"
- android:textColor="@color/action_card_state_color"
- android:textSize="@dimen/action_card_state_font_size" />
-
- </LinearLayout>
+ <TextView
+ android:id="@+id/action_card_state"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/action_card_label"
+ android:layout_marginStart="12dp"
+ android:layout_marginEnd="12dp"
+ android:paddingTop="4dp"
+ android:fontFamily="@string/condensed_font"
+ android:maxLines="1"
+ android:textColor="@color/action_card_state_color"
+ android:textSize="@dimen/action_card_state_font_size" />
<ImageView
android:id="@+id/action_card_icon"
android:layout_width="@dimen/action_card_icon_width"
android:layout_height="@dimen/action_card_icon_height"
android:layout_margin="@dimen/action_card_icon_padding"
- android:layout_gravity="end|bottom"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
android:contentDescription="@null"
- android:scaleType="fitCenter"
- android:src="@drawable/ic_tvoption_aspect"
- android:duplicateParentState="true" />
+ android:scaleType="fitCenter" />
</com.android.tv.menu.ActionCardView>
diff --git a/res/layout/menu_card_app_link.xml b/res/layout/menu_card_app_link.xml
index 918cb788..a7e3bd4a 100644
--- a/res/layout/menu_card_app_link.xml
+++ b/res/layout/menu_card_app_link.xml
@@ -33,13 +33,6 @@
android:layout_gravity="top"
android:scaleType="centerCrop"/>
- <View android:id="@+id/image_gradient"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/card_image_gradient"
- android:visibility="gone" />
-
<TextView android:id="@+id/app_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/layout/menu_card_channel.xml b/res/layout/menu_card_channel.xml
index 4e49636f..ed7b8273 100644
--- a/res/layout/menu_card_channel.xml
+++ b/res/layout/menu_card_channel.xml
@@ -32,13 +32,6 @@
android:layout_gravity="top"
android:scaleType="centerCrop"/>
- <View android:id="@+id/image_gradient"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/card_image_gradient"
- android:visibility="gone" />
-
<!-- The bottom margin specified in the redline is 8dp, but the redline doesn't consider
the descenders. So actually, if the bottom margin is set to 8dp, the bottom line of
the text lies 11dp above the bottom of the poster art due to the descenders.
diff --git a/res/layout/menu_card_dvr.xml b/res/layout/menu_card_dvr.xml
index cc589775..4f159083 100644
--- a/res/layout/menu_card_dvr.xml
+++ b/res/layout/menu_card_dvr.xml
@@ -23,17 +23,15 @@
android:focusable="true"
android:clickable="true">
- <FrameLayout
+ <ImageView
android:layout_width="@dimen/card_image_layout_width"
android:layout_height="@dimen/card_image_layout_height"
- android:background="@color/channel_card_guide">
- <ImageView
- android:layout_width="82dp"
- android:layout_height="48dp"
- android:layout_marginTop="16dp"
- android:src="@drawable/ic_dvr"
- android:layout_gravity="center_horizontal" />
- </FrameLayout>
+ android:background="@color/channel_card_guide"
+ android:paddingBottom="16dp"
+ android:paddingEnd="30dp"
+ android:paddingStart="30dp"
+ android:paddingTop="16dp"
+ android:src="@drawable/ic_dvr" />
<FrameLayout
android:layout_width="match_parent"
diff --git a/res/layout/menu_card_guide.xml b/res/layout/menu_card_guide.xml
index 6b724b12..c36b7df5 100644
--- a/res/layout/menu_card_guide.xml
+++ b/res/layout/menu_card_guide.xml
@@ -23,17 +23,15 @@
android:focusable="true"
android:clickable="true">
- <FrameLayout
+ <ImageView
android:layout_width="@dimen/card_image_layout_width"
android:layout_height="@dimen/card_image_layout_height"
- android:background="@color/channel_card_guide">
- <ImageView
- android:layout_width="82dp"
- android:layout_height="48dp"
- android:layout_marginTop="16dp"
- android:src="@drawable/ic_channel_guide"
- android:layout_gravity="center_horizontal" />
- </FrameLayout>
+ android:background="@color/channel_card_guide"
+ android:paddingBottom="16dp"
+ android:paddingEnd="30dp"
+ android:paddingStart="30dp"
+ android:paddingTop="16dp"
+ android:src="@drawable/ic_channel_guide" />
<TextView
android:layout_width="match_parent"
diff --git a/res/layout/menu_card_setup.xml b/res/layout/menu_card_setup.xml
index 38abd4e5..520cb4e5 100644
--- a/res/layout/menu_card_setup.xml
+++ b/res/layout/menu_card_setup.xml
@@ -22,17 +22,15 @@
android:focusable="true"
android:clickable="true">
- <FrameLayout
+ <ImageView
android:layout_width="@dimen/card_image_layout_width"
android:layout_height="@dimen/card_image_layout_height"
- android:background="@color/channel_card_guide">
- <ImageView
- android:layout_width="82dp"
- android:layout_height="48dp"
- android:layout_marginTop="16dp"
- android:src="@drawable/ic_setup_channels"
- android:layout_gravity="center_horizontal" />
- </FrameLayout>
+ android:background="@color/channel_card_guide"
+ android:paddingBottom="16dp"
+ android:paddingEnd="30dp"
+ android:paddingStart="30dp"
+ android:paddingTop="16dp"
+ android:src="@drawable/ic_setup_channels" />
<TextView
android:layout_width="match_parent"
diff --git a/res/layout/menu_card_text.xml b/res/layout/menu_card_text.xml
index 777b100f..7674f816 100644
--- a/res/layout/menu_card_text.xml
+++ b/res/layout/menu_card_text.xml
@@ -16,7 +16,6 @@
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tv="http://schemas.android.com/apk/res/com.android.tv"
android:layout_width="match_parent"
android:layout_height="wrap_content">
diff --git a/res/layout/option_container.xml b/res/layout/option_container.xml
index f053e660..dd8c96c7 100644
--- a/res/layout/option_container.xml
+++ b/res/layout/option_container.xml
@@ -22,6 +22,8 @@
android:layout_gravity="end"
android:elevation="@dimen/side_panel_elevation"
android:background="@color/side_panel_background"
+ android:translationX="@dimen/side_panel_enter_offset_x"
+ android:alpha="0.0"
android:visibility="gone">
<!-- Background for header -->
diff --git a/res/layout/option_fragment.xml b/res/layout/option_fragment.xml
index 39f67497..4a4cbbdf 100644
--- a/res/layout/option_fragment.xml
+++ b/res/layout/option_fragment.xml
@@ -41,7 +41,6 @@
android:clipChildren="false"
android:clipToPadding="false"
android:focusable="true"
- android:paddingTop="@dimen/side_panel_list_padding_top"
android:paddingBottom="@dimen/side_panel_list_padding_bottom"
lb:verticalMargin="@dimen/side_panel_list_vertical_margin" />
diff --git a/res/layout/option_item_action.xml b/res/layout/option_item_action.xml
index a7a02b2d..6dc5b35b 100644
--- a/res/layout/option_item_action.xml
+++ b/res/layout/option_item_action.xml
@@ -24,19 +24,8 @@
android:focusable="true"
android:background="?android:attr/selectableItemBackground" >
- <ImageView
- android:id="@+id/icon"
- android:layout_width="36dp"
- android:layout_height="36dp"
- android:layout_weight="0"
- android:layout_marginEnd="20dp"
- android:layout_marginTop="14dp"
- android:layout_marginBottom="14dp"
- android:contentDescription="@null" />
-
<include layout="@layout/option_item_common"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1" />
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
</LinearLayout>
diff --git a/res/layout/option_item_channel_check.xml b/res/layout/option_item_channel_check.xml
index 2817d2b9..f68c2f9a 100644
--- a/res/layout/option_item_channel_check.xml
+++ b/res/layout/option_item_channel_check.xml
@@ -28,7 +28,6 @@
android:id="@+id/check_box"
android:layout_width="@dimen/option_item_compound_button_width"
android:layout_height="match_parent"
- android:layout_weight="0"
android:background="@null"
android:clickable="false" />
diff --git a/res/layout/option_item_channel_lock.xml b/res/layout/option_item_channel_lock.xml
index f4f65f99..f7b5c9e9 100644
--- a/res/layout/option_item_channel_lock.xml
+++ b/res/layout/option_item_channel_lock.xml
@@ -28,7 +28,6 @@
android:id="@+id/check_box"
android:layout_width="@dimen/option_item_compound_button_width"
android:layout_height="match_parent"
- android:layout_weight="0"
android:button="@drawable/btn_lock_material_anim"
android:background="@null"
android:clickable="false" />
diff --git a/res/layout/option_item_check_box.xml b/res/layout/option_item_check_box.xml
index 1ab2ba45..711e362b 100644
--- a/res/layout/option_item_check_box.xml
+++ b/res/layout/option_item_check_box.xml
@@ -28,7 +28,6 @@
android:id="@+id/check_box"
android:layout_width="@dimen/option_item_compound_button_width"
android:layout_height="wrap_content"
- android:layout_weight="0"
android:layout_gravity="center"
android:background="@null"
android:clickable="false" />
diff --git a/res/layout/option_item_common.xml b/res/layout/option_item_common.xml
index ca0013c6..65294211 100644
--- a/res/layout/option_item_common.xml
+++ b/res/layout/option_item_common.xml
@@ -42,7 +42,7 @@
android:fontFamily="@string/option_item_secondary_text_font"
android:textSize="@dimen/option_item_secondary_text_size"
android:textColor="@color/option_item_secondary_text_color"
- android:maxLines="3"
+ android:maxLines="@integer/option_item_description_max_lines"
android:ellipsize="end"
android:focusable="false" />
diff --git a/res/layout/option_item_radio_button.xml b/res/layout/option_item_radio_button.xml
index 2e4fa11a..35be8c78 100644
--- a/res/layout/option_item_radio_button.xml
+++ b/res/layout/option_item_radio_button.xml
@@ -28,7 +28,6 @@
android:id="@+id/radio_button"
android:layout_width="@dimen/option_item_compound_button_width"
android:layout_height="match_parent"
- android:layout_weight="0"
android:background="@null"
android:clickable="false" />
diff --git a/res/layout/option_item_switch.xml b/res/layout/option_item_switch.xml
index 4750ebc4..7b5c6ece 100644
--- a/res/layout/option_item_switch.xml
+++ b/res/layout/option_item_switch.xml
@@ -33,7 +33,6 @@
android:id="@+id/switch_button"
android:layout_width="@dimen/option_item_compound_button_width"
android:layout_height="match_parent"
- android:layout_weight="0"
android:background="@null"
android:clickable="false" />
diff --git a/res/layout/play_controls_contents.xml b/res/layout/play_controls_contents.xml
index ac61a2d4..9afc5f3d 100644
--- a/res/layout/play_controls_contents.xml
+++ b/res/layout/play_controls_contents.xml
@@ -16,6 +16,7 @@
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tv="http://schemas.android.com/apk/res-auto"
android:id="@+id/play_controls"
style="@style/menu_row_contents_view"
android:layoutDirection="ltr">
@@ -28,153 +29,118 @@
android:layout_alignStart="@+id/body"
android:layout_marginBottom="@dimen/play_controls_time_bottom_margin"
android:gravity="center"
- android:singleLine="true"
+ android:maxLines="1"
android:textColor="@color/play_controls_time_text_color"
android:textSize="@dimen/play_controls_time_text_size"
android:fontFamily="@string/font" />
- <LinearLayout
+ <RelativeLayout
android:id="@id/body"
- android:orientation="vertical"
android:layout_width="@dimen/play_controls_width"
android:layout_height="wrap_content"
android:layout_below="@id/time_text"
android:layout_centerHorizontal="true"
android:background="@drawable/play_controls_body_shape">
- <RelativeLayout
+ <com.android.tv.menu.PlaybackProgressBar
+ android:id="@+id/progress"
android:layout_width="match_parent"
- android:layout_height="@dimen/play_controls_progress_height">
-
- <ImageView
- android:id="@+id/timeline_bg_start"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentStart="true"
- android:src="@color/play_controls_progress_bar_background" />
- <ImageView
- android:id="@+id/watched"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_toEndOf="@id/timeline_bg_start"
- android:src="@color/play_controls_progress_bar_watched" />
- <ImageView
- android:id="@+id/buffered"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_toEndOf="@id/watched"
- android:src="@color/play_controls_progress_bar_buffered" />
- <ImageView
- android:id="@+id/timeline_bg_end"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentEnd="true"
- android:layout_toEndOf="@id/buffered"
- android:src="@color/play_controls_progress_bar_background" />
-
- </RelativeLayout>
-
- <FrameLayout
+ android:layout_height="@dimen/play_controls_progress_height"
+ android:layout_alignParentTop="true"
+ tv:progressDrawable="@drawable/playback_progress_bar" />
+ <TextView
android:id="@+id/background"
android:layout_width="match_parent"
+ android:layout_height="@dimen/play_controls_button_height"
+ android:layout_below="@id/progress"
+ android:background="@drawable/play_controls_body_background"
+ android:gravity="center"
+ android:maxLines="1"
+ android:textColor="@color/play_controls_unavailable_message_text_color"
+ android:textSize="@dimen/play_controls_unavailable_message_text_size"
+ android:fontFamily="@string/font" />
+ <TextView
+ android:id="@+id/program_start_time"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/play_controls_body_background">
-
- <TextView
- android:id="@+id/program_start_time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/play_controls_program_time_margin_start"
- android:layout_marginTop="@dimen/play_controls_program_time_margin_top"
- android:singleLine="true"
- android:textColor="@color/play_controls_rec_time_text_color"
- android:textSize="@dimen/play_controls_rec_time_text_size"
- android:fontFamily="@string/font" />
- <TextView
- android:id="@+id/program_end_time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="@dimen/play_controls_program_time_margin_end"
- android:layout_marginTop="@dimen/play_controls_program_time_margin_top"
- android:layout_gravity="end"
- android:singleLine="true"
- android:textColor="@color/play_controls_rec_time_text_color"
- android:textSize="@dimen/play_controls_rec_time_text_size"
- android:fontFamily="@string/font" />
-
- <RelativeLayout
- android:id="@+id/play_control_bar"
- android:layout_width="match_parent"
- android:layout_height="@dimen/play_controls_button_height">
-
- <com.android.tv.menu.PlayControlsButton
- android:id="@+id/play_pause"
- android:layout_width="@dimen/play_controls_button_width"
- android:layout_height="match_parent"
- android:layout_marginLeft="@dimen/play_controls_button_normal_margin"
- android:layout_marginRight="@dimen/play_controls_button_normal_margin"
- android:layout_centerHorizontal="true" />
- <com.android.tv.menu.PlayControlsButton
- android:id="@+id/rewind"
- android:layout_width="@dimen/play_controls_button_width"
- android:layout_height="match_parent"
- android:layout_marginLeft="@dimen/play_controls_button_normal_margin"
- android:layout_marginRight="@dimen/play_controls_button_normal_margin"
- android:layout_toLeftOf="@id/play_pause" />
- <com.android.tv.menu.PlayControlsButton
- android:id="@+id/jump_previous"
- android:layout_width="@dimen/play_controls_button_width"
- android:layout_height="match_parent"
- android:layout_marginLeft="@dimen/play_controls_button_normal_margin"
- android:layout_marginRight="@dimen/play_controls_button_normal_margin"
- android:layout_toLeftOf="@id/rewind" />
- <com.android.tv.menu.PlayControlsButton
- android:id="@+id/fast_forward"
- android:layout_width="@dimen/play_controls_button_width"
- android:layout_height="match_parent"
- android:layout_marginLeft="@dimen/play_controls_button_normal_margin"
- android:layout_marginRight="@dimen/play_controls_button_normal_margin"
- android:layout_toRightOf="@id/play_pause" />
- <com.android.tv.menu.PlayControlsButton
- android:id="@+id/jump_next"
- android:layout_width="@dimen/play_controls_button_width"
- android:layout_height="match_parent"
- android:layout_marginLeft="@dimen/play_controls_button_normal_margin"
- android:layout_marginRight="@dimen/play_controls_button_normal_margin"
- android:layout_toRightOf="@id/fast_forward" />
- <com.android.tv.menu.PlayControlsButton
- android:id="@+id/record"
- android:layout_width="@dimen/play_controls_button_width"
- android:layout_height="match_parent"
- android:layout_marginLeft="@dimen/play_controls_button_normal_margin"
- android:layout_marginRight="@dimen/play_controls_button_normal_margin"
- android:layout_toRightOf="@id/jump_next"
- android:visibility="gone" />
-
- </RelativeLayout>
+ android:layout_alignParentStart="true"
+ android:layout_below="@id/progress"
+ android:layout_marginStart="@dimen/play_controls_program_time_margin_start"
+ android:layout_marginTop="@dimen/play_controls_program_time_margin_top"
+ android:maxLines="1"
+ android:textColor="@color/play_controls_rec_time_text_color"
+ android:textSize="@dimen/play_controls_rec_time_text_size"
+ android:fontFamily="@string/font" />
+ <TextView
+ android:id="@+id/program_end_time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_below="@id/progress"
+ android:layout_marginEnd="@dimen/play_controls_program_time_margin_end"
+ android:layout_marginTop="@dimen/play_controls_program_time_margin_top"
+ android:maxLines="1"
+ android:textColor="@color/play_controls_rec_time_text_color"
+ android:textSize="@dimen/play_controls_rec_time_text_size"
+ android:fontFamily="@string/font" />
- <TextView
- android:id="@+id/unavailable_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:singleLine="true"
- android:textColor="@color/play_controls_unavailable_message_text_color"
- android:textSize="@dimen/play_controls_unavailable_message_text_size"
- android:fontFamily="@string/font"
- android:visibility="gone"
- android:text="@string/play_controls_unavailable" />
- </FrameLayout>
- </LinearLayout>
+ <com.android.tv.menu.PlayControlsButton
+ android:id="@+id/play_pause"
+ android:layout_width="@dimen/play_controls_button_width"
+ android:layout_height="@dimen/play_controls_button_height"
+ android:layout_below="@id/progress"
+ android:layout_marginLeft="@dimen/play_controls_button_compact_margin"
+ android:layout_marginRight="@dimen/play_controls_button_compact_margin"
+ android:layout_centerHorizontal="true" />
+ <com.android.tv.menu.PlayControlsButton
+ android:id="@+id/rewind"
+ android:layout_width="@dimen/play_controls_button_width"
+ android:layout_height="@dimen/play_controls_button_height"
+ android:layout_below="@id/progress"
+ android:layout_marginLeft="@dimen/play_controls_button_compact_margin"
+ android:layout_marginRight="@dimen/play_controls_button_compact_margin"
+ android:layout_toStartOf="@id/play_pause" />
+ <com.android.tv.menu.PlayControlsButton
+ android:id="@+id/jump_previous"
+ android:layout_width="@dimen/play_controls_button_width"
+ android:layout_height="@dimen/play_controls_button_height"
+ android:layout_below="@id/progress"
+ android:layout_marginLeft="@dimen/play_controls_button_compact_margin"
+ android:layout_marginRight="@dimen/play_controls_button_compact_margin"
+ android:layout_toStartOf="@id/rewind" />
+ <com.android.tv.menu.PlayControlsButton
+ android:id="@+id/fast_forward"
+ android:layout_width="@dimen/play_controls_button_width"
+ android:layout_height="@dimen/play_controls_button_height"
+ android:layout_below="@id/progress"
+ android:layout_marginLeft="@dimen/play_controls_button_compact_margin"
+ android:layout_marginRight="@dimen/play_controls_button_compact_margin"
+ android:layout_toEndOf="@id/play_pause" />
+ <com.android.tv.menu.PlayControlsButton
+ android:id="@+id/jump_next"
+ android:layout_width="@dimen/play_controls_button_width"
+ android:layout_height="@dimen/play_controls_button_height"
+ android:layout_below="@id/progress"
+ android:layout_marginLeft="@dimen/play_controls_button_compact_margin"
+ android:layout_marginRight="@dimen/play_controls_button_compact_margin"
+ android:layout_toEndOf="@id/fast_forward" />
+ <com.android.tv.menu.PlayControlsButton
+ android:id="@+id/record"
+ android:layout_width="@dimen/play_controls_button_width"
+ android:layout_height="@dimen/play_controls_button_height"
+ android:layout_below="@id/progress"
+ android:layout_marginLeft="@dimen/play_controls_button_compact_margin"
+ android:layout_marginRight="@dimen/play_controls_button_compact_margin"
+ android:layout_toEndOf="@id/jump_next" />
+ </RelativeLayout>
- <ImageView
+ <View
android:id="@+id/time_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="@dimen/play_controls_time_indicator_width"
+ android:layout_height="@dimen/play_controls_time_indicator_height"
android:layout_marginTop="@dimen/play_controls_time_indicator_top_margin"
android:layout_alignTop="@id/body"
android:layout_alignStart="@id/body"
android:background="@drawable/play_controls_time_indicator"
- android:visibility="invisible"
android:elevation="1dp" />
</RelativeLayout>
diff --git a/res/layout/select_input_item.xml b/res/layout/select_input_item.xml
index 1ff6df29..12fedca6 100644
--- a/res/layout/select_input_item.xml
+++ b/res/layout/select_input_item.xml
@@ -28,6 +28,7 @@
<TextView android:id="@+id/input_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:maxWidth="@dimen/input_banner_item_label_max_width"
android:fontFamily="@string/condensed_font"
android:singleLine="true"
android:ellipsize="end"
@@ -37,6 +38,7 @@
android:layout_marginStart="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:maxWidth="@dimen/input_banner_item_label_max_width"
android:fontFamily="@string/condensed_font"
android:singleLine="true"
android:ellipsize="end"
diff --git a/res/layout/tunable_tv_view.xml b/res/layout/tunable_tv_view.xml
index e02fb892..00c9908c 100644
--- a/res/layout/tunable_tv_view.xml
+++ b/res/layout/tunable_tv_view.xml
@@ -16,15 +16,14 @@
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
- <View
- android:id="@+id/block_screen_for_tune"
- android:visibility="gone"
+
+ <com.android.tv.ui.AppLayerTvView android:id="@+id/tv_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@android:color/black" />
+ android:layout_gravity="start|center_vertical" />
<include layout="@layout/block_screen"
- android:id="@+id/hide_screen" />
+ android:id="@+id/block_screen" />
<ProgressBar
android:id="@+id/buffering_spinner"
@@ -34,11 +33,8 @@
android:background="@android:color/transparent"
android:layout_gravity="center" />
- <include layout="@layout/block_screen"
- android:id="@+id/block_screen" />
-
<View
- android:id="@+id/dim"
+ android:id="@+id/dim_screen"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/res/raw/third_party_license_metadata b/res/raw/third_party_license_metadata
new file mode 100755
index 00000000..4a31b623
--- /dev/null
+++ b/res/raw/third_party_license_metadata
@@ -0,0 +1,21 @@
+19:1096 Animal Sniffer
+1140:11358 Apache Commons Codec
+12514:11357 Error Prone
+23885:11358 ExoPlayer
+35266:11358 FasterXML Jackson2
+46640:11358 Google Auto
+58013:11358 Guava JDK5
+69386:11362 Guava JDK7
+80759:11358 J2ObjC
+92129:11358 JSR 250
+103498:11358 OkHttp
+114865:11358 Okio
+126232:10402 gRPC
+136654:11358 instrumentation
+148036:1473 Auth client library
+149521:1602 JSR 305
+151136:1732 Protobuf
+152886:1732 Protobuf Nano
+154631:1561 minijail
+156203:26427 ffmpeg
+182640:19442 icu4j
diff --git a/res/raw/third_party_licenses b/res/raw/third_party_licenses
new file mode 100755
index 00000000..96227dce
--- /dev/null
+++ b/res/raw/third_party_licenses
@@ -0,0 +1,3751 @@
+
+
+Animal Sniffer:
+
+The MIT License
+
+Copyright (c) 2008 Kohsuke Kawaguchi and codehaus.org.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+Apache Commons Codec:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+Error Prone:
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+ExoPlayer:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+FasterXML Jackson2:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+Google Auto:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+Guava JDK5:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+Guava JDK7:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+
+J2ObjC:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+JSR 250:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+OkHttp:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+Okio:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+gRPC:
+
+
+ Apache License
+ Version 2.0, January 2004
+ https://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for any such Derivative Works as a whole, provided Your use,
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ Copyright 2015-2017 gRPC authors.
+
+ 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
+
+ https://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.
+
+
+instrumentation:
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+Auth client library:
+
+Copyright 2014, Google Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+JSR 305:
+
+Copyright (c) 2007-2009, JSR305 expert group
+All rights reserved.
+
+http://www.opensource.org/licenses/bsd-license.php
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of the JSR305 expert group nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+
+Protobuf:
+
+Copyright 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it. This code is not
+standalone and requires a support library to be linked with it. This
+support library is itself covered by the above license.
+
+
+Protobuf Nano:
+
+Copyright 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it. This code is not
+standalone and requires a support library to be linked with it. This
+support library is itself covered by the above license.
+
+
+minijail:
+
+// Copyright 2014 The Chromium OS Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ffmpeg:
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
+icu4j:
+
+COPYRIGHT AND PERMISSION NOTICE (ICU 58 and later)
+
+Copyright © 1991-2016 Unicode, Inc. All rights reserved.
+Distributed under the Terms of Use in http://www.unicode.org/copyright.html
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Unicode data files and any associated documentation
+(the "Data Files") or Unicode software and any associated documentation
+(the "Software") to deal in the Data Files or Software
+without restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, and/or sell copies of
+the Data Files or Software, and to permit persons to whom the Data Files
+or Software are furnished to do so, provided that either
+(a) this copyright and permission notice appear with all copies
+of the Data Files or Software, or
+(b) this copyright and permission notice appear in associated
+Documentation.
+
+THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
+NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
+DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale,
+use or other dealings in these Data Files or Software without prior
+written authorization of the copyright holder.
+
+---------------------
+
+Third-Party Software Licenses
+
+This section contains third-party software notices and/or additional
+terms for licensed third-party software components included within ICU
+libraries.
+
+1. ICU License - ICU 1.8.1 to ICU 57.1
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1995-2016 International Business Machines Corporation and others
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
+SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+All trademarks and registered trademarks mentioned herein are the
+property of their respective owners.
+
+2. Chinese/Japanese Word Break Dictionary Data (cjdict.txt)
+
+ # The Google Chrome software developed by Google is licensed under
+ # the BSD license. Other software included in this distribution is
+ # provided under other licenses, as set forth below.
+ #
+ # The BSD License
+ # http://opensource.org/licenses/bsd-license.php
+ # Copyright (C) 2006-2008, Google Inc.
+ #
+ # All rights reserved.
+ #
+ # Redistribution and use in source and binary forms, with or without
+ # modification, are permitted provided that the following conditions are met:
+ #
+ # Redistributions of source code must retain the above copyright notice,
+ # this list of conditions and the following disclaimer.
+ # Redistributions in binary form must reproduce the above
+ # copyright notice, this list of conditions and the following
+ # disclaimer in the documentation and/or other materials provided with
+ # the distribution.
+ # Neither the name of Google Inc. nor the names of its
+ # contributors may be used to endorse or promote products derived from
+ # this software without specific prior written permission.
+ #
+ #
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #
+ #
+ # The word list in cjdict.txt are generated by combining three word lists
+ # listed below with further processing for compound word breaking. The
+ # frequency is generated with an iterative training against Google web
+ # corpora.
+ #
+ # * Libtabe (Chinese)
+ # - https://sourceforge.net/project/?group_id=1519
+ # - Its license terms and conditions are shown below.
+ #
+ # * IPADIC (Japanese)
+ # - http://chasen.aist-nara.ac.jp/chasen/distribution.html
+ # - Its license terms and conditions are shown below.
+ #
+ # ---------COPYING.libtabe ---- BEGIN--------------------
+ #
+ # /*
+ # * Copyrighy (c) 1999 TaBE Project.
+ # * Copyright (c) 1999 Pai-Hsiang Hsiao.
+ # * All rights reserved.
+ # *
+ # * Redistribution and use in source and binary forms, with or without
+ # * modification, are permitted provided that the following conditions
+ # * are met:
+ # *
+ # * . Redistributions of source code must retain the above copyright
+ # * notice, this list of conditions and the following disclaimer.
+ # * . Redistributions in binary form must reproduce the above copyright
+ # * notice, this list of conditions and the following disclaimer in
+ # * the documentation and/or other materials provided with the
+ # * distribution.
+ # * . Neither the name of the TaBE Project nor the names of its
+ # * contributors may be used to endorse or promote products derived
+ # * from this software without specific prior written permission.
+ # *
+ # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ # * OF THE POSSIBILITY OF SUCH DAMAGE.
+ # */
+ #
+ # /*
+ # * Copyright (c) 1999 Computer Systems and Communication Lab,
+ # * Institute of Information Science, Academia
+ # * Sinica. All rights reserved.
+ # *
+ # * Redistribution and use in source and binary forms, with or without
+ # * modification, are permitted provided that the following conditions
+ # * are met:
+ # *
+ # * . Redistributions of source code must retain the above copyright
+ # * notice, this list of conditions and the following disclaimer.
+ # * . Redistributions in binary form must reproduce the above copyright
+ # * notice, this list of conditions and the following disclaimer in
+ # * the documentation and/or other materials provided with the
+ # * distribution.
+ # * . Neither the name of the Computer Systems and Communication Lab
+ # * nor the names of its contributors may be used to endorse or
+ # * promote products derived from this software without specific
+ # * prior written permission.
+ # *
+ # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ # * OF THE POSSIBILITY OF SUCH DAMAGE.
+ # */
+ #
+ # Copyright 1996 Chih-Hao Tsai @ Beckman Institute,
+ # University of Illinois
+ # c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4
+ #
+ # ---------------COPYING.libtabe-----END--------------------------------
+ #
+ #
+ # ---------------COPYING.ipadic-----BEGIN-------------------------------
+ #
+ # Copyright 2000, 2001, 2002, 2003 Nara Institute of Science
+ # and Technology. All Rights Reserved.
+ #
+ # Use, reproduction, and distribution of this software is permitted.
+ # Any copy of this software, whether in its original form or modified,
+ # must include both the above copyright notice and the following
+ # paragraphs.
+ #
+ # Nara Institute of Science and Technology (NAIST),
+ # the copyright holders, disclaims all warranties with regard to this
+ # software, including all implied warranties of merchantability and
+ # fitness, in no event shall NAIST be liable for
+ # any special, indirect or consequential damages or any damages
+ # whatsoever resulting from loss of use, data or profits, whether in an
+ # action of contract, negligence or other tortuous action, arising out
+ # of or in connection with the use or performance of this software.
+ #
+ # A large portion of the dictionary entries
+ # originate from ICOT Free Software. The following conditions for ICOT
+ # Free Software applies to the current dictionary as well.
+ #
+ # Each User may also freely distribute the Program, whether in its
+ # original form or modified, to any third party or parties, PROVIDED
+ # that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear
+ # on, or be attached to, the Program, which is distributed substantially
+ # in the same form as set out herein and that such intended
+ # distribution, if actually made, will neither violate or otherwise
+ # contravene any of the laws and regulations of the countries having
+ # jurisdiction over the User or the intended distribution itself.
+ #
+ # NO WARRANTY
+ #
+ # The program was produced on an experimental basis in the course of the
+ # research and development conducted during the project and is provided
+ # to users as so produced on an experimental basis. Accordingly, the
+ # program is provided without any warranty whatsoever, whether express,
+ # implied, statutory or otherwise. The term "warranty" used herein
+ # includes, but is not limited to, any warranty of the quality,
+ # performance, merchantability and fitness for a particular purpose of
+ # the program and the nonexistence of any infringement or violation of
+ # any right of any third party.
+ #
+ # Each user of the program will agree and understand, and be deemed to
+ # have agreed and understood, that there is no warranty whatsoever for
+ # the program and, accordingly, the entire risk arising from or
+ # otherwise connected with the program is assumed by the user.
+ #
+ # Therefore, neither ICOT, the copyright holder, or any other
+ # organization that participated in or was otherwise related to the
+ # development of the program and their respective officials, directors,
+ # officers and other employees shall be held liable for any and all
+ # damages, including, without limitation, general, special, incidental
+ # and consequential damages, arising out of or otherwise in connection
+ # with the use or inability to use the program or any product, material
+ # or result produced or otherwise obtained by using the program,
+ # regardless of whether they have been advised of, or otherwise had
+ # knowledge of, the possibility of such damages at any time during the
+ # project or thereafter. Each user will be deemed to have agreed to the
+ # foregoing by his or her commencement of use of the program. The term
+ # "use" as used herein includes, but is not limited to, the use,
+ # modification, copying and distribution of the program and the
+ # production of secondary products from the program.
+ #
+ # In the case where the program, whether in its original form or
+ # modified, was distributed or delivered to or received by a user from
+ # any person, organization or entity other than ICOT, unless it makes or
+ # grants independently of ICOT any specific warranty to the user in
+ # writing, such person, organization or entity, will also be exempted
+ # from and not be held liable to the user for any such damages as noted
+ # above as far as the program is concerned.
+ #
+ # ---------------COPYING.ipadic-----END----------------------------------
+
+3. Lao Word Break Dictionary Data (laodict.txt)
+
+ # Copyright (c) 2013 International Business Machines Corporation
+ # and others. All Rights Reserved.
+ #
+ # Project: http://code.google.com/p/lao-dictionary/
+ # Dictionary: http://lao-dictionary.googlecode.com/git/Lao-Dictionary.txt
+ # License: http://lao-dictionary.googlecode.com/git/Lao-Dictionary-LICENSE.txt
+ # (copied below)
+ #
+ # This file is derived from the above dictionary, with slight
+ # modifications.
+ # ----------------------------------------------------------------------
+ # Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell.
+ # All rights reserved.
+ #
+ # Redistribution and use in source and binary forms, with or without
+ # modification,
+ # are permitted provided that the following conditions are met:
+ #
+ #
+ # Redistributions of source code must retain the above copyright notice, this
+ # list of conditions and the following disclaimer. Redistributions in
+ # binary form must reproduce the above copyright notice, this list of
+ # conditions and the following disclaimer in the documentation and/or
+ # other materials provided with the distribution.
+ #
+ #
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ # OF THE POSSIBILITY OF SUCH DAMAGE.
+ # --------------------------------------------------------------------------
+
+4. Burmese Word Break Dictionary Data (burmesedict.txt)
+
+ # Copyright (c) 2014 International Business Machines Corporation
+ # and others. All Rights Reserved.
+ #
+ # This list is part of a project hosted at:
+ # github.com/kanyawtech/myanmar-karen-word-lists
+ #
+ # --------------------------------------------------------------------------
+ # Copyright (c) 2013, LeRoy Benjamin Sharon
+ # All rights reserved.
+ #
+ # Redistribution and use in source and binary forms, with or without
+ # modification, are permitted provided that the following conditions
+ # are met: Redistributions of source code must retain the above
+ # copyright notice, this list of conditions and the following
+ # disclaimer. Redistributions in binary form must reproduce the
+ # above copyright notice, this list of conditions and the following
+ # disclaimer in the documentation and/or other materials provided
+ # with the distribution.
+ #
+ # Neither the name Myanmar Karen Word Lists, nor the names of its
+ # contributors may be used to endorse or promote products derived
+ # from this software without specific prior written permission.
+ #
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+ # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ # SUCH DAMAGE.
+ # --------------------------------------------------------------------------
+
+5. Time Zone Database
+
+ ICU uses the public domain data and code derived from Time Zone
+Database for its time zone support. The ownership of the TZ database
+is explained in BCP 175: Procedure for Maintaining the Time Zone
+Database section 7.
+
+ # 7. Database Ownership
+ #
+ # The TZ database itself is not an IETF Contribution or an IETF
+ # document. Rather it is a pre-existing and regularly updated work
+ # that is in the public domain, and is intended to remain in the
+ # public domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do
+ # not apply to the TZ Database or contributions that individuals make
+ # to it. Should any claims be made and substantiated against the TZ
+ # Database, the organization that is providing the IANA
+ # Considerations defined in this RFC, under the memorandum of
+ # understanding with the IETF, currently ICANN, may act in accordance
+ # with all competent court orders. No ownership claims will be made
+ # by ICANN or the IETF Trust on the database or the code. Any person
+ # making a contribution to the database or code waives all rights to
+ # future claims in that contribution or in the TZ Database.
diff --git a/res/transition/dvr_details_shared_element_enter_transition.xml b/res/transition/dvr_details_shared_element_enter_transition.xml
new file mode 100644
index 00000000..d3fc0651
--- /dev/null
+++ b/res/transition/dvr_details_shared_element_enter_transition.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 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.
+-->
+
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tv="http://schemas.android.com/apk/res-auto">
+ <transition class="com.android.tv.dvr.ui.FadeBackground"
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:duration="500"
+ tv:fadingMode="fade_in">
+ <targets>
+ <target android:targetId="@id/details_frame" />
+ <target android:targetId="@id/details_overview_image" />
+ <target android:targetId="@id/details_overview_right_panel" />
+ </targets>
+ </transition>
+ <!-- The followings are copied from lb_shared_element_enter_transiton.xml -->
+ <fade
+ android:fadingMode="fade_in"
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:startDelay="325"
+ android:duration="150"/>
+ <changeBounds
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:duration="500"/>
+ <changeTransform
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:duration="500"/>
+ <!-- TODO: Change this to changeImageTransform once b/32405620 is fixed. -->
+ <transition class="com.android.tv.dvr.ui.ChangeImageTransformWithScaledParent"
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:duration="500"/>
+</transitionSet> \ No newline at end of file
diff --git a/res/transition/dvr_details_shared_element_return_transition.xml b/res/transition/dvr_details_shared_element_return_transition.xml
new file mode 100644
index 00000000..ceabca46
--- /dev/null
+++ b/res/transition/dvr_details_shared_element_return_transition.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 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.
+-->
+
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tv="http://schemas.android.com/apk/res-auto">
+ <transition class="com.android.tv.dvr.ui.FadeBackground"
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:duration="325"
+ tv:fadingMode="fade_out">
+ <targets>
+ <target android:targetId="@id/details_frame" />
+ <target android:targetId="@id/details_overview_image" />
+ <target android:targetId="@id/details_overview_right_panel" />
+ </targets>
+ </transition>
+ <!-- The followings are copied from lb_shared_element_return_transiton.xml -->
+ <fade
+ android:fadingMode="fade_out"
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:duration="75"/>
+ <changeBounds
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:duration="325"/>
+ <changeTransform
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:duration="325"/>
+ <!-- TODO: Change this to changeImageTransofrm once b/32405620 is fixed. -->
+ <transition class="com.android.tv.dvr.ui.ChangeImageTransformWithScaledParent"
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ android:duration="325"/>
+</transitionSet> \ No newline at end of file
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 7778e751..24d484d9 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Speelkontroles"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Onlangse kanale"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanale"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV-opsies"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP-opsies"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Speelkontroles onbeskikbaar vir hierdie kanaal"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Speel of laat wag"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Vinnig vorentoe"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Onderskrifte"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Vertoonmodus"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Aan"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Af"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-oudio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Kry meer kanale"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Instellings"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Bron"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Ruil"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Aan"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Af"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Klank"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Hoof"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP-venster"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Uitleg"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Regs onder"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Regs bo"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Links bo"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Links onder"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Langs mekaar"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Grootte"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Groot"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Klein"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Invoerbron"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenna/kabel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Geen programinligting nie"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Geen inligting nie"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Geblokkeerde kanaal"</string>
- <string name="default_language" msgid="4122326459624337928">"Onbekende taal"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Onbekende taal"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Onderskrifte %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Onderskrifte"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Af"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Pasmaak formatering"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Groepeer volgens"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Hierdie program word geblokkeer"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Hierdie program is ongegradeer"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Hierdie program is <xliff:g id="RATING">%1$s</xliff:g> gegradeer"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Die invoer steun nie outoskandering nie"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Kan nie outoskandeer vir \'<xliff:g id="TV_INPUT">%s</xliff:g>\' begin nie"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d kanaal is bygevoeg</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Geen kanale bygevoeg nie"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Ontvanger"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Ouerkontroles"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Aan"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Af"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Ander lande"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Geen"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Geen"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Ongegradeer"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Keer ongegradeerde programme"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Geen"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Hoë beperkings"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Mediumbeperkings"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Voer jou PIN in om hierdie kanaal te kyk"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Voer jou PIN in om hierdie program te kyk"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Hierdie program is <xliff:g id="RATING">%1$s</xliff:g> gegradeer. Voer jou PIN in om hierdie program te kyk"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Hierdie program is ongegradeer. Voer jou PIN in om hierdie program te kyk"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Voer jou PIN in"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Skep \'n PIN om ouerkontroles op te stel"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Voer nuwe PIN in"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Die PIN is verkeerd. Probeer weer."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Probeer weer. PIN stem nie ooreen nie"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Voer jou poskode in."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Regstreekse kanale-program sal die poskode gebruik om \'n volledige programgids vir die TV-kanale te voorsien."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Voer jou poskode in"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Ongeldige poskode"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Instellings"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Pasmaak kanaallys"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Kies kanale vir jou programgids"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanaalbronne"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nuwe kanale beskikbaar"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Ouerkontroles"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Tydskuif"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Neem op terwyl jy kyk sodat jy regstreekse programme kan onderbreek of terugspeel.\nWaarskuwing: Dit kan die lewe van die interne berging deur die intensiewe gebruik van die berging verkort."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Oopbronlisensies"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Oopbronlisensies"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Stuur terugvoer"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Weergawe"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Druk Regs en voer jou PIN in om hierdie kanaal te kyk"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Druk Regs en voer jou PIN in om hierdie program te kyk"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Hierdie program is ongegradeer.\nDruk Regs en voer jou PIN in om hierdie program te kyk"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Hierdie program is <xliff:g id="RATING">%1$s</xliff:g> gegradeer.\nDruk Regs en voer jou PIN in om hierdie program te kyk."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Gebruik die verstekprogram vir Regstreekse TV om hierdie kanaal te kyk."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Gebruik die verstekprogram vir Regstreekse TV om hierdie program te kyk."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Hierdie program is ongegradeer.\nGebruik die verstekprogram vir Regstreekse TV om hierdie program te kyk."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Hierdie program is <xliff:g id="RATING">%1$s</xliff:g> gegradeer.\nGebruik die verstekprogram vir Regstreekse TV om hierdie kanaal te kyk."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Program is geblokkeer"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Hierdie program is ongegradeer"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Hierdie program is <xliff:g id="RATING">%1$s</xliff:g> gegradeer"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Net oudio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Swak sein"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Druk KIES"</b>" om na die TV-kieslys te gaan."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Geen TV-invoer gevind nie"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Kan nie die TV-invoer vind nie"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP word nie gesteun nie"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Daar is geen beskikbare invoer om met PIP te wys nie"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Instemmertipe is nie geskik nie. Begin asseblief die Live TV-program vir instemmertipe-TV-invoer."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Kon nie instel nie"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Geen program is gevind om hierdie handeling te behartig nie."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d opnames geskeduleer</item>
<item quantity="one">%1$d opname geskeduleer</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Kanselleer opname"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Stop opname"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Kyk"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Speel van begin af"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Speel verder"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"As daar te veel programme is wat op dieselfde tyd opgeneem moet word, sal net die programme met die hoër prioriteit opgeneem word."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Stoor"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Eenmalige opnames het die hoogste prioriteit"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Kanselleer"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Kanselleer"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Vergeet"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Stop"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Bekyk opnameskedule"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Net hierdie een program"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Neem eerder hierdie een op"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Kanselleer hierdie opname"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Kyk nou"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Vee opnames uit …"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Kan opgeneem word"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Opname geskeduleer"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Opneemkonflik"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Neem tans op"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Kon nie opneem nie"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Lees tans programme om opneemskedules te skep"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Leesprogramme"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Leesprogramme"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Bekyk onlangse opnames"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Die opname van <xliff:g id="PROGRAMNAME">%1$s</xliff:g> is nie volledig nie."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Die opnames van <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> en <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> is onvolledig."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Die opnames van <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> en <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> is onvolledig."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Die opname van <xliff:g id="PROGRAMNAME">%1$s</xliff:g> het nie klaargemaak nie weens onvoldoende bergingspasie."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Die opnames van <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> en <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> het nie klaargemaak nie weens onvoldoende bergingspasie."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Die opnames van <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> en <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> het nie klaargemaak nie weens onvoldoende bergingspasie."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR het meer berging nodig"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Jy sal programme met DVR kan opneem. DVR werk egter nie op die oomblik nie omdat daar nie genoeg berging op jou toestel beskikbaar is nie. Koppel asseblief \'n eksterne hardeskryf wat <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB of groter is en volg die stappe om dit as toestelberging te formateer."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Jy sal programme met DVR kan opneem. DVR werk egter nie op die oomblik nie omdat daar nie genoeg berging op jou toestel beskikbaar is nie. Koppel asseblief \'n eksterne hardeskryf wat <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB of groter is en volg die stappe om dit as toestelberging te formateer."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Te min bergingspasie"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Hierdie program sal nie opgeneem word nie omdat daar te min bergingspasie is. Probeer \'n paar bestaande opnames uitvee."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Berging ontbreek"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Van die berging wat DVR gebruik, ontbreek. Koppel asseblief die eksterne skyf wat jy vroeër gebruik het om DVR te heraktiveer. Andersins kan jy kies om die berging te vergeet as dit nie meer beskikbaar is nie."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Vergeet berging?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Al jou opgeneemde inhoud en skedules sal verloor word."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Stop opname?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Die opgeneemde inhoud sal gestoor word."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Die opname van <xliff:g id="PROGRAMNAME">%1$s</xliff:g> sal gestaak word omdat dit met hierdie program bots. Die inhoud wat opgeneem is, sal gestoor word."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Opname is geskeduleer, maar daar is botsings"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Opname het begin, maar daar is konflikte"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> sal opgeneem word."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Dieselfde program is reeds geskeduleer om om <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> opgeneem te word."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Reeds opgeneem"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Hierdie program is reeds opgeneem. Dit is in die DVR-biblioteek beskikbaar."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Reeksopname geskeduleer"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> opnames is geskeduleer vir <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opname is geskeduleer vir <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> opnames is geskeduleer vir <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> van hulle sal weens oorvleueling nie opgeneem word nie.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opname is geskeduleer vir <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Dit sal weens oorvleueling nie opgeneem word nie.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> opnames is geskeduleer vir <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodes van hierdie reeks en ander reekse sal weens oorvleueling nie opgeneem word nie.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opname is geskeduleer vir <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodes van hierdie reeks en ander reekse sal weens oorvleueling nie opgeneem word nie.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> opnames is geskeduleer vir <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 episode van \'n ander reeks sal weens oorvleueling nie opgeneem word nie.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opname is geskeduleer vir <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 episode van \'n ander reeks sal weens oorvleueling nie opgeneem word nie.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> opnames is geskeduleer vir <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodes van \'n ander reeks sal weens oorvleueling nie opgeneem word nie.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opname is geskeduleer vir <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodes van \'n ander reeks sal weens oorvleueling nie opgeneem word nie.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Kon nie opgeneemde program vind nie."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Verwante opnames"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Geen programbeskrywing nie)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d opnames</item>
<item quantity="one">%1$d opname</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Stop om reeks op te neem?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Opgeneemde episodes sal in die DVR-biblioteek beskikbaar bly."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Stop"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Geen episodes is tans op die lug nie."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Geen episodes is beskikbaar nie.\nHulle sal opgeneem word sodra hulle beskikbaar is."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minute)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Vandag <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Môre <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Telling"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Opgeneemde programme"</string>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index bd63879b..5b181215 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"ሞኖ"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"ስቲሪዮ"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"የማጫወቻ መቆጣጠሪያዎች"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"የቅርብ ጊዜ ሰርጦች"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"ሰርጦች"</string>
<string name="menu_title_options" msgid="7184594626814914022">"የቴሌቪዥን አማራጮች"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"የፒአይፒ አማራጮች"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"ለዚህ ሰርጥ የማጫወቻ መቆጣጠሪያዎች አይገኝም"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"አጫውት ወይም ለአፍታ አቁም"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"በፍጥነት አሳልፍ"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"የተዘጉ የስዕል መግለጫዎች"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"የማሳያ ሁኔታ"</string>
<string name="options_item_pip" msgid="3951350386626879645">"ፒአይፒ"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"በርቷል"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"ጠፍቷል"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"ባለብዙ ተሰሚ"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"ተጨማሪ ሰርጦችን ያግኙ"</string>
<string name="options_item_settings" msgid="7623205838542400074">"ቅንብሮች"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"ምንጭ"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"ማገላበጥ"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"በርቷል"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"ጠፍቷል"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"ድምፅ"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"ዋና"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"የፒአይፒ መስኮት"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"አቀማመጥ"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"ከታች በስተቀኝ"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"ከላይ በስተቀኝ"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"ከላይ በስተግራ"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"ከታች በስተግራ"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"ጎን ለጎን"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"መጠን"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"ትልቅ"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"ትንሽ"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"የግብዓት ምንጭ"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"ቴሌቪዥን (አንቴና/ገመድ)"</string>
<string name="no_program_information" msgid="1049844207745145132">"ምንም የፕሮግራም መረጃ የለም"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"ምንም መረጃ የለም"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"የታገደ ሰርጥ"</string>
- <string name="default_language" msgid="4122326459624337928">"ያልታወቀ ቋንቋ"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"ያልታወቀ ቋንቋ"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"ዝግ መግለጫ ጽሑፎች %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"የተዘጉ መግለጫ ጽሑፎች"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"ጠፍቷል"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"ቅርጸትን አብጅ"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"ኤስዲ"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"ሰብስብ በ"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"ይህ ፕሮግራም ታግዷል"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"ይህ ፕሮግራም ደረጃ ያልተሰጠው ነው"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"ይህ ፕሮግራም <xliff:g id="RATING">%1$s</xliff:g> ደረጃ ነው የተሰጠው"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"ግብዓቱ ራስ-ቃኝን አይደግፍም።"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"ለ«<xliff:g id="TV_INPUT">%s</xliff:g>» ራስ-ቃኝን መጀመር አልተቻለም"</string>
@@ -92,7 +74,6 @@
<item quantity="other">%1$d ሰርጦች ታክለዋል</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"ምንም ሰርጦች አልታከሉም"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ማስተካከያ"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"የወላጅ ቁጥጥሮች"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"በርቷል"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ጠፍቷል"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"ሌሎች አገሮች"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"ምንም"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ምንም"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"ደረጃ አልተሰጠውም"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"ደረጃ ያልተሰጣቸው ፕሮግራሞችን አግድ"</string>
<string name="option_rating_none" msgid="5204552587760414879">"ምንም"</string>
<string name="option_rating_high" msgid="8898400296730158893">"ከፍተኛ ገደቦች"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"መካከለኛ ገደቦች"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ይህን ሰርጥ ለመመልከት የእርስዎን ፒን ያስገቡ"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"ይህን ፕሮግራም ለመመልከት የእርስዎን ፒን ያስገቡ"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ይህ ፕሮግራም የ<xliff:g id="RATING">%1$s</xliff:g> ደረጃ ተሰጥቶታል። ይህን ፕሮግራም ለመመልከት የእርስዎን ፒን ያስገቡ።"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"ይህ ፕሮግራም ደረጃ ያልተሰጠው ነው። ይህን ፕሮግራም ለመከታተል የእርስዎን ፒን ያስገቡት።"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"የእርስዎን ፒን ያስገቡ"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"የወላጅ መቆጣጠሪያዎችን ለማዋቀር ፒን ይፍጠሩ።"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"አዲስ ፒን ያስገቡ"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"ይህ ፒን የተሳሳተ ነበር። እንደገና ይሞክሩ።"</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"እንደገና ይሞክሩ፣ ፒኑ አይዛመድም"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"ዚፕ ኮድዎን ያስገቡ።"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"የLive TV መተግበሪያ ለቴሌቪዥን ሰርጦቹ ሙሉ የፕሮግራም ዝርዝር ለማቅረብ ዚፕ ኮዱን ይጠቀማል።"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"ዚፕ ኮድዎን ያስገቡ"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"ልክ ያልኾነ ዚፕ ኮድ"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"ቅንብሮች"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"የሰርጥ ዝርዝር አብጅ"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ለፕሮግራሙ መመሪያዎ ሰርጦችን ይምረጡ"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"የሰርጥ ምንጮች"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"አዲስ ሰርጦች ይገኛሉ"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"የወላጅ መቆጣጠሪያዎች"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"የጊዜ ሽግሽግ"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"የቀጥታ ስርጭቶችን ባሉበት ለማቆም ወይም ለማጠንጠን እየተመለከቱ ሳለ ይቅረጹ።\nማስጠንቀቂያ፦ ይሄ ባለው ከፍተኛ የማከማቻ ፍጆታ ምክንያት የውስጣዊ ማከማቻ ዕድሜውን ሊቀንስ ይችላል።"</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"የክፍት ምንጭ ፍቃዶች"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"የክፍት ምንጭ ፍቃዶች"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"ግብረ ምላሽ ይላኩ"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"ስሪት"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"ይህን ሰርጥ ለመመልከት ቀኝን ይጫኑ እና የእርስዎን ፒን ያስገቡ"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"ይህን ፕሮግራም ለመመልከት ቀኝን ይጫኑ እና የእርስዎን ፒን ያስገቡ"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"ይህ ፕሮግራም ደረጃ ያልተሰጠው ነው።\nይህን ፕሮግራም ለመመልከት ቀኝን ይጫኑና የእርስዎን ፒን ያስገቡት"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"ይህ ፕሮግራም <xliff:g id="RATING">%1$s</xliff:g> ደረጃ ነው የተሰጠው።\nይህን ፕሮግራም ለመመልከት ቀኝን ይጫኑ እና የእርስዎን ፒን ያስገቡ።"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ይህን ሰርጥ ለመመልከት ነባሪውን የቀጥተኛ ቴሌቪዥን መተግበሪያ ይጠቀሙ።"</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ይህን ፕሮግራም ለመመልከት ነባሪውን የቀጥተኛ ቴሌቪዥን መተግበሪያ ይጠቀሙ።"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"ይህ ፕሮግራም ደረጃ ያልተሰጠው ነው።\nይህን ፕሮግራም ለመመልከት ነባሪውን የቀጥታ ቴሌቪዥን መተግበሪያ ይጠቀሙ።"</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ይህ ፕሮግራም የ<xliff:g id="RATING">%1$s</xliff:g> ደረጃ ነው የተሰጠው።\nይህን ፕሮግራም ለመመልከት ነባሪውን የቀጥተኛ ቴሌቪዥን መተግበሪያ ይጠቀሙ።"</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"ፕሮግራም ታግዷል"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"ይህ ፕሮግራም ደረጃ ያልተሰጠው ነው"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ይህ ፕሮግራም <xliff:g id="RATING">%1$s</xliff:g> ደረጃ ነው የተሰጠው"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"ኦዲዮ ብቻ"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"ደካማ ምልክት"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307">"የቴሌቪዥን ምናሌውን ለመድረስ "<b>"ምረጥን ይጫኑ"</b>"።"</string>
<string name="msg_no_input" msgid="3897674146985427865">"ምንም የቴሌቪዥን ግብዓት አልተገኘም"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"የቴሌቪዥን ግብዓቱን ማግኘት አልተቻለም"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"ፒአይፒ አይደገፍም"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"ከፒአይፒው ጋር አብሮ ሊታይ የሚችል ግቤት አይገኝም"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"የቃኚ አይነት ተገቢ አይደለም። እባክዎ የቃኚ አይነት ቴሌቪዥን ግብዓት ለማግኘት የቀጥተኛ ሰርጦች መተግበሪያውን ያስጀምሩት።"</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"መቃኘት አልተሳካም"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"ይህን እርምጃ የሚያከናውን ምንም መተግበሪያ አልተገኘም።"</string>
@@ -226,6 +217,8 @@
<item quantity="one">%1$d ቀረጻዎች በመርሐግብር ተይዘዋል</item>
<item quantity="other">%1$d ቀረጻዎች በመርሐግብር ተይዘዋል</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"መቅረጹን አስቀር"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"መቅረጽ አቁም"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"ይመልከቱ"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"ከመጀመሪያው አጫውት"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"ከቆመበት ቀጥል"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"በተመሳሳዩ ጊዜ ላይ የሚቀረጹ በጣም ብዙ ፕሮግራሞች ሲኖሩ ከፍ ያለ ቅድሚያ ያላቸው ብቻ ናቸው የሚቀረጹት።"</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"አስቀምጥ"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"የአንድ-ጊዜ ቀረጻዎች ከፍተኛ ቅድሚያ ተሰጭነት አላቸው"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"ይቅር"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"ተወው"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"እርሳ"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"አቁም"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"የምዝገባ መርሐግብርን ይመልከቱ"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"ይህ ነጠላ ፕሮግራም"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"በምትኩ ይሄኛውን ቅረጽ"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"ይህን ቀረጻ ተወው"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"አሁን ይመልከቱ"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"ቀረጻዎችን ሰርዝ…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"ሊቀረጽ የሚችል"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ቀረጻ መርሐግብር ተይዞለታል"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"የቀረጻ ግጭት"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"መቅዳት"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"መቅረጽ አልተሳካም"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"የቀረጻ መርሐግብሮችን ለመፍጠር ፕሮግራሞችን በማንበብ ላይ"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"ፕሮግራሞችን በማንበብ ላይ"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"ፕሮግራሞችን በማንበብ ላይ"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"የቅርብ ጊዜ ቅጂዎችን አሳይ"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"የ<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ቅጂ አልተጠናቀቀም።"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"የ<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> እና <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ቅጂዎች አልተጠናቀቁም።"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"የ<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>፣ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> እና <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ቅጂዎች አልተጠናቀቁም።"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"የ<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ቅጂ ባለው በቂ ያልሆነ ማከማቻ ምክንያት አልተጠናቀቀም።"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"የ<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> እና <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ቅጂዎች ባለው በቂ ያልሆነ ማከማቻ ምክንያት አልተጠናቀቁም።"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"የ<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>፣ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> እና <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ቅጂዎች ባለው በቂ ያልሆነ ማከማቻ ምክንያት አልተጠናቀቁም።"</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"ዲቪአር ተጨማሪ ማከማቻ ያስፈልገዋል"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"ፕሮግራሞችን በዲቪአር መቅረጽ ይችላሉ። ይሁንና አሁን ዲቪአር እንዲሰራ በመሣሪያዎ ላይ በቂ የማከማቻ ቦታ የለም። እባክዎ <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> ጊባ ወይም ከዚያ በላይ የሆነ ውጫዊ አንጻፊ ይሰኩና እንደ የመሣሪያ ማከማቻ ቅርጸት ለመስራት ያሉትን ደረጃዎች ይከተሉ።"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"ፕሮግራሞችን በዲቪአር መቅረጽ ይችላሉ። ይሁንና አሁን ዲቪአር እንዲሰራ በመሣሪያዎ ላይ በቂ የማከማቻ ቦታ የለም። እባክዎ <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> ጊባ ወይም ከዚያ በላይ የሆነ ውጫዊ አንጻፊ ይሰኩና እንደ የመሣሪያ ማከማቻ ቅርጸት ለመስራት ያሉትን ደረጃዎች ይከተሉ።"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"በቂ ማከማቻ የለም"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"በቂ ማከማቻ ስለሌለ ይህ ፕሮግራም አይቀረጽም። አሁን ያሉ አንዳንድ ቀረጻዎችን ለመሰረዝ ይሞክሩ።"</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"የሚጎድል ማከማቻ"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"በDVR ጥቅም ላይ የዋለ አንዳንድ ማከማቻ ይጎድላል። DVRን ዳግም ለማንቃት ከዚህ በፊት የሚጠቀሙበትን ውጫዊ አንጻፊ እባክዎ ያገናኙ። በአማራጭነት፣ ከእንግዲህ የማይገኝ ከሆነ ማከማቻውን ለመርሳት መምረጥ ይችላሉ።"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"ማከማቻ ይረሳ?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"ሁሉም የእርስዎ የተቀዳ ይዘት እና መርሐግብሮች ይጠፋሉ።"</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"መቅረጽ ይቁም?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"የተቀረጸው ይዘት ይቀመጣል።"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"የ<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ቀረጻ ከዚህ ፕሮግራም ጋር ስለሚጋጭ ይቆማል። የተቀረጸው ይዘት ይቀመጣል።"</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ምዝገባ መርሐግብር ተይዞለታል፣ ነገር ግን ግጭቶች አሉ"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ቀረጻ ተጀምሯል፣ ነገር ግን ግጭቶች አሉት"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ይቀረጻል።"</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"ተመሳሳዩ ፕሮግራም አስቀድሞ በ<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> ላይ እንዲቀረጽ መርሐግብር ተይዞለታል።"</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"አስቀድሞ ተቀርጿል"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ይህ ፕሮግራም አስቀድሞ ተቀርጿል። በዲቪአር ቤተ-መጽሐፍት ውስጥ ይገኛል።"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"የተከታታዮች ቀረጻ መርሐግብር ተይዞለታል"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ቀረጻዎች ለ<xliff:g id="SERIESNAME_3">%2$s</xliff:g> የጊዜ መርሐግብር ተይዞላቸዋል።</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ቀረጻዎች ለ<xliff:g id="SERIESNAME_3">%2$s</xliff:g> የጊዜ መርሐግብር ተይዞላቸዋል።</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ቀረጻዎች ለ<xliff:g id="SERIESNAME_3">%2$s</xliff:g> የጊዜ መርሐግብር ተይዞላቸዋል። ከእነሱ ውስጥ <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> በግጭቶች ምክንያት አይቀረጹም።</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ቀረጻዎች ለ<xliff:g id="SERIESNAME_3">%2$s</xliff:g> የጊዜ መርሐግብር ተይዞላቸዋል። ከእነሱ ውስጥ <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> በግጭቶች ምክንያት አይቀረጹም።</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ቀረጻዎች ለ<xliff:g id="SERIESNAME_4">%2$s</xliff:g> የጊዜ መርሐግብር ተይዞላቸዋል። <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> የዚህ ተከታታይ እና የሌሎች ተከታታዮች ትርዒት ክፍሎች በግጭቶች ምክንያት አይቀረጹም።</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ቀረጻዎች ለ<xliff:g id="SERIESNAME_4">%2$s</xliff:g> የጊዜ መርሐግብር ተይዞላቸዋል። <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> የዚህ ተከታታይ እና የሌሎች ተከታታዮች ትርዒት ክፍሎች በግጭቶች ምክንያት አይቀረጹም።</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ቀረጻዎች ለ<xliff:g id="SERIESNAME_3">%2$s</xliff:g> የጊዜ መርሐግብር ተይዞላቸዋል። 1 የሌሎች ተከታታዮች የትርዒት ክፍል በግጭት ምክንያት አይቀረጽም።</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ቀረጻዎች ለ<xliff:g id="SERIESNAME_3">%2$s</xliff:g> የጊዜ መርሐግብር ተይዞላቸዋል። 1 የሌሎች ተከታታዮች የትርዒት ክፍል በግጭት ምክንያት አይቀረጽም።</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ቀረጻዎች ለ<xliff:g id="SERIESNAME_4">%2$s</xliff:g> የጊዜ መርሐግብር ተይዞላቸዋል። <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> የሌላ ተከታታይ የትዕይንት ክፍሎች በግጭቶች ምክንያት አይቀረጹም።</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ቀረጻዎች ለ<xliff:g id="SERIESNAME_4">%2$s</xliff:g> የጊዜ መርሐግብር ተይዞላቸዋል። <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> የሌላ ተከታታይ የትዕይንት ክፍሎች በግጭቶች ምክንያት አይቀረጹም።</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"የተቀረጸ ፕሮግራም አልተገኘም።"</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ተዛማጅ ቀረጻዎች"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(ምንም የፕሮግራም መግለጫ የለም)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d ቀረጻዎች</item>
<item quantity="other">%1$d ቀረጻዎች</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"የተከታታይ ቀረጻ ይቆም?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"የተቀረጹ ክፍሎች በዲቪአር ቤተ-መጽሐፍቱ ላይ የሚገኙ እንደሆኑ ይቆያሉ።"</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"አቁም"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ምንም ተከታታይ የትዕይንት ክፍሎች የሉም።"</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ምንም ክፍሎች አይገኙም።\nልክ የሚገኙ ሲሆኑ ይቀረጻሉ።"</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d ደቂቃዎች)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ዛሬ"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ነገ"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"ነጥብ"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"የተቀረጹ ፕሮግራሞች"</string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index f91139b9..a1b47209 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"أحادية"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"ستيريو"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"عناصر التحكم في التشغيل"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"أحدث القنوات"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"القنوات"</string>
<string name="menu_title_options" msgid="7184594626814914022">"خيارات التلفزيون"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"‏خيارات PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"عناصر تحكم التشغيل غير متاحة لهذه القناة"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"تشغيل الفيديو أو إيقافه مؤقتًا"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"تقديم سريع"</string>
@@ -32,40 +31,22 @@
<string name="channels_item_program_guide" msgid="2889807207930678418">"دليل البرامج"</string>
<string name="channels_item_setup" msgid="6557412175737379022">"تتوفر قنوات جديدة"</string>
<string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"فتح <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"التسميات التوضيحية المغلقة"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"الترجمة والشرح"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"وضع العرض"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"تشغيل"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"إيقاف"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"إعدادات صوتية متعددة"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"جلب قنوات أخرى"</string>
<string name="options_item_settings" msgid="7623205838542400074">"الإعدادات"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"المصدر"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"تبديل"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"تشغيل"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"إيقاف"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"الصوت"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"الرئيسي"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"‏نافذة PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"التنسيق"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"أسفل اليمين"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"أعلى اليمين"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"أعلى اليسار"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"أسفل اليسار"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"جنبًا إلى جنب"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"الحجم"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"كبيرة"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"صغيرة"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"مصدر الإدخال"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"تلفزيون (هوائي/كابل)"</string>
<string name="no_program_information" msgid="1049844207745145132">"لا تتوفّر معلومات عن البرنامج"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"لا توجد معلومات"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"القناة المحظورة"</string>
- <string name="default_language" msgid="4122326459624337928">"لغة غير معروفة"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"التسميات التوضيحية المغلقة"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"لغة غير معروفة"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"‏مقاطع ترجمة وشرح %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"الترجمة والشرح"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"إيقاف"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"تخصيص التنسيق"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"تعيين التفضيلات عبر النظام للتسميات التوضيحية المغلقة"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"تعيين التفضيلات عبر النظام للترجمة والشرح"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"وضع العرض"</string>
<string name="side_panel_title_multi_audio" msgid="5970537894780855080">"إعدادات صوتية متعددة"</string>
<string name="multi_audio_channel_mono" msgid="6229173848963557723">"أحادية"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"دقة قياسية"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"تجميع بحسب"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"تم حظر هذا البرنامج"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"لم يتم تقييم هذا البرنامج"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"تم تصنيف هذا البرنامج على أنه <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"الإدخال ليس متوافقًا مع الفحص التلقائي"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"تعذر بدء البحث التلقائي في \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
@@ -96,7 +78,6 @@
<item quantity="one">‏تمت إضافة %1$d قناة</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"لم تتم إضافة قنوات"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"موالف"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"عناصر التحكم الأبوي"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"تشغيل"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"إيقاف"</string>
@@ -112,6 +93,8 @@
<string name="other_countries" msgid="8342216398676184749">"بلدان أخرى"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"لا شيء"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"لا شيء"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"غير مقيَّم"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"حظر البرامج غير المقيَّمة"</string>
<string name="option_rating_none" msgid="5204552587760414879">"لا شيء"</string>
<string name="option_rating_high" msgid="8898400296730158893">"قيود مرتفعة"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"قيود متوسّطة"</string>
@@ -128,6 +111,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"أدخل رقم التعريف الشخصي لمشاهدة هذه القناة"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"أدخل رقم التعريف الشخصي لمشاهدة هذا البرنامج"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"هذا البرنامج يحمل التقييم <xliff:g id="RATING">%1$s</xliff:g>. يمكنك إدخال رقم التعريف الشخصي لمشاهدة هذا البرنامج"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"لم يتم تقييم هذا البرنامج. أدخل رقم التعريف الشخصي لمشاهدة هذا البرنامج"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"أدخل رقم التعريف الشخصي"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"لتعيين عناصر التحكم الأبوي، عليك إنشاء رقم تعريف شخصي"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"إدخال رقم تعريف شخصي جديد"</string>
@@ -143,22 +127,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"رقم التعريف الشخصي هذا خاطئ. أعد المحاولة."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"أعد المحاولة، رقم التعريف الشخصي غير مطابق"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"أدخل الرمز البريدي."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"‏سيستخدم تطبيق Live TV الرمز البريدي لتوفير دليل برامج كامل لقنوات التلفزيون."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"أدخل الرمز البريدي"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"الرمز البريدي غير صالح"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"الإعدادات"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"تخصيص قائمة قنوات"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"اختر القنوات الخاصة بدليل البرامج."</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"مصادر القنوات"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"تتوفر قنوات جديدة."</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"أدوات الرقابة الأبوية"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"الانتقال الزمني"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"يمكنك التسجيل أثناء المشاهدة حتى يتسنى لك إيقاف بث البرامج المباشرة مؤقتًا أو إرجاع البث إلى أوقات سابقة.\nتحذير: قد يؤدي هذا إلى استهلاك مكثّف لمساحة وحدة التخزين الداخلية؛ ما يؤدي إلى نفادها في فترة قصيرة."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"تراخيص البرامج المفتوحة المصدر"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"تراخيص البرامج المفتوحة المصدر"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"إرسال تعليقات"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"الإصدار"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"لمشاهدة هذه القناة، اضغط على اليمين وأدخل رقم التعريف الشخصي"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"لمشاهدة هذا البرنامج، اضغط على اليمين وأدخل رقم التعريف الشخصي"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"لم يتم تقييم هذا البرنامج.\nلمشاهدة هذا البرنامج، اضغط على اليمين وأدخل رقم التعريف الشخصي"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"تم تصنيف هذا البرنامج على أنه <xliff:g id="RATING">%1$s</xliff:g>.\nلمشاهدة هذا البرنامج، اضغط على اليمين وأدخل رقم التعريف الشخصي."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"‏لمشاهدة هذه القناة، يمكنك استخدام تطبيق Live TV الافتراضي."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"‏لمشاهدة هذا البرنامج، يمكنك استخدام تطبيق Live TV الافتراضي."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"‏لم يتم تقييم هذا البرنامج.\nلمشاهدة هذا البرنامج، استخدم تطبيق Live TV الافتراضي."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"‏هذا البرنامج يحمل التقييم <xliff:g id="RATING">%1$s</xliff:g>.\nلمشاهدة هذا البرنامج، يمكنك استخدام تطبيق Live TV الافتراضي."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"البرنامج محظور"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"لم يتم تقييم هذا البرنامج"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"تم تصنيف هذا البرنامج على أنه <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"الصوت فقط"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"الإشارة ضعيفة"</string>
@@ -197,10 +190,8 @@
<string name="intro_description" msgid="7806473686446937307">"‏"<b>"اضغط على \"تحديد\""</b>" للوصول إلى قائمة TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"لم يتم العثور على إدخال تلفزيون"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"لا يمكن العثور على إدخال تلفزيون"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"‏خدمة PIP ليست متوافقة"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"‏ليس هناك إدخال متاح يمكن عرضه باستخدام PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"نوع الموالف غير مناسب، لذلك يُرجى تشغيل تطبيق القنوات المباشرة لنوع الموالف إدخال التلفزيون."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"أخفق التوليف"</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"تعذّر التوليف"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"لم يتم العثور على تطبيق يمكنه مباشرة هذا الإجراء."</string>
<string name="msg_all_channels_hidden" msgid="777397634062471936">"كل قنوات المصدر مخفية.\nحدد على الأقل قناة واحدة لمشاهدتها."</string>
<string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"الفيديو غير متوفر بشكل مفاجئ"</string>
@@ -262,6 +253,8 @@
<item quantity="other">‏%1$d تسجيل حسب جدول زمني</item>
<item quantity="one">‏%1$d تسجيل حسب جدول زمني</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"إلغاء التسجيل"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"إيقاف التسجيل"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"مشاهدة"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"تشغيل من البداية"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"استئناف التشغيل"</string>
@@ -298,9 +291,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"عندما تكون هناك برامج كثيرة جدًا مطلوب تسجيلها في آنٍ واحد، فلن يتم تسجيل أي برامج منها إلا تلك ذات القدر الأعلى من الأولوية فقط."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"حفظ"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"تسجيلات المرة الواحدة لها الأولوية القصوى"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"إلغاء"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"إلغاء"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"حذف"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"إيقاف"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"عرض جدول عمليات التسجيل الزمني"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"هذا البرنامج وحده"</string>
@@ -310,25 +300,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"تسجيل هذا بدلاً من ذلك"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"إلغاء هذا التسجيل"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"المشاهدة الآن"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"حذف التسجيلات…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"قابل للتسجيل"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"تمتّ جدولة التسجيل"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"تعارض في التسجيل"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"جارٍ التسجيل"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"أخفق التسجيل"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"جارٍ قراءة البرامج لإنشاء جداول زمنية للتسجيل"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"جارٍ قراءة البرامج"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"تعذّر التسجيل"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"جارٍ قراءة البرامج"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"عرض التسجيلات الأخيرة"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"لم يكتمل تسجيل <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"لم يكتمل تسجيل كل من <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> و<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"لم يكتمل تسجيل كل من <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> و<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> و<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"لم يكتمل تسجيل <xliff:g id="PROGRAMNAME">%1$s</xliff:g> نظرًا لأن سعة التخزين غير كافية."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"لم يكتمل تسجيل كل من <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> و<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> نظرًا لأن سعة التخزين غير كافية."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"لم يكتمل تسجيل كل من <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> و<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> و<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> نظرًا لأن سعة التخزين غير كافية."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"يحتاج مسجِّل الفيديو الرقمي إلى المزيد من السعة التخزينية"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"ستتمكن من تسجيل البرامج باستخدام مسجّل الفيديو الرقمي؛ ولكن ليست هناك سعة تخزينية كافية على جهازك الآن ليعمل مسجِّل الفيديو الرقمي. يُرجى توصيل محرك أقراص خارجي بسعة تخزين <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>غيغابايت أو أكبر واتباع الخطوات لتهيئته كوحدة تخزين للجهاز."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"ستتمكن من تسجيل البرامج باستخدام مسجّل الفيديو الرقمي؛ ولكن ليست هناك سعة تخزينية كافية على جهازك الآن ليعمل مسجِّل الفيديو الرقمي. يُرجى توصيل محرك أقراص خارجي بسعة تخزين <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>غيغابايت أو أكبر واتباع الخطوات لتهيئته كوحدة تخزين للجهاز."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"السعة التخزينية غير كافية"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"لن يتم تسجيل هذا البرنامج لأنه ليست هناك سعة تخزين كافية. جرِّب حذف بعض التسجيلات الحالية."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"سعة التخزين المفقودة"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"‏بعض سعة التخزين المستخدمة في جهاز DVR مفقود. يُرجى توصيل محرك الأقراص الخارجي الذي سبق لك استخدامه لإعادة تمكين جهاز DVR. بدلاً من ذلك، يمكنك اختيار حذف سعة التخزين إذا لم تعد متاحة."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"هل تريد حذف سعة التخزين؟"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"سيتم فقد جميع المحتويات والجداول الزمنية المسجَّلة."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"هل تريد إيقاف التسجيل؟"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"سيتم حفظ المحتوى الذي تم تسجيله."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"سيتم إيقاف تسجيل <xliff:g id="PROGRAMNAME">%1$s</xliff:g> لأنه يتعارض مع هذا البرنامج. وسيتم حفظ المحتوى الذي تم تسجيله."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"تمت إضافة جدول زمني لإجراء التسجيل ولكنه يتعارض مع جداول زمنية أخرى"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"تم بدء التسجيل ولكنه يتعارض مع جداول زمنية أخرى"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"لن يتم تسجيل <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
@@ -350,17 +343,49 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"تم إعداد جدول زمني من قبل لتسجيل البرنامج نفسه في <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"تم التسجيل من قبل"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"‏تم تسجيل هذا البرنامج من قبل. وسيكون متاحًا في مكتبة DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"تمت جدولة تسجيل المسلسل"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="zero">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيل لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="two">تمت جدولة تسجيلين (<xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>) لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="few">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيلات لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="many">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيلاً لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيل لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one">تمت جدولة تسجيل واحد (<xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g>) لمسلسل <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="zero">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيل لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> من الحلقات بسبب تعارض المواعيد.</item>
+ <item quantity="two">تمت جدولة تسجيلين (<xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>) لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> من الحلقات بسبب تعارض المواعيد.</item>
+ <item quantity="few">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيلات لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> من الحلقات بسبب تعارض المواعيد.</item>
+ <item quantity="many">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيلاً لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> من الحلقات بسبب تعارض المواعيد.</item>
+ <item quantity="other">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيل لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> من الحلقات بسبب تعارض المواعيد.</item>
+ <item quantity="one">تمت جدولة تسجيل واحد (<xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g>) لمسلسل <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. ولن يتم إجراء هذا التسجيل بسبب تعارض المواعيد.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="zero">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> تسجيل لمسلسل <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> من حلقات هذا المسلسل والمسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="two">تمت جدولة تسجيلين (<xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>) لمسلسل <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> من حلقات هذا المسلسل والمسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="few">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> تسجيلات لمسلسل <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> من حلقات هذا المسلسل والمسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="many">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> تسجيلاً لمسلسل <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> من حلقات هذا المسلسل والمسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="other">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> تسجيل لمسلسل <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> من حلقات هذا المسلسل والمسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="one">تمت جدولة تسجيل واحد (<xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g>) لمسلسل <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> من حلقات هذا المسلسل والمسلسل الآخر بسبب تعارض المواعيد.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="zero">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيل لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. ولن يتم تسجيل حلقة واحدة من المسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="two">تمت جدولة تسجيلين (<xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>) لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. ولن يتم تسجيل حلقة واحدة من المسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="few">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيلات لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. ولن يتم تسجيل حلقة واحدة من المسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="many">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيلاً لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. ولن يتم تسجيل حلقة واحدة من المسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="other">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> تسجيل لمسلسل <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. ولن يتم تسجيل حلقة واحدة من المسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="one">تمت جدولة تسجيل واحد (<xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g>) لمسلسل <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. ولن يتم تسجيل حلقة واحدة من المسلسل الآخر بسبب تعارض المواعيد.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="zero">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> تسجيل لمسلسل <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> من حلقات المسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="two">تمت جدولة تسجيلين (<xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>) لمسلسل <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> من حلقات المسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="few">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> تسجيلات لمسلسل <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> من حلقات المسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="many">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> تسجيلاً لمسلسل <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> من حلقات المسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="other">تمت جدولة <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> تسجيل لمسلسل <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> من حلقات المسلسل الآخر بسبب تعارض المواعيد.</item>
+ <item quantity="one">تمت جدولة تسجيل واحد (<xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g>) لمسلسل <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. ولن يتم تسجيل <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> من حلقات المسلسل الآخر بسبب تعارض المواعيد.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"لم يتم العثور على البرنامج المُسّجل"</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"تسجيلات ذات صلة"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(لا يتوفر وصف للبرنامج)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="zero">‏%1$d تسجيل</item>
<item quantity="two">‏تسجيلان (%1$d)</item>
@@ -388,6 +413,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"هل تريد إيقاف تسجيل السلسلة؟"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"‏ستظل الحلقات المسجّلة متاحة في مكتبة DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"إيقاف"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ليست هناك حلقات يتم بثها على الهواء حاليًا."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"لا تتوفر أي حلقات.\nسيتم تسجيلها بعد توفرها."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="zero">‏(%1$d دقيقة)</item>
@@ -403,4 +429,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> اليوم"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> غدًا"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"النتيجة"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"البرامج المسجّلة"</string>
</resources>
diff --git a/res/values-az/arrays.xml b/res/values-az-rAZ/arrays.xml
index 7f891617..7f891617 100644
--- a/res/values-az/arrays.xml
+++ b/res/values-az-rAZ/arrays.xml
diff --git a/res/values-az/rating_system_strings.xml b/res/values-az-rAZ/rating_system_strings.xml
index bd28a4e8..bd28a4e8 100644
--- a/res/values-az/rating_system_strings.xml
+++ b/res/values-az-rAZ/rating_system_strings.xml
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
new file mode 100644
index 00000000..7fe8ae8e
--- /dev/null
+++ b/res/values-az-rAZ/strings.xml
@@ -0,0 +1,359 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Oyun kontrolu"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanallar"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"TV seçənəkləri"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Oxutma idarə elementləri bu kanal üçün əlçatan deyil"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Oxudun və ya durdurun"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Sürətlə irəli"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Geri qayıdın"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Növbəti"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Əvvəlki"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Proqram Təlimatı"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Yeni əlçatan kanallar"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqini açın"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Qapalı başlıqlar"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Ekran rejimi"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Daha çox kanal əldə edin"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Ayarlar"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/kabel)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"No proqram informasiya"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Məlumat yoxdur"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"bloklanmış kanallar"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Naməlum dil"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Subtitr %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Qapalı başlıqlar"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Deaktiv"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Formatı fərdiləşdirin"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Qapalı başlıqlar üçün daxili sistem tərcihlərini ayarlayın"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Ekran rejimi"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multi-audio"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"Mono"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"Stereo"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 Əhatəli"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 Əhatəli"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for multi_audio_channel_suffix (4443825738196093772) -->
+ <skip />
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Kanal siyahısını fərdiləşdirin"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Qrup seçin"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Qrupu silin"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Qruplaşdırın"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Kanal mənbəyi"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Qruplaşdırın"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Bu proqram bloklanıb."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Bu proqram reytinqsizdir"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Bu proqram <xliff:g id="RATING">%1$s</xliff:g> ilə qiymətləndirilib."</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Daxiletmə avto-skanı dəstəkləmir"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' üçün avto-skanı başlatmaq olmur"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Qapalı mövzular üçün sistem tərcihlərini başlatmaq olmur."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d kanal əlavə edildi</item>
+ <item quantity="one">%1$d kanal əlavə edildi</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Kanal əlavə edilmədi"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Valideyn nəzarəti"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Aktiv"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Deaktiv"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Kanallar bloklanıb"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Hamısını bloklayın"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Hamısını blokdan çıxarın"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Gizli kanallar"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Proqram məhdudiyyətləri"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN kodu dəyişin"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Reytinq sistemləri"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Ratings"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Bütün reytinq sistemlərinə baxın"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Digər ölkələr"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Heç bir"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Heç bir"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Reytinqsiz"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Reytinqsiz proqramları blok edin"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Heç bir"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Yüksək məhdudiyyətlər"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Orta məhdudiyyətlər"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Aşağı məhdudiyyətlər"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Fərdi"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Uşaqlar üçün uyğun məzmun"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Böyük uşaqlar üçün uyğun məzmun"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Yeniyetmələr üçün uyğun məzmun"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Manual məhdudiyyətlər"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s və sub-reytinqlər"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Alt-reytinqlər"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Bu kanalı izləmək üçün PİN kodunuzu daxil edin"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Bu proqramı izləmək üçün PİN kodunuzu daxil edin"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Bu proqram <xliff:g id="RATING">%1$s</xliff:g> ilə qiymətləndirilib. Bu proqramı izləmək üçün PİN kodunuzu daxil edin"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Bu proqram reytinqsizdir. Bu proqramı izləmək üçün PIN\'i daxil edin"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"PİN kodunuzu daxil edin"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Valideyn nəzarəi yaratmaq üçün PİN yaradın"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Yeni PIN kodu daxil edin"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"PİN kodunuzu təsdiq edin"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Cari PİN kodu daxil edin"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Yanlış PİN kodu 5 dəfə daxil etdiniz.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> saniyə sonra yenidən cəhd edin.</item>
+ <item quantity="one">Yanlış PİN kodu 5 dəfə daxil etdiniz.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> saniyə sonra yenidən cəhd edin.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"Həmin PİN kod səhv idi. Yenidən cəhd edin."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Yenidən cəhd edin, PİN uyğun deyil"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Poçt İndeksi daxil edin."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Canlı Kanal tətbiqi TV kanallarını tam proqram təlimatı ilə təmin etmək üçün Poçt İndeksi istifadə edəcək."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Poçt İndeksi daxil edin"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Yanlış Poçt İndeksi"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Ayarlar"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Kanal siyahısını fərdiləşdirin"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Proqram təlimatınız üçün kanal seçin"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanal mənbələri"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Yeni əlçatan kanallar"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Valideyn nəzarəti"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Zaman keçidi"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"İzləyərkən qeyd edin, beləliklə canlı proqramlara fasilə verə və ya geri sara bilərsiniz.\nXəbərdarlıq: İnstensiv yaddaş istifadəsi daxili yaddaşı azalda bilər."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Açıq mənbə lisenziyaları"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Cavab rəyi göndərin"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versiya"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Bu kanalı izləmək üçün Sağa basın və PİN kodunuzu daxil edin"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Bu proqramı izləmək üçün Sağa basın və PİN kodunuzu daxil edin"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Bu proqram reytinqsizdir.\nBu proqramı izləmək üçün Right düyməsini basın və PIN kodu daxil edin"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Bu proqram <xliff:g id="RATING">%1$s</xliff:g> ilə qiymətləndirilib.\nBu proqramı izləmək üçün Sağa basın və PİN kodunuzu daxil edin."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Bu kanalı izləmək üçün defolt Live TV tətbiqini istifadə edin."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Bu proqramı izləmək üçün defolt Live TV tətbiqini istifadə edin."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Bu proqram reytinqsizdir.\nBu proqramı izləmək üçün defolt Live TV tətbiqindən istifadə edin."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Bu proqram <xliff:g id="RATING">%1$s</xliff:g> ilə qiymətləndirilib. \n Bu proqramı izləmək üçün defolt Live TV tətbiqini istifadə edin."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Proqram blok edilib"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Bu proqram reytinqsizdir"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Bu proqram <xliff:g id="RATING">%1$s</xliff:g> ilə qiymətləndirilib."</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Yalnız Audio"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Zəif siqnal"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"İnternet bağlantısı yoxdur"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">Bu kanal <xliff:g id="END_TIME_1">%1$s</xliff:g> radələrinə kimi fəaliyyət göstərə bilməz, cünki, digər kanallar qeydə alınır \n\nQeydə alma cədvəlini nizamlamaq üçün Sağı basın.</item>
+ <item quantity="one">Digər kanal qeydə alındığı üçün bu kanal <xliff:g id="END_TIME_0">%1$s</xliff:g> radələrinə kimi fəaliyyət göstərə bilməz. \n\nQeydə alma cədvəlini nizamlamaq üçün Sağı basın.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Başlıq yoxdur"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal blok edilib"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Yeni"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Mənbələr"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d kanal</item>
+ <item quantity="one">%1$d kanal</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Əlçatan kanal yoxdur"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Yeni"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Quraşdırılmayıb"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Əlavə mənbə əldə edin"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Canlı kanallar təklif edən tətbiqlər axtarın"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Yeni kanal mənbələri əlçatandır"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Yeni kanal mənbələrinin kanal təklifləri var.\nOnları indi ayarlayın, və ya daha sonra kanal mənbələri ayarından edin."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"İndi ayarlayın"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Ok, oldu."</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"TV menyusuna giriş üçün "<b>"SEÇİN basın"</b>"."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"TV daxiletmə tapılmadı"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"TV daxiletmə tapılmır"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Sazlama növü uyğun deyil. TV daxiletmə sazlama növü üçün Canlı Kanallar tətbiqini işə salın."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Sazlama alınmadı"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Bu əməliyyatı idarə etmək üçün heç bir tətbiq tapılmadı."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Bütün mənbə kanalları gizlədilib.\nİzləmək üçün ən azı bir kanal seçin."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Bu video gözlənilmədən əlçatmazdır"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"Geri düyməsi qoşulu cihazlar üçündür. Çıxmaq üçün ƏSAS SƏHİFƏ düyməsini basın."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Canlı Kanallar TV siyahıları oxumaq üçün icazə istəyir."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Mənbələrinizi quraşdırın"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Canlı kanallar tətbiq tərəfindən yayımlanan kanallar ilə ənənəvi TV kanallarının təcrübəsini özündə birləşdirir. \n\n Artıq yüklənmiş kanal mənbələrini quraşdıraraq başlayın. Və ya canlı kanallar təklif edən bir neçə tətbiq üçün Google Play Store\'da axtarış edin."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Qeydə almalar və cədvəllər"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 dəqiqə"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 dəqiqə"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 saat"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 saat"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Son"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Planlaşdırılıb"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Seriyalar"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Digərləri"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Kanal qeydə alına bilməz."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Proqram qeydə alına bilməz."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> tətbiqinin qeydə alınması üçün vaxt təyin edilib"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> bu dəqiqədən etibarən <xliff:g id="ENDTIME">%2$s</xliff:g> radələrinə kimi deydə alınır"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Tam cədvəl"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">Növbəti %1$d gün</item>
+ <item quantity="one">Növbəti %1$d gün</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d dəqiqə</item>
+ <item quantity="one">%1$d dəqiqə</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d yeni qeydə alma</item>
+ <item quantity="one">%1$d yeni qeydə alma</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d qeydə alma</item>
+ <item quantity="one">%1$d qeydə alma</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d qeydə alma təyin edildi</item>
+ <item quantity="one">%1$d qeydə alma təyin edildi</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Qeyd etməni ləğv edin"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Qeyd etməyi dayandırın"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"İzləyin"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Əvvəldən oxudun"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Oxutmağa davam edin"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Silin"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Qeydə almaları silin"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Davam edin"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g> mövsüm"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Cədvələ baxın"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Ətraflı məlumat"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Qeydə almaları silin"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Silmək istədiyiniz epizodları seçin. Silinənlər bərpa oluna bilməz."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Silinmək üçün heç bir qeydə alma yoxdur."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Baxılmış epizodları seçin"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Bütün epizodları seçin"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Bütün epizodların seçimlərini qaldırın"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> müddətdən <xliff:g id="WATCHED">%1$d</xliff:g> dəqiqəsinə baxıldı"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> müddətdən <xliff:g id="WATCHED">%1$d</xliff:g> saniyəsinə baxıldı"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Heç vaxt baxılmayıb"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%2$d epizoddan %1$d epizod silindi</item>
+ <item quantity="one">%2$d epizoddan %1$d epizod silindi</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Prioritet"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Ən yüksək"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Ən alçaq"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Yox. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Kanallar"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Hər hansı"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Prioriteti seçin"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Eyni anda qeydə alınacaq bir neçə proqram olduqda, yalnız vacib olanlar qeydə alınacaq."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Yadda saxlayın"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Bir dəfəlik qeydiyyatlar yüksək prioritetlidir"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Dayandırın"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Qeydiyyat cədvəlinə baxın"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Tək bu proqram"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"indi - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Bütün seriyalar…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"İstənilən halda vaxt təyin edin"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Əvəzinə bunu qeydə alın"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Bu qeydə almanı ləğv edin"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"İndi baxın"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Qeydə almaları silin..."</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Qeydə alınabilən"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Qeydiyyat planlaşdırılıb"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Qeydiyyat münaqişəsi"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Qeydə alınır"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Qeydə alma uğursuz oldu"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Oxuma proqramları"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Son yazılara baxın"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> qeydə alınması tamamlanmadı."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> və <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> qeydə alınması tamamlanmadı."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> və <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> qeydə alınması tamamlanmadı."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Yetərsiz yaddaş səbəbi ilə <xliff:g id="PROGRAMNAME">%1$s</xliff:g> qeydə alınması tamamlanmadı."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Yetərsiz yaddaş səbəbi ilə <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> və <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> qeydə alınması tamamlanmadı."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Yetərsiz yaddaş səbəbi ilə <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> və <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> qeydə alınması tamamlanmadı."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR üçün əlavə yaddaş tələb olunur"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR ilə proqram qeydə ala biləcəksiniz. Hazırda DVR-ın işləməsi üçün cihazda kifayət qədər yaddaş yoxdur. <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB və ya daha böyük həcmli xarici yaddaşı qoşun və cihaz yaddaşı olaraq format etmək üçün mərhələlərə riayət edin."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Kifayət qədər yer yoxdur"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Kifayət qədər boş yer olmadığı üçün bu proqram qeydə alınmayacaq. Bəzi mövcud qeydə almaları silməyə çalışın."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Yaddaş catışmır"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Qeydetmə dayandırılsın?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Qeydə alınan məzmun yadda saxlanacaq."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Bu proqram ilə ziddiyyəti olduğu üçün <xliff:g id="PROGRAMNAME">%1$s</xliff:g> proqramının qeydə alınması dayandırılacaq. Qeydə alınmış məzmun yadda saxlanacaq."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Qeydiyyat vaxtı təyin edilib lakin ziddiyətlər var"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Qeydə alma başladı, lakin ziddiyətlər var."</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> qeydə alınacaq."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> qeydə alındı."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> tətbiqinin bəzi hissələri qeydə alınmayacaq."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> və <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> tətbiqlərinin bəzi hissələri qeydə alınmayacaq."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> tətbiqlərinin bəzi hissələri və daha bir cədvəl qeydə alınmayacaq."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> tətbiqlərinin bəzi hissələri və daha %3$d cədvəl qeydə alınmayacaq.</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> tətbiqlərinin bəzi hissələri və daha %3$d cədvəl qeydə alınmayacaq.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Qeydə almaq istəyirsiniz?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Nə qədər müddətə qeydə almaq istəyirsiniz?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Artıq vaxt təyin edilib"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Eyni proqramın qeydə alınması üçün artıq <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> radələrində vaxt təyin edilib."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Artıq qeydə alınıb"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Bu proqram artıq qeydə alınıb. O, DVR kitabxanasında əlçatandır."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Seriyaların qeydiyyatı planlaşdırıldı"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> qeydə alma <xliff:g id="SERIESNAME_3">%2$s</xliff:g> üçün təyin edildi.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> qeydə alma <xliff:g id="SERIESNAME_1">%2$s</xliff:g> üçün təyin edildi.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> qeydə alma <xliff:g id="SERIESNAME_3">%2$s</xliff:g> üçün təyin edildi. Onlardan <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> ədədi ziddiyyət səbəbilə qəydə alınmayacaq.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> qeydə alma <xliff:g id="SERIESNAME_1">%2$s</xliff:g> üçün təyin edildi. Bu, ziddiyyət səbəbilə qəydə alınmayacaq.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> qeydə alma <xliff:g id="SERIESNAME_4">%2$s</xliff:g> üçün təyin edildi. Bu seriyaların <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> epizodu və digər seriyalar ziddiyyət səbəbilə qeydə alınmayacaq.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> qeydə alma <xliff:g id="SERIESNAME_1">%2$s</xliff:g> üçün təyin edildi. Bu seriyaların <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> epizodu və digər seriyalar ziddiyyət səbəbilə qeydə alınmayacaq.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> qeydə alma <xliff:g id="SERIESNAME_3">%2$s</xliff:g> üçün təyin edildi. Digər seriyaların 1 epizodu ziddiyyət səbəbilə qeydə alınmayacaq.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> qeydə alma <xliff:g id="SERIESNAME_1">%2$s</xliff:g> üçün təyin edildi. Digər seriyaların 1 epizodu ziddiyyət səbəbilə qeydə alınmayacaq.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> qeydə alma <xliff:g id="SERIESNAME_4">%2$s</xliff:g> üçün təyin edildi. Digər seriyaların <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> epizodu ziddiyyət səbəbilə qeydə alınmayacaq.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> qeydə alma <xliff:g id="SERIESNAME_1">%2$s</xliff:g> üçün təyin edildi. Digər seriyaların <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> epizodu ziddiyyət səbəbilə qeydə alınmayacaq.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Qeyd edilmiş proqram tapılmadı."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Əlaqədar qeydetmələr"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d qeyd etmə</item>
+ <item quantity="one">%1$d qeyd etmə</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> qeyd cədvəlindən çıxarıldı"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Kökləyici ziddiyətləri səbəbi ilə qismən qeydə alınacaq."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Kökləyici ziddiyətləri səbəbi ilə qeydə alınmacaq."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Hələ ki cədvəldə heç bir qeydə alma yoxdur.\nProqram bələdçisindən qeydə alma üçün vaxt təyin edə bilərsiniz."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d qeydə alma münaqişəsi</item>
+ <item quantity="one">%1$d qeydə alma münaqişəsi</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Davamlılıq ayarları"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Ardıcıl qeydə almanı başladın"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Ardıcıl qeydə alma dayandırılsın"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Ardıcıl qeydə alma dayandırılsın?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Qeydə alınmış epizodlar DVR kitabxanasında əlçatan olacaq."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Dayandırın"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Heç bir epizod indi canlı yayımda deyil."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Heç bir epizod əlçatan deyil.\nOnlar, əlçatan olduqda qeydə alınacaq."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d dəqiqə)</item>
+ <item quantity="one">(%1$d dəqiqə) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Bugün"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Sabah"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Dünən"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> bugün"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> sabah"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Hesab"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Qeyd edilmiş Proqramlar"</string>
+</resources>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
deleted file mode 100644
index 6ccb6d24..00000000
--- a/res/values-az/strings.xml
+++ /dev/null
@@ -1,352 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Oyun kontrolu"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Son kanallar"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"TV seçənəkləri"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP seçənəklər"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Oxutma idarə elementləri bu kanal üçün əlçatan deyil"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Oxudun və ya durdurun"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Sürətlə irəli"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Geri qayıdın"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Növbəti"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Əvvəlki"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Proqram Təlimatı"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Yeni əlçatan kanallar"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqini açın"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Qapalı başlıqlar"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Ekran rejimi"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Aktiv"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Qeyri-aktiv"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Daha çox kanal əldə edin"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Ayarlar"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Mənbə"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Dəyişdirin"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Aktiv"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Qeyri-aktiv"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Səs"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Əsas"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP pəncərəsi"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Etiket"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Aşağı sağ"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Yuxarı sağ"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Yuxarı sol"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Aşağı sol"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Yan-yana"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Ölçü"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Böyük"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Kiçik"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Mənbəni daxil edin"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/kabel)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"No proqram informasiya"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Məlumat yoxdur"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"bloklanmış kanallar"</string>
- <string name="default_language" msgid="4122326459624337928">"Naməlum dil"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Qapalı başlıqlar"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Deaktiv"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Formatı fərdiləşdirin"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Qapalı başlıqlar üçün daxili sistem tərcihlərini ayarlayın"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Ekran rejimi"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multi-audio"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"Mono"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"Stereo"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 Əhatəli"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 Əhatəli"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for multi_audio_channel_suffix (4443825738196093772) -->
- <skip />
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Kanal siyahısını fərdiləşdirin"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Qrup seçin"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Qrupu silin"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Qruplaşdırın"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Kanal mənbəyi"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Qruplaşdırın"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Bu proqram bloklanıb."</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Bu proqram <xliff:g id="RATING">%1$s</xliff:g> ilə qiymətləndirilib."</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Daxiletmə avto-skanı dəstəkləmir"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' üçün avto-skanı başlatmaq olmur"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Qapalı mövzular üçün sistem tərcihlərini başlatmaq olmur."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d kanal əlavə edildi</item>
- <item quantity="one">%1$d kanal əlavə edildi</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Kanal əlavə edilmədi"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Valideyn nəzarəti"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Aktiv"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Deaktiv"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Kanallar bloklanıb"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Hamısını bloklayın"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Hamısını blokdan çıxarın"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Gizli kanallar"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Proqram məhdudiyyətləri"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN kodu dəyişin"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Reytinq sistemləri"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Ratings"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Bütün reytinq sistemlərinə baxın"</string>
- <string name="other_countries" msgid="8342216398676184749">"Digər ölkələr"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Heç bir"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Heç bir"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Heç bir"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Yüksək məhdudiyyətlər"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Orta məhdudiyyətlər"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Aşağı məhdudiyyətlər"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Fərdi"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Uşaqlar üçün uyğun məzmun"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Böyük uşaqlar üçün uyğun məzmun"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Yeniyetmələr üçün uyğun məzmun"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Manual məhdudiyyətlər"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s və sub-reytinqlər"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Alt-reytinqlər"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Bu kanalı izləmək üçün PİN kodunuzu daxil edin"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Bu proqramı izləmək üçün PİN kodunuzu daxil edin"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Bu proqram <xliff:g id="RATING">%1$s</xliff:g> ilə qiymətləndirilib. Bu proqramı izləmək üçün PİN kodunuzu daxil edin"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"PİN kodunuzu daxil edin"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Valideyn nəzarəi yaratmaq üçün PİN yaradın"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Yeni PIN kodu daxil edin"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"PİN kodunuzu təsdiq edin"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Cari PİN kodu daxil edin"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">Yanlış PİN kodu 5 dəfə daxil etdiniz.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> saniyə sonra yenidən cəhd edin.</item>
- <item quantity="one">Yanlış PİN kodu 5 dəfə daxil etdiniz.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> saniyə sonra yenidən cəhd edin.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"Həmin PİN kod səhv idi. Yenidən cəhd edin."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Yenidən cəhd edin, PİN uyğun deyil"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Ayarlar"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Kanal siyahısını fərdiləşdirin"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Proqram təlimatınız üçün kanal seçin"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanal mənbələri"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Yeni əlçatan kanallar"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Valideyn nəzarəti"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Açıq mənbə lisenziyaları"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Açıq mənbə lisenziyaları"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Versiya"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Bu kanalı izləmək üçün Sağa basın və PİN kodunuzu daxil edin"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Bu proqramı izləmək üçün Sağa basın və PİN kodunuzu daxil edin"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Bu proqram <xliff:g id="RATING">%1$s</xliff:g> ilə qiymətləndirilib.\nBu proqramı izləmək üçün Sağa basın və PİN kodunuzu daxil edin."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Bu kanalı izləmək üçün defolt Live TV tətbiqini istifadə edin."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Bu proqramı izləmək üçün defolt Live TV tətbiqini istifadə edin."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Bu proqram <xliff:g id="RATING">%1$s</xliff:g> ilə qiymətləndirilib. \n Bu proqramı izləmək üçün defolt Live TV tətbiqini istifadə edin."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Proqram blok edilib"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Bu proqram <xliff:g id="RATING">%1$s</xliff:g> ilə qiymətləndirilib."</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Yalnız Audio"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Zəif siqnal"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"İnternet bağlantısı yoxdur"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Bu kanal <xliff:g id="END_TIME_1">%1$s</xliff:g> radələrinə kimi fəaliyyət göstərə bilməz, cünki, digər kanallar qeydə alınır \n\nQeydə alma cədvəlini nizamlamaq üçün Sağı basın.</item>
- <item quantity="one">Digər kanal qeydə alındığı üçün bu kanal <xliff:g id="END_TIME_0">%1$s</xliff:g> radələrinə kimi fəaliyyət göstərə bilməz. \n\nQeydə alma cədvəlini nizamlamaq üçün Sağı basın.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Başlıq yoxdur"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal blok edilib"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Yeni"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Mənbələr"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d kanal</item>
- <item quantity="one">%1$d kanal</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Əlçatan kanal yoxdur"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Yeni"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Quraşdırılmayıb"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Əlavə mənbə əldə edin"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Canlı kanallar təklif edən tətbiqlər axtarın"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Yeni kanal mənbələri əlçatandır"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Yeni kanal mənbələrinin kanal təklifləri var.\nOnları indi ayarlayın, və ya daha sonra kanal mənbələri ayarından edin."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"İndi ayarlayın"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"Ok, oldu."</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"TV menyusuna giriş üçün "<b>"SEÇİN basın"</b>"."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"TV daxiletmə tapılmadı"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"TV daxiletmə tapılmır"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP dəstəklənmir"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP ilə göstərilə biləcək əlçatan daxiletmə yoxdur"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Sazlama növü uyğun deyil. TV daxiletmə sazlama növü üçün Canlı Kanallar tətbiqini işə salın."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Sazlama alınmadı"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Bu əməliyyatı idarə etmək üçün heç bir tətbiq tapılmadı."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Bütün mənbə kanalları gizlədilib.\nİzləmək üçün ən azı bir kanal seçin."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Bu video gözlənilmədən əlçatmazdır"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"Geri düyməsi qoşulu cihazlar üçündür. Çıxmaq üçün ƏSAS SƏHİFƏ düyməsini basın."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Canlı Kanallar TV siyahıları oxumaq üçün icazə istəyir."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Mənbələrinizi quraşdırın"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Canlı kanallar tətbiq tərəfindən yayımlanan kanallar ilə ənənəvi TV kanallarının təcrübəsini özündə birləşdirir. \n\n Artıq yüklənmiş kanal mənbələrini quraşdıraraq başlayın. Və ya canlı kanallar təklif edən bir neçə tətbiq üçün Google Play Store\'da axtarış edin."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Qeydə almalar və cədvəllər"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 dəqiqə"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 dəqiqə"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 saat"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 saat"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Son"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Planlaşdırılıb"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Seriyalar"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Digərləri"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Kanal qeydə alına bilməz."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Proqram qeydə alına bilməz."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> tətbiqinin qeydə alınması üçün vaxt təyin edilib"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> bu dəqiqədən etibarən <xliff:g id="ENDTIME">%2$s</xliff:g> radələrinə kimi deydə alınır"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Tam cədvəl"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">Növbəti %1$d gün</item>
- <item quantity="one">Növbəti %1$d gün</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d dəqiqə</item>
- <item quantity="one">%1$d dəqiqə</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d yeni qeydə alma</item>
- <item quantity="one">%1$d yeni qeydə alma</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d qeydə alma</item>
- <item quantity="one">%1$d qeydə alma</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d qeydə alma təyin edildi</item>
- <item quantity="one">%1$d qeydə alma təyin edildi</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"İzləyin"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Əvvəldən oxudun"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Oxutmağa davam edin"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Silin"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Qeydə almaları silin"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Davam edin"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g> mövsüm"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Cədvələ baxın"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Ətraflı məlumat"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Qeydə almaları silin"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Silmək istədiyiniz epizodları seçin. Silinənlər bərpa oluna bilməz."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Silinmək üçün heç bir qeydə alma yoxdur."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Baxılmış epizodları seçin"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Bütün epizodları seçin"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Bütün epizodların seçimlərini qaldırın"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> müddətdən <xliff:g id="WATCHED">%1$d</xliff:g> dəqiqəsinə baxıldı"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> müddətdən <xliff:g id="WATCHED">%1$d</xliff:g> saniyəsinə baxıldı"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Heç vaxt baxılmayıb"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%2$d epizoddan %1$d epizod silindi</item>
- <item quantity="one">%2$d epizoddan %1$d epizod silindi</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Prioritet"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Ən yüksək"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Ən alçaq"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Yox. <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Kanallar"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Hər hansı"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Prioriteti seçin"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Eyni anda qeydə alınacaq bir neçə proqram olduqda, yalnız vacib olanlar qeydə alınacaq."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Yadda saxlayın"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Bir dəfəlik qeydiyyatlar yüksək prioritetlidir"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Ləğv edin"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Ləğv edin"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Unudun"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Dayandırın"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Qeydiyyat cədvəlinə baxın"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Tək bu proqram"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"indi - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Bütün seriyalar…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"İstənilən halda vaxt təyin edin"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Əvəzinə bunu qeydə alın"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Bu qeydə almanı ləğv edin"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"İndi baxın"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Qeydə alınabilən"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Qeydiyyat planlaşdırılıb"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Qeydiyyat münaqişəsi"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Qeydə alınır"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Qeydə alma uğursuz oldu"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Qeyd etmə cədvəli yaratmaq üçün proqramlar oxunur"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Oxuma proqramları"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR üçün əlavə yaddaş tələb olunur"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR ilə proqram qeydə ala biləcəksiniz. Hazırda DVR-ın işləməsi üçün cihazda kifayət qədər yaddaş yoxdur. <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB və ya daha böyük həcmli xarici yaddaşı qoşun və cihaz yaddaşı olaraq format etmək üçün mərhələlərə riayət edin."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Yaddaş catışmır"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR tərəfindən istifadə olunan yaddaşın bir hissəsi əlçatan deyil. DVR\'ı yenidən aktiv etməmişdən əvvəl istifadə etdiyiniz xarici diskə qoşulun. Bundan başqa, artıq əlçatan deyilsə, yaddaşı unutmağı seçə bilərsiniz."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Yaddaş ehtiyyatını unutmusunuz?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Qeydə alınmış bütün məzmun və cədvəlləriniz itəcək."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Qeydetmə dayandırılsın?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Qeydə alınan məzmun yadda saxlanacaq."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Qeydiyyat vaxtı təyin edilib lakin ziddiyətlər var"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Qeydə alma başladı, lakin ziddiyətlər var."</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> qeydə alınacaq."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> qeydə alındı."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> tətbiqinin bəzi hissələri qeydə alınmayacaq."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> və <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> tətbiqlərinin bəzi hissələri qeydə alınmayacaq."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> tətbiqlərinin bəzi hissələri və daha bir cədvəl qeydə alınmayacaq."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> tətbiqlərinin bəzi hissələri və daha %3$d cədvəl qeydə alınmayacaq.</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> tətbiqlərinin bəzi hissələri və daha %3$d cədvəl qeydə alınmayacaq.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Qeydə almaq istəyirsiniz?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Nə qədər müddətə qeydə almaq istəyirsiniz?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Artıq vaxt təyin edilib"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Eyni proqramın qeydə alınması üçün artıq <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> radələrində vaxt təyin edilib."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Artıq qeydə alınıb"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Bu proqram artıq qeydə alınıb. O, DVR kitabxanasında əlçatandır."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Qeyd edilmiş proqram tapılmadı."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Əlaqədar qeydetmələr"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Proqramın təsviri yoxdur)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d qeyd etmə</item>
- <item quantity="one">%1$d qeyd etmə</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> qeyd cədvəlindən çıxarıldı"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Kökləyici ziddiyətləri səbəbi ilə qismən qeydə alınacaq."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Kökləyici ziddiyətləri səbəbi ilə qeydə alınmacaq."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Hələ ki cədvəldə heç bir qeydə alma yoxdur.\nProqram bələdçisindən qeydə alma üçün vaxt təyin edə bilərsiniz."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d qeydə alma münaqişəsi</item>
- <item quantity="one">%1$d qeydə alma münaqişəsi</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Davamlılıq ayarları"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Ardıcıl qeydə almanı başladın"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Ardıcıl qeydə alma dayandırılsın"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Ardıcıl qeydə alma dayandırılsın?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Qeydə alınmış epizodlar DVR kitabxanasında əlçatan olacaq."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Dayandırın"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Heç bir epizod əlçatan deyil.\nOnlar, əlçatan olduqda qeydə alınacaq."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d dəqiqə)</item>
- <item quantity="one">(%1$d dəqiqə) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Bugün"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Sabah"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Dünən"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> bugün"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> sabah"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Hesab"</string>
-</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index ab202fe2..cd4ae375 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Контроли за пускане"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Скорошни канали"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Канали"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Опции за TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Опции за PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"За този канал няма налични контроли за възпроизвеждане"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Пускане или поставяне на пауза"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Превъртане напред"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Надписи"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Показв.: Режим"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Вкл."</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Изкл."</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Много записи"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Още канали"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Настройки"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Източник"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Размяна"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Вкл."</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Изкл."</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Звук"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Основен"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Прозорец на PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Оформление"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Долу вдясно"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Горе вдясно"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Горе вляво"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Долу вляво"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Редом"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Размер"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Голям"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Малък"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Вход"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"Телевизор (антена/кабел)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Няма информация за програмите"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Няма информация"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Блокиран канал"</string>
- <string name="default_language" msgid="4122326459624337928">"Неизвестен език"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Неизвестен език"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Надписи: %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Надписи"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Изключване"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Форматиране: Персон."</string>
@@ -79,10 +60,11 @@
<string name="edit_channels_item_group_by" msgid="7794571851966798199">"Групиране по"</string>
<string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Източник на канала"</string>
<string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"Висока/стандартна детайлност"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Висока детайлност"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Стандартна детайлност"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Групиране по"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Тази програма е блокирана"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Тази програма е без класификация"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Класификацията на тази програма е „<xliff:g id="RATING">%1$s</xliff:g>“"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Входът не поддържа автоматично сканиране"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Автоматичното сканиране за „<xliff:g id="TV_INPUT">%s</xliff:g>“ не може да се стартира"</string>
@@ -92,7 +74,6 @@
<item quantity="one">Добавен е %1$d канал</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Няма добавени канали"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Тунер"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Родителски контрол"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Вкл."</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Изкл."</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Други държави"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Няма"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Няма"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Без класификация"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Програми без класиф.: Блокир."</string>
<string name="option_rating_none" msgid="5204552587760414879">"Няма"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Високи ограничения"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Средни ограничения"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Въведете ПИН кода си, за да гледате този канал"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Въведете ПИН кода си, за да гледате тази програма"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Тази програма е класифицирана като „<xliff:g id="RATING">%1$s</xliff:g>“. Въведете ПИН кода си, за да я гледате"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Тази програма е без класификация. Въведете ПИН кода си, за да я гледате"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Въведете ПИН кода си"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"За да зададете родителски контроли, създайте ПИН код"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Въведете новия ПИН код"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Този ПИН код бе грешен. Опитайте отново."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Опитайте отново, ПИН кодът не е идентичен"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Въведете пощенския си код."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Приложението Телевизия онлайн ще използва пощенския код, за да предоставя пълния програмен справочник за телевизионните канали."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Въведете пощенския си код"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Пощенският код е невалиден"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Настройки"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Персон. на списъка с канали"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Изберете канали за програмния си справочник"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Източници на канали"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Налице са нови канали"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Родителски контроли"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Отложено възпроизвеждане"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Записвайте, докато гледате, за да можете да поставяте на пауза или превъртате назад програми на живо.\nПредупреждение: Тази функция може да намали живота на вътрешното хранилище чрез интензивното му използване."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Лицензи за отворен код"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Лицензи за отворен код"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Изпращане на отзиви"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Версия"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"За да гледате този канал, натиснете стрелката за надясно и въведете ПИН кода си"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"За да гледате тази програма, натиснете стрелката за надясно и въведете ПИН кода си"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Тази програма е без класификация.\nЗа да я гледате, натиснете бутона за надясно и въведете ПИН кода си."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Класификацията на тази програма е „<xliff:g id="RATING">%1$s</xliff:g>“.\nЗа да я гледате, натиснете стрелката за надясно и въведете ПИН кода си."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"За да гледате този канал, използвайте стандартното приложение за телевизия на живо."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"За да гледате тази програма, използвайте стандартното приложение за телевизия на живо."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Тази програма е без класификация.\nЗа да я гледате, използвайте стандартното приложение за телевизия на живо."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Тази програма е класифицирана като „<xliff:g id="RATING">%1$s</xliff:g>“.\nЗа да я гледате, използвайте стандартното приложение за телевизия на живо."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Програмата е блокирана"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Тази програма е без класификация"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Класификацията на тази програма е „<xliff:g id="RATING">%1$s</xliff:g>“"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Само аудио"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Слаб сигнал"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Натиснете „ИЗБИРАНЕ“"</b>" за достъп до менюто на телевизора."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Няма намерен вход на телевизора"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Входът на телевизора не може да бъде намерен"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Функцията „Картина в картината“ не се поддържа"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Няма наличен вход, който да може да се показва с PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Типът тунер не е подходящ. Моля, стартирайте приложението Live TV за телевизионен вход от типа „тунер“."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Настройването не бе успешно"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Не бе намерено приложение за извършване на това действие."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d насрочени записа</item>
<item quantity="one">%1$d насрочен запис</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Анулиране на записа"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Спиране на записа"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Гледане"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Пускане от началото"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Продължаване"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Когато има прекалено много програми за записване по едно и също време, ще бъдат записани само тези с най-висок приоритет."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Запазване"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Най-висок приоритет имат еднократните записи"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Отказ"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Отказ"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Забравяне"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Спиране"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Вижте графика за записване"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Само тази програма"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Записване на тази програма"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Анулиране на този запис"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Гледайте сега"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Изтриване на записи…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"С възможност за запис"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Записът е насрочен"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Конфликт със записа"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Записва се"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Записването не бе успешно"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Програмите се четат с цел създаване на графици за записване"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Програмите се четат"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Програмите се четат"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Преглед на скорошните записи"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Записът на „<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ е непълен."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Записите на „<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>“ и „<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>“ са непълни."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Записите на „<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>“, „<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>“ и „<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>“ са непълни."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Записването на „<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ не завърши поради недостатъчно място в хранилището."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Записването на „<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>“ и „<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>“ не завърши поради недостатъчно място в хранилището."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Записването на „<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>“, „<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>“ и „<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>“ не завърши поради недостатъчно място в хранилището."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Дигиталният видеорекордер се нуждае от още място за съхранение"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Ще сте в състояние да записвате програми посредством дигиталния видеорекордер. В момента обаче той не може да работи, тъй като няма достатъчно място в хранилището на устройството ви. Моля, свържете външен диск с размер от поне <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> ГБ и изпълнете стъпките, за да го форматирате като хранилище на устройството."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Ще сте в състояние да записвате програми посредством дигиталния видеорекордер. В момента обаче той не може да работи, тъй като няма достатъчно място в хранилището на устройството ви. Моля, свържете външен диск с размер от поне <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> ГБ и изпълнете стъпките, за да го форматирате като хранилище на устройството."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Няма достатъчно място в хранилището"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Тази програма няма да бъде записана, защото няма достатъчно място в хранилището. Пробвайте да изтриете някои съществуващи записи."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Хранилището липсва"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Част от използваното от цифровия видеорекордер хранилище липсва. Моля, свържете по-рано ползвания от вас външен диск, за да активирате отново видеорекордера. Друга възможност е да изберете хранилището да се забрави, ако вече не е налично."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Да се забрави ли хранилището?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Цялото ви записано съдържание и графици ще бъдат изгубени."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Да се спре ли записването?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Записаното съдържание ще бъде запазено."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Записването на „<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ ще бъде спряно, защото е в конфликт с тази програма. Записаното съдържание ще бъде запазено."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Записът е насрочен, но има конфликти"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Записването започна, но има конфликти"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"„<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ ще се запише."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Същата програма вече е насрочена за записване в <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Вече записахте"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Тази програма вече е записана. Тя е налична в библиотеката на устройството за дигитален видеозапис."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Записването на поредицата е насрочено"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">За „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ са насрочени <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записа.</item>
+ <item quantity="one">За „<xliff:g id="SERIESNAME_1">%2$s</xliff:g>“ е насрочен <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> запис.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">За „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ са насрочени <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записа. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> епизода няма да бъдат записани поради конфликти.</item>
+ <item quantity="one">За „<xliff:g id="SERIESNAME_1">%2$s</xliff:g>“ е насрочен <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> запис. Епизодът няма да бъде записан поради конфликти.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">За „<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“ са насрочени <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записа. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизода от тази и от друга поредица няма да бъдат записани поради конфликти.</item>
+ <item quantity="one">За „<xliff:g id="SERIESNAME_1">%2$s</xliff:g>“ е насрочен <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> запис. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> епизода от тази и от друга поредица няма да бъдат записани поради конфликти.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">За „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ са насрочени <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записа. 1 епизод от друга поредица няма да бъде записан поради конфликти.</item>
+ <item quantity="one">За „<xliff:g id="SERIESNAME_1">%2$s</xliff:g>“ е насрочен <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> запис. 1 епизод от друга поредица няма да бъде записан поради конфликти.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">За „<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“ са насрочени <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записа. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизода от друга поредица няма да бъдат записани поради конфликти.</item>
+ <item quantity="one">За „<xliff:g id="SERIESNAME_1">%2$s</xliff:g>“ е насрочен <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> запис. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> епизода от друга поредица няма да бъдат записани поради конфликти.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Записаната програма не е намерена."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Сродни записи"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Няма описание на програмата)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d записа</item>
<item quantity="one">%1$d запис</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Да се спре ли записването на поредицата?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Записаните епизоди ще останат налице в библиотеката на устройството за дигитален видеозапис."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Спиране"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"В момента не се излъчва нито един епизод."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Няма налични епизоди.\nТе ще бъдат записани, когато са налице."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d минути)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Днес: <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Утре: <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Рейтинг"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Записани програми"</string>
</resources>
diff --git a/res/values-bn-v23/strings.xml b/res/values-bn-rBD-v23/strings.xml
index b3134242..b3134242 100644
--- a/res/values-bn-v23/strings.xml
+++ b/res/values-bn-rBD-v23/strings.xml
diff --git a/res/values-bn/arrays.xml b/res/values-bn-rBD/arrays.xml
index 76a0792a..76a0792a 100644
--- a/res/values-bn/arrays.xml
+++ b/res/values-bn-rBD/arrays.xml
diff --git a/res/values-bn/rating_system_strings.xml b/res/values-bn-rBD/rating_system_strings.xml
index 81c9593b..81c9593b 100644
--- a/res/values-bn/rating_system_strings.xml
+++ b/res/values-bn-rBD/rating_system_strings.xml
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
new file mode 100644
index 00000000..83e28250
--- /dev/null
+++ b/res/values-bn-rBD/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"মোনো"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"স্টিরিও"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"খেলার নিয়ন্ত্রণগুলি"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"চ্যানেলগুলি"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"টিভি বিকল্পগুলি"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"এই চ্যানেলটির জন্য প্লে নিয়ন্ত্রণগুলি অনুপলব্ধ"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"প্লে করুন বা বিরাম দিন"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"দ্রুত ফরওয়ার্ড"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"পেছনের দিকে যান"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"পরবর্তী"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"পূর্ববর্তী"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"প্রোগ্রাম গাইড"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"নতুন চ্যানেলগুলি উপলব্ধ"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> খুলুন"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"সাবটাইটেলগুলি"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"প্রদর্শন মোড"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"একাধিক-অডিও"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"আরো চ্যানেল পান"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"সেটিংস"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (অ্যান্টেনা/কেবল)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"কোনো প্রোগ্রাম তথ্য নেই"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"কোনো তথ্য নেই"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"অবরুদ্ধ চ্যানেল"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"অজানা ভাষা"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"সাবটাইটেল %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"সাবটাইটেলগুলি"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"বন্ধ করুন"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"ফর্ম্যাটিং কাস্টমাইজ করুন"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"সাবটাইটেলগুলির জন্য সিস্টেম-ব্যাপী পছন্দগুলি সেট করুন"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"প্রদর্শন মোড"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"একাধিক-অডিও"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"মনো"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"স্টিরিও"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"৫.১ সারাউন্ড"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"৭.১ সারাউন্ড"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d চ্যানেলগুলি"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"চ্যানেল তালিকা কাস্টমাইজ করুন"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"গোষ্ঠী নির্বাচন করুন"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"গোষ্ঠী নির্বাচন মুক্ত করুন"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"এর ভিত্তিতে গোষ্ঠীভুক্ত করুন"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"চ্যানেল উৎস"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"এর ভিত্তিতে গোষ্ঠীভুক্ত করুন"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"এই প্রোগ্রামটি অবরুদ্ধ করা হয়েছে"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"এই প্রোগ্রামটিতে কোনও রেটিং দেওয়া হয়নি"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"এই প্রোগ্রামটি <xliff:g id="RATING">%1$s</xliff:g> রেট প্রাপ্ত৷"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"ইনপুটটি অটো-স্ক্যান সমর্থন করে না"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' এর জন্য স্বয়ংক্রিয়-স্ক্যান শুরু করা যায়নি"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"সাবটাইটেলগুলির জন্য সিস্টেম-ব্যাপী পছন্দগুলি শুরু করা যায়নি৷"</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$dটি চ্যানেল যোগ করা হয়েছে</item>
+ <item quantity="other">%1$dটি চ্যানেল যোগ করা হয়েছে</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"কোনো চ্যানেল যোগ করা হয়নি"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"অভিভাবকীয় নিয়ন্ত্রণগুলি"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"চালু করুন"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"বন্ধ করুন"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"অবরুদ্ধ চ্যানেলগুলি"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"সবগুলি অবরুদ্ধ করুন"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"সবগুলিকে অবরোধ মুক্ত করুন"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"লুকানো চ্যানেলগুলি"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"প্রোগ্রামের বিধিনিষেধগুলি"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"পিন পরিবর্তন করুন"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"রেটিং পদ্ধতি"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"রেটিংগুলি"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"রেটিংয়ের সমস্ত পদ্ধতি দেখুন"</string>
+ <string name="other_countries" msgid="8342216398676184749">"অন্যান্য দেশ"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"একটিও নেই"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"কোনো কিছুই নেই"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"রেটিং দেওয়া হয়নি"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"রেটিং ছাড়া প্রোগ্রাম ব্লক করুন"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"কোনো কিছুই নেই"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"উচ্চ মাত্রার বিধিনিষেধগুলি"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"মাঝারি মাত্রার বিধিনিষেধগুলি"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"কম মাত্রার বিধিনিষেধগুলি"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"কাস্টম"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"শিশুদের জন্য উপযুক্ত সামগ্রী"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"বয়স্ক শিশুদের জন্য উপযুক্ত সামগ্রী"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"তেরো থেকে উনিশ বছর বয়সীদের জন্য উপযুক্ত সামগ্রী"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"নিজে করা সম্পর্কিত বিধিনিষেধগুলি"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s এবং উপ-রেটিংগুলি"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"উপ-রেটিংগুলি"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"এই চ্যানেলটি দেখতে আপনার পিন লিখুন"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"এই প্রোগ্রামটি দেখতে আপনার পিন লিখুন"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"এই প্রোগ্রামটি <xliff:g id="RATING">%1$s</xliff:g> রেটপ্রাপ্ত। এই প্রোগ্রামটি দেখার জন্য আপনার PIN লিখুন।"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"এই প্রোগ্রামটিতে কোনও রেটিং দেওয়া হয়নি এটি দেখতে আপনার পিন লিখুন"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"আপনার পিন লিখুন"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"অভিভাবকীয় নিয়ন্ত্রণগুলি সেট করতে, একটি পিন তৈরি করুন"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"নতুন পিন লিখুন"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"আপনার পিন নিশ্চিত করুন"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"আপনার বর্তমান পিন লিখুন"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">আপনি ৫ বার ভুল পিন প্রবেশ করিয়েছেন।\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।</item>
+ <item quantity="other">আপনি ৫ বার ভুল পিন প্রবেশ করিয়েছেন।\n <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"এই PINটি ভুল ছিল৷ আবার চেষ্টা করুন৷"</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"আবার চেষ্টা করুন, পিন মেলেনি"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"আপনার ডাক পিন কোড লিখুন৷"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Live TV অ্যাপটি টিভি চ্যানেলগুলির প্রোগ্রামের সম্পূর্ণ নির্দেশিকা প্রদান করার জন্য ডাক পিন কোড ব্যবহার করবে৷"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"আপনার ডাক পিন কোড লিখুন"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"অবৈধ ডাক পিন কোড"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"সেটিংস"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"চ্যানেল তালিকা কাস্টমাইজ করুন"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"আপনার প্রোগ্রাম গাইডের জন্য চ্যানেলগুলি নির্বাচন করুন"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"চ্যানেলের উৎসগুলি"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"নতুন চ্যানেলগুলি উপলব্ধ"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"অভিভাবকীয় নিয়ন্ত্রণগুলি"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"টাইমশিফ্ট"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"দেখার সময় রেকর্ড করুন সুতারং আপনি লাইভ প্রোগ্রামগুলিকে বিরাম দিতে বা রিওয়াইন্ড করতে পারেন৷\nসতর্কতা: সঞ্চয়স্থানের বেশি পরিমাণে ব্যবহার করার ফলে অভ্যন্তরীণ সঞ্চয়স্থানের কর্মক্ষমতা হ্রাস করতে পারে৷"</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"মুক্ত উৎস লাইসেন্সগুলি"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"প্রতিক্রিয়া পাঠান"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"সংস্করণ"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"এই চ্যানেলটিকে দেখতে, ডানদিকে চাপুন এবং আপনার পিন লিখুন"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"এই প্রোগ্রামটি দেখতে, ডানদিকে চাপুন এবং আপনার পিন লিখুন"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"এই প্রোগ্রামটিতে কোনও রেটিং দেওয়া হয়নি।\nএটি দেখতে ডান দিকের বোতামটি টিপুন এবং আপনার পিন লিখুন"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"এই প্রোগ্রামটি <xliff:g id="RATING">%1$s</xliff:g> রেট প্রাপ্ত৷\nএই প্রোগ্রামটি দেখতে, ডানদিকে চাপুন এবং আপনার পিন লিখুন"</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"এই চ্যানেলটি দেখতে, ডিফল্ট লাইভ টিভি অ্যাপ্লিকেশানটি ব্যবহার করুন৷"</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"এই প্রোগ্রামটি দেখতে, ডিফল্ট লাইভ টিভি অ্যাপ্লিকেশানটি ব্যবহার করুন৷"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"এই প্রোগ্রামটিতে কোনও রেটিং দেওয়া হয়নি\nডিফল্ট লাইভ TV অ্যাপে এটি দেখুন।"</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"এই প্রোগ্রামটি <xliff:g id="RATING">%1$s</xliff:g> রেট প্রাপ্ত৷\nএই প্রোগ্রামটি দেখতে, ডিফল্ট লাইভ টিভি অ্যাপ্লিকেশানটি ব্যবহার করুন৷"</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"প্রোগ্রামটি অবরুদ্ধ"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"এই প্রোগ্রামটিতে কোনও রেটিং দেওয়া হয়নি"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"এই প্রোগ্রামটি <xliff:g id="RATING">%1$s</xliff:g> রেট প্রাপ্ত৷"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"কেবলমাত্র অডিও"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"সিগন্যাল দুর্বল"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"কোনো ইন্টারনেট সংযোগ নেই"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="one"><xliff:g id="END_TIME_1">%1$s</xliff:g>পর্যন্ত এই চ্যালেনটি চালানো যাবে না কারণ অন্যান্য চ্যানেলগুলি রেকর্ড করা হচ্ছে৷ \n\nরেকর্ড করার সময়সূচী সামঞ্জস্য করতে ডান দিকে ক্লিক করুন৷</item>
+ <item quantity="other"><xliff:g id="END_TIME_1">%1$s</xliff:g>পর্যন্ত এই চ্যালেনটি চালানো যাবে না কারণ অন্যান্য চ্যানেলগুলি রেকর্ড করা হচ্ছে৷ \n\nরেকর্ড করার সময়সূচী সামঞ্জস্য করতে ডান দিকে ক্লিক করুন৷</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"কোনো শিরোনাম নেই"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"চ্যানেল অবরুদ্ধ করা হয়েছে"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"নতুন"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"উৎসগুলি"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$dটি চ্যানেল</item>
+ <item quantity="other">%1$dটি চ্যানেল</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"কোনো চ্যানেল উপলব্ধ নেই"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"নতুন"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"সেট আপ করা নেই"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"আরো উৎস পান"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"লাইভ চ্যানেল অফার করে এমন অ্যাপ্স ব্রাউজ করুন"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"নতুন চ্যানেলের সূত্রগুলি উপলব্ধ রয়েছে"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"নতুন চ্যানেলের সূত্রগুলিতে প্রদান করার জন্য চ্যানেল রয়েছে।\nসেগুলিকে এখনই সেট আপ করুন, বা চ্যানের সূত্রের সেটিংয়ের মধ্যে পরে এটি করুন।"</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"এখনই সেট আপ করুন"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"ঠিক আছে, বুঝেছি"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"টিভি মেনু অ্যাক্সেস করতে "<b>"নির্বাচন করুন টিপুন"</b>"৷"</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"কোনো TV ইনপুট খুঁজে পাওয়া যায়নি"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"TV ইনপুট খুঁজে পাওয়া যায়নি"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"টিউনারের প্রকারটি উপযুক্ত নয়; টিউনার প্রকারের টিভি ইনপুটের জন্য দয়া করে লইভ চ্যানেলগুলি অ্যাপ্লিকেশানটি লঞ্চ করুন৷"</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"টিউন করা ব্যর্থ হয়েছে"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"এই ক্রিয়াটিকে চালনা করার জন্য কোনো অ্যাপ্লিকেশান পাওয়া যায়নি৷"</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"সমস্ত উৎস চ্যানেল লুকানো আছে৷\nদেখার জন্য কমপক্ষে একটি চ্যানেল নির্বাচন করুন৷"</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ভিডিওটি অপ্রত্যাশিতভাবে অনুপলব্ধ"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"\'ব্যাক\' কীটি সংযুক্ত ডিভাইসের ক্ষেত্রে ব্যবহারের জন্য৷ প্রস্থান করতে হোম বোতামটি টিপুন৷"</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"টিভির তালিকাগুলি পড়ার জন্য লাইভ চ্যানেলগুলিকে অনুমতি নিতে হবে।"</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"আপনার উৎসগুলি সেট আপ করুন"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"লাইভ চ্যানেলগুলি অ্যাপ্লিকেশানগুলির দ্বারা সরবরাহ করা স্ট্রিমিং চ্যানেলের সঙ্গে ঐতিহ্যগত টিভি চ্যানেলের সম্মিলিত অভিজ্ঞতা প্রদান করে৷ \n\nইতিমধ্যেই ইনস্টল থাকা চ্যানেল উৎসগুলি সেট আপ করার মাধ্যেমে শুরু করুন৷ অথবা লাইভ চ্যানেলগুলি অফার করে এমন অ্যাপ্লিকেশানগুলি পেতে Google Play স্টোর ব্রাউজ করুন৷"</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"রেকডিং &amp; সময়সূচী"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"১০ মিনিট"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"৩০ মিনিট"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"১ ঘণ্টা"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"৩ ঘণ্টা"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"সাম্প্রতিক"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"নির্ধারিত"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"সিরিজ"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"অন্যরা"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"চ্যানেলটি রেকর্ড করা যাবে না৷"</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"প্রোগ্রামটি রেকর্ড করা যাবে না৷"</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> রেকর্ড করার সময় নির্ধারিত হয়েছে"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>কে এখান থেকে <xliff:g id="ENDTIME">%2$s</xliff:g> পর্যন্ত রেকর্ড করা হচ্ছে"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"সম্পূর্ণ সময়সূচী"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="one">পরবর্তী %1$d দিন</item>
+ <item quantity="other">পরবর্তী %1$d দিন</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="one">%1$d মিনিট</item>
+ <item quantity="other">%1$d মিনিট</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="one">%1$dটি নতুন রেকডিং</item>
+ <item quantity="other">%1$dটি নতুন রেকডিং</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="one">%1$dটি রেকর্ডিং</item>
+ <item quantity="other">%1$dটি রেকর্ডিং</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="one">%1$dটি রেকর্ডিংয়ের সময় নির্ধারিত হয়েছে</item>
+ <item quantity="other">%1$dটি রেকর্ডিংয়ের সময় নির্ধারিত হয়েছে</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"রেকর্ডিং বাতিল করুন"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"রেকডিং বন্ধ করুন"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"দেখুন"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"শুরু থেকে প্লে করুন"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"আবার প্লে করুন"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"মুছুন"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"রেকডিংগুলি মুছুন"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"আবার শুরু করুন"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"সিজন <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"সময়সূচী দেখুন"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"আরো পড়ুন"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"রেকডিংগুলি মুছুন"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"আপনি যে পর্বগুলিকে মুছতে চান সেগুলিকে নির্বাচন করুন। একবার মোছা হলে সেগুলিকে পুনরুদ্ধার করা যাবে না।"</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"মোছার জন্য সেখানে কোনো রেকডিং নেই।"</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"দেখা পর্বগুলিকে নির্বাচন করুন"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"সমস্ত পর্ব নির্বাচন করুন"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"সমস্ত পর্ব নির্বাচন মুক্ত করুন"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> এর মধ্যে <xliff:g id="WATCHED">%1$d</xliff:g> মিনিট দেখা হয়েছে"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> এর মধ্যে <xliff:g id="WATCHED">%1$d</xliff:g> সেকেন্ড দেখা হয়েছে"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"কখনই দেখা হয়নি"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="one">%2$dটির মধ্যে %1$dটি পর্ব মোছা হয়েছে</item>
+ <item quantity="other">%2$dটির মধ্যে %1$dটি পর্ব মোছা হয়েছে</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"অগ্রাধিকার"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"সর্বোচ্চ"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"সর্বনিম্ন"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"না৷ <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"চ্যানেল"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"যে কোনো"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"অগ্রাধিকার চয়ন করুন"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"যখন একই সময়ে অনেকগুলি প্রোগ্রাম রেকর্ড করা হয় তখন শুধুমাত্র উচ্চ অগ্রাধিকারযুক্ত প্রোগ্রামগুলিকে রেকর্ড করা হবে৷"</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"সংরক্ষণ করুন"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"একবার করা রেকর্ডিংগুলিতে সর্বোচ্চ অগ্রাধিকার রয়েছে"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"থামান"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"রেকডিং এর সময়সূচী দেখুন"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"শুধুমাত্র এই প্রোগ্রামটি"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"এখন - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"সম্পূর্ণ সিরিজ…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"যাই হোক, সময়সূচি নির্ধারণ করুন"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"বরং এটি রেকর্ড করুন"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"এই রেকর্ডিং বাতিল করুন"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"এখনই দেখুন"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"রেকডিংগুলি মুছুন..."</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"রেকর্ড করা যাবে"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"রেকর্ডিংএর সময় নির্ধারিত হয়েছে"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"রেকর্ডিং দ্বন্দ্ব"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"রেকর্ড করা হচ্ছে"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"রেকডিং করা গেল না"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"প্রোগ্রামগুলি পড়া হচ্ছে"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"সাম্প্রতিক রেকর্ডিংগুলি দেখুন"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> এর রেকর্ডিং অসম্পূর্ণ।"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> এবং <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> এর রেকর্ডিং সম্পূর্ণ।"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> এবং <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> এর রেকর্ডিং অসম্পূর্ণ।"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"অপর্যাপ্ত সঞ্চয়স্থান থাকার কারণে <xliff:g id="PROGRAMNAME">%1$s</xliff:g> এর রেকর্ডিং সম্পূর্ণ হয়নি।"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"অপর্যাপ্ত সঞ্চয়স্থান থাকার কারণে <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> এবং <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> এর রেকর্ডিং সম্পূর্ণ হয়নি।"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"অপর্যাপ্ত সঞ্চয়স্থান থাকার কারণে <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> এবং <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> এর রেকর্ডিং সম্পূর্ণ হয়নি।"</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR এর আরো সঞ্চয়স্থান দরকার"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"আপনি DVR এর মাধ্যমে প্রোগ্রাম রেকর্ড করতে পারবেন৷ তবে DVR কাজ করার জন্য আপনার ডিভাইসে এখন যথেষ্ঠ সঞ্চয়স্থান নেই৷ অনুগ্রহ করে <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB বা তার থেকে বড় আকারের কোনো বাহ্যিক ডিভাইসের সাথে সংযোগ করুন এবং ডিভাইসের সঞ্চয়স্থান হিসাবে ফর্ম্যাট করতে পদক্ষেপগুলি অনুসরণ করুন৷"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"পর্যাপ্ত সঞ্চয়স্থান নেই"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"এখানে পর্যাপ্ত সঞ্চয়স্থান না থাকার কারণে এই প্রোগ্রামটিকে রেকর্ড করা যাবে না৷ বিদ্যমান কিছু রেকর্ডিং মোছার চেষ্টা করুন৷"</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"সঞ্চয়স্থান অনুপস্থিত"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"রেকর্ড করা থামাবেন?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"রেকর্ড করা সামগ্রী সংরক্ষণ করা হবে৷"</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"এই প্রোগ্রামের সাথে রেকডিং দ্বন্দ্ব থাকায় <xliff:g id="PROGRAMNAME">%1$s</xliff:g> এর রেকর্ডিং বন্ধ হবে। রেকর্ড করা সামগ্রী সংরক্ষিত হবে।"</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"রেকর্ডিংয়ের যে সময় নির্ধারিত করা হয়েছে তাতে অন্যদের সমসয়ের সাথে বিরোধ ঘটাতে পারে।"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"রেকর্ডিং শুরু হয়েছে কিন্তু দ্বন্দ্বগুলি রয়েছে"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> রেকর্ড করা হবে৷"</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> রেকর্ড করা হচ্ছে৷"</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> এর কিছু অংশ রেকর্ড করা হবে না৷"</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> এবং <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> এর কিছু অংশ রেকর্ড করা হবে না৷"</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>এর কিছু অংশ এবং আরো একটি সময়সূচী রেকর্ড করা হবে না৷"</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="one"> <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> এর কিছু অংশ এবং আরো %3$dটি সময়সূচী রেকর্ড করা হবে না৷</item>
+ <item quantity="other"> <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> এর কিছু অংশ এবং আরো %3$dটি সময়সূচী রেকর্ড করা হবে না৷</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"আপনি কি রেকর্ড করতে চান?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"আপনি কতক্ষন রেকর্ড করতে চান?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ইতিমধ্যে সময়সূচী নির্ধারণ করা হয়েছে"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"একই প্রোগ্রাম ইতিমধ্যেই <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> এ রেকর্ড করার জন্য নির্ধারণ করা হয়েছে।"</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ইতিমধ্যে রেকর্ড করা হয়েছে"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"এই প্রোগ্রামটি ইতিমধ্যে রেকর্ড করা হয়েছে। এটি DVR লাইব্রেরিতে উপলব্ধ।"</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"সিরিজ রেকর্ডিংয়ের সময় নির্ধারিত হয়েছে"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> এর জন্য <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>টি রেকর্ডিংয়ের সময়সূচি নির্ধারণ করা হয়েছে।</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> এর জন্য <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>টি রেকর্ডিংয়ের সময়সূচি নির্ধারণ করা হয়েছে।</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> এর জন্য <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>টি রেকর্ডিংয়ের সময়সূচি নির্ধারণ করা হয়েছে। বিরোধগুলির কারণে এগুলির মধ্যে <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>টি পর্ব রেকর্ড করা যাবে না৷</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> এর জন্য <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>টি রেকর্ডিংয়ের সময়সূচি নির্ধারণ করা হয়েছে। বিরোধগুলির কারণে এগুলির মধ্যে <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>টি পর্ব রেকর্ড করা যাবে না৷</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> এর জন্য <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>টি রেকর্ডিংয়ের সময়সূচি নির্ধারণ করা হয়েছে। বিরোধগুলির কারণে এটি এবং অন্য সিরিজের <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>টি পর্ব রেকর্ড করা যাবে না৷</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> এর জন্য <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>টি রেকর্ডিংয়ের সময়সূচি নির্ধারণ করা হয়েছে। বিরোধগুলির কারণে এটি এবং অন্য সিরিজের <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>টি পর্ব রেকর্ড করা যাবে না৷</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> এর জন্য <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>টি রেকর্ডিংয়ের সময়সূচি নির্ধারণ করা হয়েছে৷ বিরোধগুলির কারণে অন্য সিরিজের ১টি পর্ব রেকর্ড করা যাবে না৷</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> এর জন্য <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>টি রেকর্ডিংয়ের সময়সূচি নির্ধারণ করা হয়েছে৷ বিরোধগুলির কারণে অন্য সিরিজের ১টি পর্ব রেকর্ড করা যাবে না৷</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> এর জন্য <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>টি রেকর্ডিংয়ের সময়সূচি নির্ধারণ করা হয়েছে। বিরোধগুলির কারণে অন্য সিরিজের <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>টি পর্ব রেকর্ড করা যাবে না৷</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> এর জন্য <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>টি রেকর্ডিংয়ের সময়সূচি নির্ধারণ করা হয়েছে। বিরোধগুলির কারণে অন্য সিরিজের <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>টি পর্ব রেকর্ড করা যাবে না৷</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"রেকর্ড করা প্রোগ্রাম খুঁজে পাওয়া যায়নি৷"</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"সম্পর্কিত রেকর্ডিং"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="one">%1$dটি রেকর্ডিং</item>
+ <item quantity="other">%1$dটি রেকর্ডিং</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"রেকর্ড করার সময়সূচী থেকে <xliff:g id="PROGRAMNAME">%1$s</xliff:g> সরানো হয়েছে"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"টিউনার না থাকার কারণে আংশিকভাবে রেকর্ড করা হবে৷"</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"টিউনার না থাকার কারণে রেকর্ড করা হবে না৷"</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"এখনো পর্যন্ত কোনো রেকর্ডিংয়ের জন্য সময়সূচী নির্ধারণ করা হয়নি।\nআপনি প্রোগ্রাম গাইড থেকে রেকর্ডিংয়ের সময়সূচী নির্ধারণ করতে পারেন।"</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="one">%1$dটি রেকডিং দ্বন্দ্ব</item>
+ <item quantity="other">%1$dটি রেকডিং দ্বন্দ্ব</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"সিরিজ সেটিংস"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"সিরিজ রেকডিং শুরু করুন"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"সিরিজ রেকডিং বন্ধ করুন"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"সিরিজি রেকর্ড করা বন্ধ করতে চান?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"রেকর্ড করা পর্বগুলি DVR লাইব্রেরিতে উপলব্ধ থাকবে৷"</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"বন্ধ করুন"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"এখন কোনো পর্বের সম্প্রচার করা হচ্ছে না।"</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"কোনো পর্ব উপলব্ধ নেই।\nএকবার উপলব্ধ হলে সেগুলিকে রেকর্ড করা হবে।"</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="one">(%1$d মিনিট)</item>
+ <item quantity="other">(%1$d মিনিট)</item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"আজ"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"আগামীকাল"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"গতকাল"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"আজ <xliff:g id="TIME_RANGE">%1$s</xliff:g> টায়"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"আগামীকাল <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"স্কোর"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"রেকর্ড করা প্রোগ্রামগুলি"</string>
+</resources>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
deleted file mode 100644
index 52938ab2..00000000
--- a/res/values-bn/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"মোনো"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"স্টিরিও"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"খেলার নিয়ন্ত্রণগুলি"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"সাম্প্রতিক চ্যানেলগুলি"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"টিভি বিকল্পগুলি"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP বিকল্পগুলি"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"এই চ্যানেলটির জন্য প্লে নিয়ন্ত্রণগুলি অনুপলব্ধ"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"প্লে করুন বা বিরাম দিন"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"দ্রুত ফরওয়ার্ড"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"পেছনের দিকে যান"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"পরবর্তী"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"পূর্ববর্তী"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"প্রোগ্রাম গাইড"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"নতুন চ্যানেলগুলি উপলব্ধ"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> খুলুন"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"সাবটাইটেলগুলি"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"প্রদর্শন মোড"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"চালু"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"বন্ধ"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"একাধিক-অডিও"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"আরো চ্যানেল পান"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"সেটিংস"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"উৎস"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"সোয়াইপ করুন"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"চালু"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"বন্ধ"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"আওয়াজ"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"প্রধান"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP উইন্ডো"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"লেআউট"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"ডানদিকে নীচে"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"ডানদিকে শীর্ষে"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"বামদিকে শীর্ষে"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"বামদিকে নীচে"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"পাশাপাশি"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"আকার"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"বড়"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"ক্ষুদ্র"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"ইনপুট উৎস"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (অ্যান্টেনা/কেবল)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"কোনো প্রোগ্রাম তথ্য নেই"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"কোনো তথ্য নেই"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"অবরুদ্ধ চ্যানেল"</string>
- <string name="default_language" msgid="4122326459624337928">"অজানা ভাষা"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"সাবটাইটেলগুলি"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"বন্ধ করুন"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"ফর্ম্যাটিং কাস্টমাইজ করুন"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"সাবটাইটেলগুলির জন্য সিস্টেম-ব্যাপী পছন্দগুলি সেট করুন"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"প্রদর্শন মোড"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"একাধিক-অডিও"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"মনো"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"স্টিরিও"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"৫.১ সারাউন্ড"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"৭.১ সারাউন্ড"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d চ্যানেলগুলি"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"চ্যানেল তালিকা কাস্টমাইজ করুন"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"গোষ্ঠী নির্বাচন করুন"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"গোষ্ঠী নির্বাচন মুক্ত করুন"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"এর ভিত্তিতে গোষ্ঠীভুক্ত করুন"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"চ্যানেল উৎস"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"এর ভিত্তিতে গোষ্ঠীভুক্ত করুন"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"এই প্রোগ্রামটি অবরুদ্ধ করা হয়েছে"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"এই প্রোগ্রামটি <xliff:g id="RATING">%1$s</xliff:g> রেট প্রাপ্ত৷"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"ইনপুটটি অটো-স্ক্যান সমর্থন করে না"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' এর জন্য স্বয়ংক্রিয়-স্ক্যান শুরু করা যায়নি"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"সাবটাইটেলগুলির জন্য সিস্টেম-ব্যাপী পছন্দগুলি শুরু করা যায়নি৷"</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="one">%1$dটি চ্যানেল যোগ করা হয়েছে</item>
- <item quantity="other">%1$dটি চ্যানেল যোগ করা হয়েছে</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"কোনো চ্যানেল যোগ করা হয়নি"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ট্যিউনার"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"অভিভাবকীয় নিয়ন্ত্রণগুলি"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"চালু করুন"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"বন্ধ করুন"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"অবরুদ্ধ চ্যানেলগুলি"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"সবগুলি অবরুদ্ধ করুন"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"সবগুলিকে অবরোধ মুক্ত করুন"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"লুকানো চ্যানেলগুলি"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"প্রোগ্রামের বিধিনিষেধগুলি"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"পিন পরিবর্তন করুন"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"রেটিং পদ্ধতি"</string>
- <string name="option_ratings" msgid="4009116954188688616">"রেটিংগুলি"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"রেটিংয়ের সমস্ত পদ্ধতি দেখুন"</string>
- <string name="other_countries" msgid="8342216398676184749">"অন্যান্য দেশ"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"একটিও নেই"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"কোনো কিছুই নেই"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"কোনো কিছুই নেই"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"উচ্চ মাত্রার বিধিনিষেধগুলি"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"মাঝারি মাত্রার বিধিনিষেধগুলি"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"কম মাত্রার বিধিনিষেধগুলি"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"কাস্টম"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"শিশুদের জন্য উপযুক্ত সামগ্রী"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"বয়স্ক শিশুদের জন্য উপযুক্ত সামগ্রী"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"তেরো থেকে উনিশ বছর বয়সীদের জন্য উপযুক্ত সামগ্রী"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"নিজে করা সম্পর্কিত বিধিনিষেধগুলি"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s এবং উপ-রেটিংগুলি"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"উপ-রেটিংগুলি"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"এই চ্যানেলটি দেখতে আপনার পিন লিখুন"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"এই প্রোগ্রামটি দেখতে আপনার পিন লিখুন"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"এই প্রোগ্রামটি <xliff:g id="RATING">%1$s</xliff:g> রেটপ্রাপ্ত। এই প্রোগ্রামটি দেখার জন্য আপনার PIN লিখুন।"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"আপনার পিন লিখুন"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"অভিভাবকীয় নিয়ন্ত্রণগুলি সেট করতে, একটি পিন তৈরি করুন"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"নতুন পিন লিখুন"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"আপনার পিন নিশ্চিত করুন"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"আপনার বর্তমান পিন লিখুন"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="one">আপনি ৫ বার ভুল পিন প্রবেশ করিয়েছেন।\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।</item>
- <item quantity="other">আপনি ৫ বার ভুল পিন প্রবেশ করিয়েছেন।\n <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"এই PINটি ভুল ছিল৷ আবার চেষ্টা করুন৷"</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"আবার চেষ্টা করুন, পিন মেলেনি"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"সেটিংস"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"চ্যানেল তালিকা কাস্টমাইজ করুন"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"আপনার প্রোগ্রাম গাইডের জন্য চ্যানেলগুলি নির্বাচন করুন"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"চ্যানেলের উৎসগুলি"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"নতুন চ্যানেলগুলি উপলব্ধ"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"অভিভাবকীয় নিয়ন্ত্রণগুলি"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"মুক্ত উৎস লাইসেন্সগুলি"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"মুক্ত উৎস লাইসেন্সগুলি"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"সংস্করণ"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"এই চ্যানেলটিকে দেখতে, ডানদিকে চাপুন এবং আপনার পিন লিখুন"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"এই প্রোগ্রামটি দেখতে, ডানদিকে চাপুন এবং আপনার পিন লিখুন"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"এই প্রোগ্রামটি <xliff:g id="RATING">%1$s</xliff:g> রেট প্রাপ্ত৷\nএই প্রোগ্রামটি দেখতে, ডানদিকে চাপুন এবং আপনার পিন লিখুন"</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"এই চ্যানেলটি দেখতে, ডিফল্ট লাইভ টিভি অ্যাপ্লিকেশানটি ব্যবহার করুন৷"</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"এই প্রোগ্রামটি দেখতে, ডিফল্ট লাইভ টিভি অ্যাপ্লিকেশানটি ব্যবহার করুন৷"</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"এই প্রোগ্রামটি <xliff:g id="RATING">%1$s</xliff:g> রেট প্রাপ্ত৷\nএই প্রোগ্রামটি দেখতে, ডিফল্ট লাইভ টিভি অ্যাপ্লিকেশানটি ব্যবহার করুন৷"</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"প্রোগ্রামটি অবরুদ্ধ"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"এই প্রোগ্রামটি <xliff:g id="RATING">%1$s</xliff:g> রেট প্রাপ্ত৷"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"কেবলমাত্র অডিও"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"সিগন্যাল দুর্বল"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"কোনো ইন্টারনেট সংযোগ নেই"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="one"><xliff:g id="END_TIME_1">%1$s</xliff:g>পর্যন্ত এই চ্যালেনটি চালানো যাবে না কারণ অন্যান্য চ্যানেলগুলি রেকর্ড করা হচ্ছে৷ \n\nরেকর্ড করার সময়সূচী সামঞ্জস্য করতে ডান দিকে ক্লিক করুন৷</item>
- <item quantity="other"><xliff:g id="END_TIME_1">%1$s</xliff:g>পর্যন্ত এই চ্যালেনটি চালানো যাবে না কারণ অন্যান্য চ্যানেলগুলি রেকর্ড করা হচ্ছে৷ \n\nরেকর্ড করার সময়সূচী সামঞ্জস্য করতে ডান দিকে ক্লিক করুন৷</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"কোনো শিরোনাম নেই"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"চ্যানেল অবরুদ্ধ করা হয়েছে"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"নতুন"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"উৎসগুলি"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="one">%1$dটি চ্যানেল</item>
- <item quantity="other">%1$dটি চ্যানেল</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"কোনো চ্যানেল উপলব্ধ নেই"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"নতুন"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"সেট আপ করা নেই"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"আরো উৎস পান"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"লাইভ চ্যানেল অফার করে এমন অ্যাপ্স ব্রাউজ করুন"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"নতুন চ্যানেলের সূত্রগুলি উপলব্ধ রয়েছে"</string>
- <string name="new_sources_description" msgid="749649005588426813">"নতুন চ্যানেলের সূত্রগুলিতে প্রদান করার জন্য চ্যানেল রয়েছে।\nসেগুলিকে এখনই সেট আপ করুন, বা চ্যানের সূত্রের সেটিংয়ের মধ্যে পরে এটি করুন।"</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"এখনই সেট আপ করুন"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"ঠিক আছে, বুঝেছি"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"টিভি মেনু অ্যাক্সেস করতে "<b>"নির্বাচন করুন টিপুন"</b>"৷"</string>
- <string name="msg_no_input" msgid="3897674146985427865">"কোনো TV ইনপুট খুঁজে পাওয়া যায়নি"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"TV ইনপুট খুঁজে পাওয়া যায়নি"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP সমর্থিত নয়"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP এর সাথে দেখানো যেতে পারে এমন কোনো উপলব্ধ ইনপুট নেই"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"টিউনারের প্রকারটি উপযুক্ত নয়; টিউনার প্রকারের টিভি ইনপুটের জন্য দয়া করে লইভ চ্যানেলগুলি অ্যাপ্লিকেশানটি লঞ্চ করুন৷"</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"টিউন করা ব্যর্থ হয়েছে"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"এই ক্রিয়াটিকে চালনা করার জন্য কোনো অ্যাপ্লিকেশান পাওয়া যায়নি৷"</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"সমস্ত উৎস চ্যানেল লুকানো আছে৷\nদেখার জন্য কমপক্ষে একটি চ্যানেল নির্বাচন করুন৷"</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ভিডিওটি অপ্রত্যাশিতভাবে অনুপলব্ধ"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"\'ব্যাক\' কীটি সংযুক্ত ডিভাইসের ক্ষেত্রে ব্যবহারের জন্য৷ প্রস্থান করতে হোম বোতামটি টিপুন৷"</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"টিভির তালিকাগুলি পড়ার জন্য লাইভ চ্যানেলগুলিকে অনুমতি নিতে হবে।"</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"আপনার উৎসগুলি সেট আপ করুন"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"লাইভ চ্যানেলগুলি অ্যাপ্লিকেশানগুলির দ্বারা সরবরাহ করা স্ট্রিমিং চ্যানেলের সঙ্গে ঐতিহ্যগত টিভি চ্যানেলের সম্মিলিত অভিজ্ঞতা প্রদান করে৷ \n\nইতিমধ্যেই ইনস্টল থাকা চ্যানেল উৎসগুলি সেট আপ করার মাধ্যেমে শুরু করুন৷ অথবা লাইভ চ্যানেলগুলি অফার করে এমন অ্যাপ্লিকেশানগুলি পেতে Google Play স্টোর ব্রাউজ করুন৷"</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"রেকডিং &amp; সময়সূচী"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"১০ মিনিট"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"৩০ মিনিট"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"১ ঘণ্টা"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"৩ ঘণ্টা"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"সাম্প্রতিক"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"নির্ধারিত"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"সিরিজ"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"অন্যরা"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"চ্যানেলটি রেকর্ড করা যাবে না৷"</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"প্রোগ্রামটি রেকর্ড করা যাবে না৷"</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> রেকর্ড করার সময় নির্ধারিত হয়েছে"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>কে এখান থেকে <xliff:g id="ENDTIME">%2$s</xliff:g> পর্যন্ত রেকর্ড করা হচ্ছে"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"সম্পূর্ণ সময়সূচী"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="one">পরবর্তী %1$d দিন</item>
- <item quantity="other">পরবর্তী %1$d দিন</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="one">%1$d মিনিট</item>
- <item quantity="other">%1$d মিনিট</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="one">%1$dটি নতুন রেকডিং</item>
- <item quantity="other">%1$dটি নতুন রেকডিং</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="one">%1$dটি রেকর্ডিং</item>
- <item quantity="other">%1$dটি রেকর্ডিং</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="one">%1$dটি রেকর্ডিংয়ের সময় নির্ধারিত হয়েছে</item>
- <item quantity="other">%1$dটি রেকর্ডিংয়ের সময় নির্ধারিত হয়েছে</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"দেখুন"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"শুরু থেকে প্লে করুন"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"পুনরায় প্লে করুন"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"মুছুন"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"রেকডিংগুলি মুছুন"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"পুনরায় শুরু করুন"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"সিজন <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"সময়সূচী দেখুন"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"আরো পড়ুন"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"রেকডিংগুলি মুছুন"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"আপনি যে পর্বগুলিকে মুছতে চান সেগুলিকে নির্বাচন করুন। একবার মোছা হলে সেগুলিকে পুনরুদ্ধার করা যাবে না।"</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"মোছার জন্য সেখানে কোনো রেকডিং নেই।"</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"দেখা পর্বগুলিকে নির্বাচন করুন"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"সমস্ত পর্ব নির্বাচন করুন"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"সমস্ত পর্ব নির্বাচন মুক্ত করুন"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> এর মধ্যে <xliff:g id="WATCHED">%1$d</xliff:g> মিনিট দেখা হয়েছে"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> এর মধ্যে <xliff:g id="WATCHED">%1$d</xliff:g> সেকেন্ড দেখা হয়েছে"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"কখনই দেখা হয়নি"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="one">%2$dটির মধ্যে %1$dটি পর্ব মোছা হয়েছে</item>
- <item quantity="other">%2$dটির মধ্যে %1$dটি পর্ব মোছা হয়েছে</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"অগ্রাধিকার"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"সর্বোচ্চ"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"সর্বনিম্ন"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"না৷ <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"চ্যানেল"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"যে কোনো"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"অগ্রাধিকার চয়ন করুন"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"যখন একই সময়ে অনেকগুলি প্রোগ্রাম রেকর্ড করা হয় তখন শুধুমাত্র উচ্চ অগ্রাধিকারযুক্ত প্রোগ্রামগুলিকে রেকর্ড করা হবে৷"</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"সংরক্ষণ করুন"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"একবার করা রেকর্ডিংগুলিতে সর্বোচ্চ অগ্রাধিকার রয়েছে"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"বাতিল করুন"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"বাতিল করুন"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"মুছে দিন"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"থামান"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"রেকডিং এর সময়সূচী দেখুন"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"শুধুমাত্র এই প্রোগ্রামটি"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"এখন - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"সম্পূর্ণ সিরিজ…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"যাই হোক, সময়সূচি নির্ধারণ করুন"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"বরং এটি রেকর্ড করুন"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"এই রেকর্ডিং বাতিল করুন"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"এখনই দেখুন"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"রেকর্ড করা যাবে"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"রেকর্ডিংএর সময় নির্ধারিত হয়েছে"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"রেকর্ডিং দ্বন্দ্ব"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"রেকর্ড করা হচ্ছে"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"রেকডিং করা গেল না"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"রেকর্ডিংয়ের সময়সূচীগুলি তৈরি করতে প্রোগ্রামগুলি পড়া হচ্ছে"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"প্রোগ্রামগুলি পড়া হচ্ছে"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR এর আরো সঞ্চয়স্থান দরকার"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"আপনি DVR এর মাধ্যমে প্রোগ্রাম রেকর্ড করতে পারবেন৷ তবে DVR কাজ করার জন্য আপনার ডিভাইসে এখন যথেষ্ঠ সঞ্চয়স্থান নেই৷ অনুগ্রহ করে <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB বা তার থেকে বড় আকারের কোনো বাহ্যিক ডিভাইসের সাথে সংযোগ করুন এবং ডিভাইসের সঞ্চয়স্থান হিসাবে ফর্ম্যাট করতে পদক্ষেপগুলি অনুসরণ করুন৷"</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"সঞ্চয়স্থান অনুপস্থিত"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR দ্বারা ব্যবহৃত কিছু সঞ্চয়স্থান অনুপস্থিত৷ DVR পুনরায় সক্ষম করার আগে অনুগ্রহ করে আপনার আগে ব্যবহার করা বাহ্যিক ড্রাইভ সংযোগ করুন৷ অথবা, যদি সঞ্চয়স্থানটি আর উপলব্ধ না থাকে তবে আপনি সেটিকে মুছে দিতে পারবেন৷"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"সঞ্চয়স্থান মুছতে চান?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"আপনার রেকর্ড করা সমস্ত সামগ্রী এবং সময়সূচী মুছে যাবে৷"</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"রেকর্ড করা থামাবেন?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"রেকর্ড করা সামগ্রী সংরক্ষণ করা হবে৷"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"রেকর্ডিংয়ের যে সময় নির্ধারিত করা হয়েছে তাতে অন্যদের সমসয়ের সাথে বিরোধ ঘটাতে পারে।"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"রেকর্ডিং শুরু হয়েছে কিন্তু দ্বন্দ্বগুলি রয়েছে"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> রেকর্ড করা হবে৷"</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> রেকর্ড করা হচ্ছে৷"</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> এর কিছু অংশ রেকর্ড করা হবে না৷"</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> এবং <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> এর কিছু অংশ রেকর্ড করা হবে না৷"</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>এর কিছু অংশ এবং আরো একটি সময়সূচী রেকর্ড করা হবে না৷"</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="one"> <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> এর কিছু অংশ এবং আরো %3$dটি সময়সূচী রেকর্ড করা হবে না৷</item>
- <item quantity="other"> <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> এর কিছু অংশ এবং আরো %3$dটি সময়সূচী রেকর্ড করা হবে না৷</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"আপনি কি রেকর্ড করতে চান?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"আপনি কতক্ষন রেকর্ড করতে চান?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ইতিমধ্যে সময়সূচী নির্ধারণ করা হয়েছে"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"একই প্রোগ্রাম ইতিমধ্যেই <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> এ রেকর্ড করার জন্য নির্ধারণ করা হয়েছে।"</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ইতিমধ্যে রেকর্ড করা হয়েছে"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"এই প্রোগ্রামটি ইতিমধ্যে রেকর্ড করা হয়েছে। এটি DVR লাইব্রেরিতে উপলব্ধ।"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"রেকর্ড করা প্রোগ্রাম খুঁজে পাওয়া যায়নি৷"</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"সম্পর্কিত রেকর্ডিং"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(প্রোগ্রামের কোনো বিবরণ নেই)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="one">%1$dটি রেকর্ডিং</item>
- <item quantity="other">%1$dটি রেকর্ডিং</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"রেকর্ড করার সময়সূচী থেকে <xliff:g id="PROGRAMNAME">%1$s</xliff:g> সরানো হয়েছে"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"টিউনার না থাকার কারণে আংশিকভাবে রেকর্ড করা হবে৷"</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"টিউনার না থাকার কারণে রেকর্ড করা হবে না৷"</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"এখনো পর্যন্ত কোনো রেকর্ডিংয়ের জন্য সময়সূচী নির্ধারণ করা হয়নি।\nআপনি প্রোগ্রাম গাইড থেকে রেকর্ডিংয়ের সময়সূচী নির্ধারণ করতে পারেন।"</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="one">%1$dটি রেকডিং দ্বন্দ্ব</item>
- <item quantity="other">%1$dটি রেকডিং দ্বন্দ্ব</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"সিরিজ সেটিংস"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"সিরিজ রেকডিং শুরু করুন"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"সিরিজ রেকডিং বন্ধ করুন"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"সিরিজি রেকর্ড করা বন্ধ করতে চান?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"রেকর্ড করা পর্বগুলি DVR লাইব্রেরিতে উপলব্ধ থাকবে৷"</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"বন্ধ করুন"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"কোনো পর্ব উপলব্ধ নেই।\nএকবার উপলব্ধ হলে সেগুলিকে রেকর্ড করা হবে।"</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="one">(%1$d মিনিট)</item>
- <item quantity="other">(%1$d মিনিট)</item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"আজ"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"আগামীকাল"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"গতকাল"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"আজ <xliff:g id="TIME_RANGE">%1$s</xliff:g> টায়"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"আগামীকাল <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"স্কোর"</string>
-</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 3ab61ffb..e26cc99d 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"estèreo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Controls de reproducció"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Canals recents"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Canals"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Opcions de TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opcions de PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Els controls de reproducció no estan disponibles en aquest canal"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Reprodueix o atura"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Avança ràpidament"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Subtítols"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Mode visualitz."</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Activada"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Desactivada"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multiàudio"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Obtén més canals"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Troba més canals"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Configuració"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Font"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Canvia"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Activada"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Desactivada"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"So"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Principal"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Finestra PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Disseny"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"A baix a dreta"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"A dalt a dreta"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"A dalt a esq."</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"A baix a esq."</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"En paral·lel"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Mida"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Gran"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Petita"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Font d\'entrada"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"Televisió (antena/cable)"</string>
<string name="no_program_information" msgid="1049844207745145132">"No hi ha informació del programa"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"No hi ha informació"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Canal bloquejat"</string>
- <string name="default_language" msgid="4122326459624337928">"Idioma desconegut"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Idioma desconegut"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Subtítols en %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Subtítols ocults"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Desactivat"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Personalitza format"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Agrupa per"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Aquest programa està bloquejat"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Aquest programa no s\'ha classificat"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Aquest programa està classificat com a <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"L\'entrada no és compatible amb la cerca automàtica."</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"No es pot iniciar la cerca automàtica de: <xliff:g id="TV_INPUT">%s</xliff:g>."</string>
@@ -92,7 +74,6 @@
<item quantity="one">S\'ha afegit %1$d canal</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"No s\'ha afegit cap canal."</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Sintonitzador"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Controls dels pares"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Activats"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Desactivats"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Altres països"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Cap"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Cap"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Sense classificar"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Bloqueja prog. sense classificar"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Cap"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Restriccions altes"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Restricc. mitjanes"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Introducció del PIN per mirar aquest canal"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Introducció del PIN per mirar aquest programa"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Aquest programa està classificat com a <xliff:g id="RATING">%1$s</xliff:g>. Introdueix el PIN per mirar-lo"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Aquest programa no s\'ha classificat. Introdueix el PIN per veure\'l."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Introducció del PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Per definir els controls dels pares, crea un PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Introdueix el PIN nou"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"El PIN era incorrecte. Torna-ho a provar."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Torna-ho a provar. El PIN no coincideix."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Introdueix el codi postal."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"L\'aplicació TV en directe farà servir el codi postal per oferir una programació completa dels canals de televisió."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Introdueix el codi postal"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"El codi postal no és vàlid"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Configuració"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personalitza la llista de canals"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Tria canals per a la programació"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Fonts de canals"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nous canals disponibles"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Controls parentals"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Desplaçament temporal"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Enregistra els programes en directe mentre els mires per poder-los posar en pausa o rebobinar.\nAdvertiment: aquesta opció suposa un ús intens de l\'emmagatzematge intern, i això en pot disminuir la vida útil."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Llicències de programari lliure"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Llicències de programari lliure"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Envia suggeriments"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versió"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Per veure aquest canal, prem el botó dret i introdueix el PIN."</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Per veure aquest programa, prem el botó dret i introdueix el PIN."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Aquest programa no s\'ha classificat.\nPer veure\'l, prem el botó dret i introdueix el PIN."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Aquest programa està classificat com a <xliff:g id="RATING">%1$s</xliff:g>.\nPer veure\'l, prem el botó dret i introdueix el PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Per mirar aquest canal, fes servir l\'aplicació Televisió en directe predeterminada."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Per mirar aquest programa, fes servir l\'aplicació Televisió en directe predeterminada."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Aquest programa no s\'ha classificat.\nPer veure\'l, utilitza l\'aplicació Televisió en directe predeterminada."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Aquest programa té la classificació següent: <xliff:g id="RATING">%1$s</xliff:g>.\nPer mirar-lo, fes servir l\'aplicació Televisió en directe predeterminada."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"El programa està bloquejat."</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Aquest programa no s\'ha classificat"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Aquest programa està classificat com a <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Només àudio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"El senyal és feble"</string>
@@ -169,8 +162,8 @@
</plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"No hi ha cap canal disponible"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nou"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"No s\'ha configurat"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Obtén més fonts"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"No configurat"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Troba més fonts"</string>
<string name="setup_store_action_description" msgid="6820482635042445297">"Navega per les aplicacions que ofereixen TV en directe"</string>
<string name="new_sources_title" msgid="3878933676500061895">"Hi ha noves fonts de canals disponibles"</string>
<string name="new_sources_description" msgid="749649005588426813">"Les noves fonts de canals tenen canals per oferir.\nConfigura-les ara o fes-ho més tard des de la seva secció de configuració."</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Prem SELECCIONA"</b>" per accedir al menú de TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"No s\'ha trobat cap entrada de televisió"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"No es troba l\'entrada de televisió"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"No s\'admet la funció PIP"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"No hi ha cap entrada disponible que es pugui mostrar amb PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"El sintonitzador no és apte; inicia l\'aplicació Canals en directe per accedir a l\'entrada del sintonitzador."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"No s\'ha pogut sintonitzar"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"No s\'ha trobat cap aplicació per processar aquesta acció."</string>
@@ -191,7 +182,7 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"La tecla ENRERE és per als dispositius connectats. Prem el botó INICI per sortir."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Canals en directe necessita permís per consultar les programacions de TV."</string>
<string name="setup_sources_text" msgid="4988039637873759839">"Configura les teves fonts"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"L\'aplicació TV en directe combina l\'experiència dels canals de televisió tradicionals amb els canals de reproducció en temps real proporcionats per les aplicacions. \n\nPer començar, configura les fonts de canals que ja hi ha instal·lades. També pots navegar per Google Play Store per descobrir més aplicacions que ofereixin TV en directe."</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"TV en directe combina l\'experiència dels canals de televisió tradicionals amb els canals de reproducció en temps real proporcionats per les aplicacions. \n\nPer començar, configura les fonts de canals que ja hi ha instal·lades. També pots navegar per Google Play Store per descobrir més aplicacions que ofereixin TV en directe."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Enregistraments i horaris"</string>
<string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minuts"</string>
<string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minuts"</string>
@@ -224,6 +215,8 @@
<item quantity="other">%1$d enregist. programats</item>
<item quantity="one">%1$d enregistr. programat</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Cancel·la l\'enregistrament"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Atura l\'enregistrament"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Reprodueix"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Reprodueix des del principi"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Reprèn la reproducció"</string>
@@ -256,9 +249,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Quan hi hagi massa programes per enregistrar a la mateixa hora, només s\'enregistraran els que tinguin una prioritat més elevada."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Desa"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Els enregistraments únics tenen la prioritat més alta"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Cancel·la"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Cancel·la"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"No recordis"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Atura"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Mostra programa d\'enregistrament"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Només aquest programa"</string>
@@ -268,25 +258,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Enregistra aquest programa"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Cancel·la aquest enregistrament"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Mira ara"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Suprimeix els enregistraments…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Enregistrable"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Enregistrament programat"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Conflicte d\'enregistrament"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"S\'està enregistrant"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Error d\'enregistrament"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"S\'estan llegint els programes per crear programacions d\'enregistrament"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"S\'estan llegint els programes"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"S\'estan llegint els programes"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Mostra els enregistraments recents"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"L\'enregistrament del programa <xliff:g id="PROGRAMNAME">%1$s</xliff:g> no s\'ha completat."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Els enregistraments dels programes <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> i <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> no s\'han completat."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Els enregistraments dels programes <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> i <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> no s\'han completat."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"L\'enregistrament del programa <xliff:g id="PROGRAMNAME">%1$s</xliff:g> no s\'ha completat perquè no hi ha prou espai d\'emmagatzematge."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Els enregistraments dels programes <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> i <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> no s\'han completat perquè no hi ha prou espai d\'emmagatzematge."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Els enregistraments dels programes <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> i <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> no s\'han completat perquè no hi ha prou espai d\'emmagatzematge."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"El DVR necessita més emmagatzematge"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Podràs· enregistrar· programes· amb· el· DVR.· No· obstant· això,· en· aquests· moments· no· tens· prou· emmagatzematge· al· dispositiu· perquè· el· DVR· pugui· funcionar.· Connecta· una· unitat· externa· que· tingui· com· a· mínim· <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB· d\'espai· disponible· i· segueix· els· passos· per· formatar-la· com· a· unitat· d\'emmagatzematge· del· dispositiu."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Podràs· enregistrar· programes· amb· el· DVR.· No· obstant· això,· en· aquests· moments· no· tens· prou· emmagatzematge· al· dispositiu· perquè· el· DVR· pugui· funcionar.· Connecta· una· unitat· externa· que· tingui· com· a· mínim· <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB· d\'espai· disponible· i· segueix· els· passos· per· formatar-la· com· a· unitat· d\'emmagatzematge· del· dispositiu."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"No hi ha prou espai d\'emmagatzematge"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Aquest programa no s\'enregistrarà perquè no hi ha prou espai d\'emmagatzematge. Prova de suprimir algun dels enregistraments actuals."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Falta el dispositiu d\'emmagatzematge"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Falta contingut emmagatzemat pel DVR. Connecta la unitat externa que utilitzaves abans per tornar a activar el DVR. Si el dispositiu d\'emmagatzematge ja no està disponible, pots optar perquè s\'oblidi."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Vols que s\'oblidi el dispositiu d\'emmagatzematge?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Tot el contingut i totes les agendes que tinguis desades es perdran."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Vols aturar l\'enregistrament?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"El contingut enregistrat es desarà."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"L\'enregistrament de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> s\'aturarà perquè entra en conflicte amb aquest programa. El contingut enregistrat es desarà."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Hi ha un enregistrament programat, però té conflictes"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"L\'enregistrament ha començat, però té conflictes"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> s\'enregistrarà."</string>
@@ -304,17 +297,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Ja s\'ha programat l\'enregistrament d\'aquest programa per a les <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Ja s\'ha enregistrat"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Aquest programa ja s\'ha enregistrat. El trobaràs a la biblioteca de DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"S\'ha programat l\'enregistrament de la sèrie"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">S\'han programat <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistraments de la sèrie <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one">S\'ha programat <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> enregistrament de la sèrie <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">S\'han programat <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistraments de la sèrie <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> no s\'enregistraran a causa d\'un conflicte.</item>
+ <item quantity="one">S\'ha programat <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> enregistrament de la sèrie <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. No s\'enregistrarà a causa d\'un conflicte.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">S\'han programat <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> enregistraments de la sèrie <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodis d\'aquesta i d\'altres sèries no s\'enregistraran a causa d\'un conflicte.</item>
+ <item quantity="one">S\'ha programat <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> enregistrament de la sèrie <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodis d\'aquesta i d\'altres sèries no s\'enregistraran a causa d\'un conflicte.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">S\'han programat <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistraments de la sèrie <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. No s\'enregistrarà un episodi d\'una altra sèrie a causa d\'un conflicte.</item>
+ <item quantity="one">S\'ha programat <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> enregistrament de la sèrie <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. No s\'enregistrarà un episodi d\'una altra sèrie a causa d\'un conflicte.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">S\'han programat <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> enregistraments de la sèrie <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. No s\'enregistraran <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodis d\'altres sèries a causa d\'un conflicte.</item>
+ <item quantity="one">S\'ha programat <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> enregistrament de la sèrie <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. No s\'enregistraran <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodis d\'altres sèries a causa d\'un conflicte.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"El programa enregistrat no s\'ha trobat."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Enregistraments relacionats"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Cap descripció del programa)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d enregistraments</item>
<item quantity="one">%1$d enregistrament</item>
@@ -334,6 +339,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Vols aturar l\'enregistrament de la sèrie?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Els episodis enregistrats continuaran estant disponibles a la biblioteca de DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Atura"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"En aquest moment no s\'està emetent cap episodi en directe."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"No hi ha episodis disponibles.\nS\'enregistraran quan estiguin disponibles."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minuts)</item>
@@ -345,4 +351,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Avui, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Demà, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Puntuació"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programes enregistrats"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 6dac1751..c69c38f7 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Ovládání přehrávání"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Poslední kanály"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanály"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Možnosti TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Možnosti PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Ovládací prvky přehrávání pro tento kanál nejsou k dispozici"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Přehrát nebo pozastavit"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Přetočit vpřed"</string>
@@ -30,42 +29,24 @@
<string name="play_controls_description_skip_next" msgid="1603587562124694592">"Další"</string>
<string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Předchozí"</string>
<string name="channels_item_program_guide" msgid="2889807207930678418">"Programový průvodce"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Jsou dostupné nové kanály"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Dostupné nové kanály"</string>
<string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Spustit aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="options_item_closed_caption" msgid="5945274655046367170">"Skryté titulky"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Režim zobrazení"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Zapnuto"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Vypnuto"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"Obraz v obraze"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Vícekanál. zvuk"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Další kanály"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Nastavení"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Zdroj"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Zaměnit"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Zapnuto"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Vypnuto"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Zvuk"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Hlavní"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Okno PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Rozvržení"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Vpravo dole"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Vpravo nahoře"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Vlevo nahoře"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Vlevo dole"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Vedle sebe"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Rozměry"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Velké"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Malé"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Zdroj vstupu"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (anténa/kabel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Žádné informace o programu"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Žádné informace"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blokovaný kanál"</string>
- <string name="default_language" msgid="4122326459624337928">"Neznámý jazyk"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Neznámý jazyk"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Skryté titulky: %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Skryté titulky"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Vypnuto"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Nastavit formátování"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Zadání sys. předvoleb pro skryté titulky"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Systémová nastavení pro skryté titulky"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"Režim zobrazení"</string>
<string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Vícekanál. zvuk"</string>
<string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Seskupit podle"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Tento program je blokován."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Tento program nemá hodnocení"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Tento program má hodnocení <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Vstup nepodporuje automatické vyhledávání"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Nelze spustit automatické vyhledávání vstupu <xliff:g id="TV_INPUT">%s</xliff:g>"</string>
@@ -94,7 +76,6 @@
<item quantity="one">Byl přidán %1$d kanál</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Bylo přidáno 0 kanálů"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Rodičovská ochrana"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Zapnuto"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Vypnuto"</string>
@@ -110,6 +91,8 @@
<string name="other_countries" msgid="8342216398676184749">"Ostatní země"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Žádný"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Žádný"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Bez hodnocení"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blokovat programy bez hodnocení"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Žádné"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Vysoké omezení"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Střední omezení"</string>
@@ -126,6 +109,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Chcete-li sledovat tento kanál, zadejte kód PIN."</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Chcete-li sledovat tento program, zadejte kód PIN."</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Tento program má hodnocení <xliff:g id="RATING">%1$s</xliff:g>. Chcete-li jej sledovat, zadejte kód PIN."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Tento program nemá hodnocení. Chcete-li ho sledovat, zadejte kód PIN."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Zadání kódu PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Chcete-li nastavit rodičovskou kontrolu, vytvořte kód PIN."</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Zadejte nový PIN"</string>
@@ -139,22 +123,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Kód PIN byl zadán chybně. Zkuste to znovu."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Kód PIN nesouhlasí. Zkuste to znovu."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Zadejte PSČ."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Aplikace Televize online vám na základě PSČ poskytne kompletního programového průvodce televizními kanály."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Zadejte PSČ"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Neplatné PSČ"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Nastavení"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Upravit seznam kanálů"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Vyberte kanály pro programového průvodce"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Zdroje kanálů"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"K dispozici jsou nové kanály"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Rodičovská ochrana"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Časový posun"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Umožňuje nahrávat při sledování, abyste mohli živě vysílané programy pozastavit nebo přetočit zpět.\nUpozornění: Funkce intenzivně využívá interní úložiště, a může tak snížit jeho životnost."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licence open source"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licence open source"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Odeslat zpětnou vazbu"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Verze"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Chcete-li tento kanál sledovat, stiskněte šipku vpravo a zadejte kód PIN."</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Chcete-li tento program sledovat, stiskněte šipku vpravo a zadejte kód PIN."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Tento program nemá hodnocení.\nChcete-li ho sledovat, stiskněte šipku vpravo a zadejte kód PIN."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Tento program má hodnocení <xliff:g id="RATING">%1$s</xliff:g>.\nChcete-li tento program sledovat, stiskněte šipku vpravo a zadejte kód PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Chcete-li tento kanál sledovat, použijte výchozí aplikaci Live TV."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Chcete-li tento program sledovat, použijte výchozí aplikaci Live TV."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Tento program nemá hodnocení.\nChcete-li ho sledovat, použijte výchozí aplikaci Live TV."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Tento program má hodnocení <xliff:g id="RATING">%1$s</xliff:g>.\nChcete-li tento program sledovat, použijte výchozí aplikaci Live TV."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Program je blokován"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Tento program nemá hodnocení"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Tento program má hodnocení <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Pouze zvuk"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Slabý signál"</string>
@@ -189,8 +182,6 @@
<string name="intro_description" msgid="7806473686446937307">"Chcete-li získat přístup k nabídce TV, "<b>"stiskněte SELECT"</b>"."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Nebyl nalezen žádný televizní vstup."</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Televizní vstup nebyl nalezen."</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Funkce PIP není podporována."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Není k dispozici vstup, který lze zobrazovat pomocí PIP."</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Typ tuneru není vhodný. Pro TV vstup typu tuneru spusťte aplikaci Televize online."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Ladění se nezdařilo."</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Aplikace potřebná k provedení této akce nebyla nalezena."</string>
@@ -244,6 +235,8 @@
<item quantity="other">%1$d naplánovaných nahrávek</item>
<item quantity="one">%1$d naplánovaná nahrávka</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Zrušit nahrávání"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Zastavit nahrávání"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Přehrát"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Přehrát od začátku"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Pokračovat v přehrávání"</string>
@@ -278,9 +271,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Když naplánujete nahrávání příliš mnoha programů, budou nahrány pouze programy s vyšší prioritou."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Uložit"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Jednorázová nahrávání mají nejvyšší prioritu"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Zrušit"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Zrušit"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Zapomenout"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Zastavit"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Zobrazit plán nahrávání"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Pouze tento program"</string>
@@ -290,25 +280,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Místo toho nahrát tento program"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Zrušit toto nahrávání"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Sledovat"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Smazat nahraný obsah…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Lze nahrát"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Nahrávání je naplánováno"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Konflikt nahrávání"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Nahrávání"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Nahrávání se nezdařilo"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Načítání programů za účelem vytvoření plánů nahrávání"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Načítání programů"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Načítání programů"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Zobrazit poslední nahrávky"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Program <xliff:g id="PROGRAMNAME">%1$s</xliff:g> se nepodařilo nahrát celý."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Programy <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> a <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> se nepodařilo nahrát celé."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Programy <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> a <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> se nepodařilo nahrát celé."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Nahrávání programu <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nebylo dokončeno z důvodu nedostatku místa v úložišti."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Nahrávání programů <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> a <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> nebylo dokončeno z důvodu nedostatku místa v úložišti."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Nahrávání programů <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> a <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> nebylo dokončeno z důvodu nedostatku místa v úložišti."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR potřebuje víc místa"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Programy bude možné nahrát pomocí DVR. Ve vašem zařízení však momentálně není dost místa, a DVR proto nebude fungovat. Zapojte externí úložiště o velikosti minimálně <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB a podle pokynů jej naformátujte jako úložiště zařízení."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Programy bude možné nahrát pomocí DVR. Ve vašem zařízení však momentálně není dost místa, a DVR proto nebude fungovat. Zapojte externí úložiště o velikosti minimálně <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB a podle pokynů jej naformátujte jako úložiště zařízení."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Nedostatek místa"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Tento program nebude nahrán z důvodu nedostatku místa. Zkuste smazat část nahraného obsahu."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Úložiště není dostupné"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Část úložiště, které využívá DVR, není dostupná. Před opětovnou aktivací DVR připojte externí disk. Pokud úložiště již není k dispozici, můžete jej zapomenout."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Zapomenout úložiště?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Veškerý nahraný obsah a plány nahrávání budou smazány."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Zastavit nahrávání?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Nahraný obsah bude uložen."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Nahrávání pořadu <xliff:g id="PROGRAMNAME">%1$s</xliff:g> bude zastaveno, protože je v konfliktu s tímto programem. Nahraný obsah bude uložen."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Nahrávání je naplánováno, ale obsahuje konflikty"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Nahrávání bylo zahájeno, ale obsahuje konflikty"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Nahraje se program <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
@@ -328,17 +321,39 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Nahrávání stejného programu již bylo naplánováno na <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Již nahráno"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Tento program již byl nahrán. Naleznete jej v knihovně DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Je naplánováno nahrávání pořadu"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="few">Byla naplánována <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="many">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="few">Byla naplánována <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Z důvodu konfliktů některá nahrávání nebudou provedena (celkem <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>).</item>
+ <item quantity="many">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Z důvodu konfliktů některá nahrávání nebudou provedena (celkem <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>).</item>
+ <item quantity="other">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Z důvodu konfliktů některá nahrávání nebudou provedena (celkem <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>).</item>
+ <item quantity="one">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Z důvodu konfliktů nahrávání nebude provedeno.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="few">Byla naplánována <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Z důvodu konfliktů nebudou nahrány epizody tohoto pořadu a jiných pořadů (celkem <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="many">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Z důvodu konfliktů nebudou nahrány epizody tohoto pořadu a jiných pořadů (celkem <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="other">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Z důvodu konfliktů nebudou nahrány epizody tohoto pořadu a jiných pořadů (celkem <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="one">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Z důvodu konfliktů nebudou nahrány epizody tohoto pořadu a jiných pořadů (celkem <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g>).</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="few">Byla naplánována <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Z důvodu konfliktů nebude nahrána 1 epizoda jiného pořadu.</item>
+ <item quantity="many">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Z důvodu konfliktů nebude nahrána 1 epizoda jiného pořadu.</item>
+ <item quantity="other">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Z důvodu konfliktů nebude nahrána 1 epizoda jiného pořadu.</item>
+ <item quantity="one">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Z důvodu konfliktů nebude nahrána 1 epizoda jiného pořadu.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="few">Byla naplánována <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Z důvodu konfliktů nebudou nahrány epizody jiných pořadů (celkem <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="many">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Z důvodu konfliktů nebudou nahrány epizody jiných pořadů (celkem <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="other">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Z důvodu konfliktů nebudou nahrány epizody jiných pořadů (celkem <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="one">Bylo naplánováno <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> nahrávání pořadu <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Z důvodu konfliktů nebudou nahrány epizody jiných pořadů (celkem <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g>).</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Nahraný program nebyl nalezen."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Související nahrávky"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Žádný popis programu)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="few">%1$d nahrávky</item>
<item quantity="many">%1$d nahrávky</item>
@@ -362,6 +377,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Zastavit nahrávání série?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Nahrané epizody zůstanou dostupné v knihovně DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Zastavit"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Momentálně nejsou vysílány žádné epizody."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Nejsou k dispozici žádné epizody.\nEpizody budou nahrány, až budou k dispozici."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="few">(%1$d minuty)</item>
@@ -375,4 +391,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Dnes v <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Zítra v <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Skóre"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Nahrané programy"</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index b053e77d..352f4c7a 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Afspilningsknapper"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Seneste kanaler"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"Tv-indstillinger"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP-muligheder"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanaler"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"Indstillinger for tv"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Afspilningsstyring er ikke tilgængeligt på denne kanal"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Afspil, eller sæt på pause"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Spol frem"</string>
@@ -30,38 +29,20 @@
<string name="play_controls_description_skip_next" msgid="1603587562124694592">"Næste"</string>
<string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Forrige"</string>
<string name="channels_item_program_guide" msgid="2889807207930678418">"Programguide"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Der er nye tilgængelige kanaler"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Nye tilgængelige kanaler"</string>
<string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Åbn <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="options_item_closed_caption" msgid="5945274655046367170">"Undertekster"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Format"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Til"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Fra"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"Integreret billede"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Flere lydspor"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Få flere kanaler"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Indstillinger"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Kilde"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Skift"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Til"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Fra"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Lyd"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Primær"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP-vindue"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Layout"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Nederst til højre"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Øverst til højre"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Øverst til venstre"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Nederst til venstre"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Side om side"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Størrelse"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Stor"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Lille"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Inputkilde"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"Tv (antenne/kabel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Ingen programoplysninger"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Ingen oplysninger"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blokeret kanal"</string>
- <string name="default_language" msgid="4122326459624337928">"Ukendt sprog"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Ukendt sprog"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Undertekster %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Undertekster"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Fra"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Tilpas formatering"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Gruppér efter"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Dette program er blokeret"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Dette program er ikke klassificeret"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Dette program er klassificereret som <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Dette input understøtter ikke automatisk scanning"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Automatisk scanning for \"<xliff:g id="TV_INPUT">%s</xliff:g>\" kunne ikke startes"</string>
@@ -92,7 +74,6 @@
<item quantity="other">%1$d kanaler blev tilføjet</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Ingen kanaler tilføjet"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Børnesikring"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Til"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Fra"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Andre lande"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Ingen"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ingen"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Ikke klassificeret"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Bloker programmer uden klassificering"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Ingen"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Høje begrænsninger"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Medium begrænsninger"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Angiv din pinkode for at se denne kanal"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Angiv din pinkode for at se dette program"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Dette program er klassificeret som <xliff:g id="RATING">%1$s</xliff:g>. Du skal indtaste din pinkode for at se programmet"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Dette program er ikke klassificeret. Indtast din pinkode for at se programmet"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Angiv din pinkode"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Angiv en pinkode for at aktivere børnesikring"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Angiv ny pinkode"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Pinkoden var forkert. Prøv igen."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Prøv igen. Pinkoden var forkert"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Angiv dit postnummer."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Appen Tv-kanaler bruger postnummeret til at levere en komplet tv-guide til tv-kanalerne."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Angiv dit postnummer"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Ugyldigt postnummer"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Indstillinger"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Tilpas kanallisten"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Vælg kanaler til din programoversigt"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanalkilder"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Der er nye tilgængelige kanaler"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nye tilgængelige kanaler"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Børnesikring"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Optag en direkte udsendelse, mens du ser den, så du kan sætte den på pause eller spole tilbage i den.\nAdvarsel! Denne intensive brug af den interne lagerplads kan reducere lagerpladsens levetid."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Open source-licenser"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Open source-licenser"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Send feedback"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Se denne kanal ved at trykke på højreknappen og angive din pinkode"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Se dette program ved at trykke på højreknappen og angive din pinkode"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Dette program er ikke klassificeret.\nDu kan se programmet ved at trykke på højreknappen og indtaste din pinkode"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Dette program er klassificereret som <xliff:g id="RATING">%1$s</xliff:g>.\nSe dette program ved at trykke på højreknappen og angive din pinkode"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Se denne kanal ved hjælp af standardappen til direkte tv."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Se dette program ved hjælp af standardappen til direkte tv."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Dette program er ikke klassificeret.\nDu kan se programmet ved at bruge standardappen til direkte tv."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Dette program er klassificeret som <xliff:g id="RATING">%1$s</xliff:g>.\nSe dette program ved hjælp af standardappen til direkte tv."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programmet er blokeret"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Dette program er ikke klassificeret"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Dette program er klassificereret som <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Kun lyd"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Svagt signal"</string>
@@ -168,11 +161,11 @@
<item quantity="other">%1$d kanaler</item>
</plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Der er ingen tilgængelige kanaler"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Nye"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Ny"</string>
<string name="setup_input_setup_now" msgid="1772000402336958967">"Ikke konfigureret"</string>
<string name="setup_store_action_title" msgid="4083402039720973414">"Få flere kilder"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Gennemse apps, der viser tv-kanaler"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Der er nye tilgængelige kanalkilder"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Find apps med tv-kanaler"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Nye tilgængelige kanalkilder"</string>
<string name="new_sources_description" msgid="749649005588426813">"Du kan få kanaler fra nye kanalkilder.\nKonfigurer dem nu, eller gør det senere i indstillingen for kanalkilder."</string>
<string name="new_sources_action_setup" msgid="177693761664016811">"Konfigurer nu"</string>
<string name="new_sources_action_skip" msgid="2501296961258184330">"OK, det er forstået"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Tryk på VÆLG"</b>" for at få adgang til TV-menuen."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Der blev ikke fundet noget tv-input"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Tv-inputtet blev ikke fundet"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP understøttes ikke"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Der er intet tilgængeligt input, som kan vises med PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tunertypen er uegnet. Åbn appen Tv-kanaler for at få tv-input fra tunertypen."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Tuningen mislykkedes"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Der blev ikke fundet nogen app, der kan håndtere denne handling."</string>
@@ -226,6 +217,8 @@
<item quantity="one">%1$d planlagt optagelse</item>
<item quantity="other">%1$d planlagte optagelser</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Annuller optagelse"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Stop optagelse"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Se"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Afspil fra begyndelsen"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Genoptag afspilning"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Når der er for mange programmer at optage på samme tid, er det kun programmer med højere prioritet, der optages."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Gem"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Engangsoptagelser har højest prioritet"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Annuller"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Annuller"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Glem"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Stop"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Tidsplan for optagelse"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Dette ene program"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Optag dette program i stedet for"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Annuller denne optagelse"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Se nu"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Slet optagelser…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Kan optages"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Optagelse er planlagt"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Modstridende optagelser"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Optager"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Optagelsen mislykkedes"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Læser programmer for at oprette tidsplaner for optagelse"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Læser programmer"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Læser programmer"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Se de seneste optagelser"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Optagelsen af <xliff:g id="PROGRAMNAME">%1$s</xliff:g> er ikke fuldført."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Optagelserne af <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> og <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> er ikke fuldført."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Optagelserne af <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> og <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> er ikke fuldført."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Optagelsen af <xliff:g id="PROGRAMNAME">%1$s</xliff:g> blev ikke fuldført, da der ikke var nok lagerplads."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Optagelserne af <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> og <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> blev ikke fuldført, da der ikke var nok lagerplads."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Optagelserne af <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> og <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> blev ikke fuldført, da der ikke var nok lagerplads."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR kræver mere lagerplads"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Du kan optage programmer med DVR. Der er dog ikke længere nok lagerplads på din enhed til at DVR kan fungere. Tilslut et eksternt drev på mindst <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB, og følg vejledningen i, hvordan du formaterer det som internt lager."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Du kan optage programmer med DVR. Der er dog ikke længere nok lagerplads på din enhed til at DVR kan fungere. Tilslut et eksternt drev på mindst <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB, og følg vejledningen i, hvordan du formaterer det som internt lager."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Der er ikke nok lagerplads"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Dette program kan ikke optages, fordi der ikke er nok lagerplads. Prøv at slette nogle eksisterende optagelser."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Lager mangler"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Noget af det lager, der bruges af DVR, mangler. Tilslut det eksterne drev, du brugte før, for at genaktivere DVR. Alternativt kan du vælge at glemme lageret, hvis det ikke længere er tilgængeligt."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Vil du glemme lageret?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Du mister alt dit optagede indhold og dine tidsplaner."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Skal optagelsen stoppes?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Det optagede indhold gemmes."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Optagelsen af <xliff:g id="PROGRAMNAME">%1$s</xliff:g> stoppes, fordi den falder sammen med dette program. Det indhold, der er optaget, vil blive gemt."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Optagelsen er planlagt, men der er konflikter"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Optagelsen er startet, men der er konflikter"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> optages."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"En optagelse af dette program er allerede planlagt kl. <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Det er allerede optaget"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Dette program er allerede optaget. Du kan finde det i DVR-samlingen."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Optagelsen er planlagt"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one">Der er planlagt <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> optagelse af <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other">Der er planlagt <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> optagelser af <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one">Der er planlagt <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> optagelse af <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> optages ikke på grund af konflikter.</item>
+ <item quantity="other">Der er planlagt <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> optagelser af <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> af dem optages ikke på grund af konflikter.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one">Der er planlagt <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> optagelse af <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> afsnit af denne og andre serier optages ikke på grund af konflikter.</item>
+ <item quantity="other">Der er planlagt <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> optagelser af <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> afsnit af denne og andre serier optages ikke på grund af konflikter.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one">Der er planlagt <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> optagelse af <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 afsnit af en anden serie optages ikke på grund af konflikter.</item>
+ <item quantity="other">Der er planlagt <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> optagelser af <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 afsnit af en anden serie optages ikke på grund af konflikter.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one">Der er planlagt <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> optagelse af <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> afsnit af andre serier optages ikke på grund af konflikter.</item>
+ <item quantity="other">Der er planlagt <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> optagelser af <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> afsnit af andre serier optages ikke på grund af konflikter.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Det optagede program blev ikke fundet."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Relaterede optagelser"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Ingen programbeskrivelse)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d optagelse</item>
<item quantity="other">%1$d optagelser</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Vil du stoppe optagelsen af serien?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Optagede afsnit kan findes i DVR-samlingen."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Stop"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Der optages ingen afsnit lige nu."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Der er ingen tilgængelige tv-serier.\nDe optages, så snart de er tilgængelige.."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d minut)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> i dag"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> i morgen"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Resultat"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Optagede programmer"</string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index b4cc6c0f..32a1b486 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"Mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"Stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Wiedergabesteuerung"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Letzte Kanäle"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanäle"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV-Optionen"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP-Optionen"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Wiedergabesteuerung für diesen Kanal nicht verfügbar"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Abspielen oder pausieren"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Vorspulen"</string>
@@ -35,37 +34,19 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Untertitel"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Anzeigemodus"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"An"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Aus"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-Audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Mehr Kanäle erhalten"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Einstellungen"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Quelle"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Wechseln"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"An"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Aus"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Ton"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Hauptoption"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP-Fenster"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Layout"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Unten rechts"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Oben rechts"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Oben links"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Unten links"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Nebeneinander"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Größe"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Groß"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Klein"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Eingangsquelle"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (Antenne/Kabel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Keine Programminformationen"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Keine Informationen"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blockierter Kanal"</string>
- <string name="default_language" msgid="4122326459624337928">"Unbekannte Sprache"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Unbekannte Sprache"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Untertitel für %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Untertitel"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Aus"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Untertitel anpassen"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Systemübergr. Einst. für Untertitel festlegen"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Systemweite Einstellungen für Untertitel festlegen"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"Anzeigemodus"</string>
<string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multi-Audio"</string>
<string name="multi_audio_channel_mono" msgid="6229173848963557723">"Mono"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Gruppieren nach"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Diese Sendung ist blockiert."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Diese Sendung hat keine Altersempfehlung"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Diese Sendung wurde als \"<xliff:g id="RATING">%1$s</xliff:g>\" eingestuft."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Der Eingang unterstützt keine automatische Suche."</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Automatische Suche für \"<xliff:g id="TV_INPUT">%s</xliff:g>\" kann nicht gestartet werden."</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d Kanal hinzugefügt</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Keine Kanäle hinzugefügt"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Jugendschutz"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"An"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Aus"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Andere Länder"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Keiner"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ohne"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Ohne Altersempfehlung"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Sendungen ohne Altersempfehlung blockieren"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Ohne"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Hohe Einschränkung"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Mäßige Einschränkung"</string>
@@ -124,40 +107,50 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Zum Ansehen dieses Kanals PIN eingeben"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Zum Ansehen dieses Programms PIN eingeben"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Diese Sendung wurde als \"<xliff:g id="RATING">%1$s</xliff:g>\" eingestuft. Gib deinen PIN ein, um sie anzusehen"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Diese Sendung hat keine Altersempfehlung. Gib deine PIN ein, um sie anzusehen."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"PIN eingeben"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Erstellen Sie eine PIN, um den Jugendschutz einzurichten."</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Erstelle eine PIN, um den Jugendschutz einzurichten."</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Neue PIN eingeben"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"PIN bestätigen"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Aktuelle PIN eingeben"</string>
<plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">Sie haben die PIN zum fünften Mal falsch eingegeben.\nVersuchen Sie es in <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> Sekunden noch einmal.</item>
- <item quantity="one">Sie haben die PIN zum fünften Mal falsch eingegeben.\nVersuchen Sie es in <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> Sekunde noch einmal.</item>
+ <item quantity="other">Du hast die PIN zum fünften Mal falsch eingegeben.\nVersuche es in <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> Sekunden noch einmal.</item>
+ <item quantity="one">Du hast die PIN zum fünften Mal falsch eingegeben.\nVersuche es in <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> Sekunde noch einmal.</item>
</plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"Diese PIN war falsch. Versuchen Sie es erneut."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Die PIN stimmt nicht. Bitte versuchen Sie es erneut."</string>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"Diese PIN war falsch. Versuche es erneut."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Die PIN stimmt nicht. Bitte versuche es erneut."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Gib deine Postleitzahl ein."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Die Live TV App verwendet die Postleitzahl, um dir die vollständige Programmübersicht der TV-Sender zur Verfügung zu stellen."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Postleitzahl eingeben"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Ungültige Postleitzahl"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Einstellungen"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Kanalliste anpassen"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Kanäle für Programmübersicht auswählen"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanalquellen"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Neue Kanäle verfügbar"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Jugendschutzeinstellungen"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Zeitversetztes Fernsehen"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Wenn du Programme aufnimmst, während du sie dir live ansiehst, kannst du sie pausieren oder zurückspulen.\nWarnung: Dies führt durch die intensive Speichernutzung möglicherweise zu einer verringerten Lebensdauer des internen Speichers."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Open-Source-Lizenzen"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Open-Source-Lizenzen"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Feedback geben"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Um sich diesen Kanal anzusehen, drücken Sie rechts und geben Sie die PIN ein."</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Um sich dieses Programm anzusehen, drücken Sie rechts und geben Sie die PIN ein."</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Diese Sendung wurde als \"<xliff:g id="RATING">%1$s</xliff:g>\" eingestuft.\nUm sich diese Sendung anzusehen, drücken Sie rechts und geben Sie Ihre PIN ein."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Um sich diesen Kanal anzusehen, verwenden Sie die Standard-App für die Liveverfolgung von TV-Sendungen."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Um sich dieses Programm anzusehen, verwenden Sie die Standard-App für die Liveverfolgung von TV-Sendungen."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Diese Sendung wurde als \"<xliff:g id="RATING">%1$s</xliff:g>\" eingestuft.\nUm sich diese Sendung anzusehen, verwenden Sie die Standard-App für die Liveverfolgung von TV-Sendungen."</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Um sich diesen Kanal anzusehen, drücke rechts und gib die PIN ein."</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Um sich dieses Programm anzusehen, drücke rechts und gib die PIN ein."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Diese Sendung hat keine Altersempfehlung.\nUm sie anzusehen, drücke rechts und gib deine PIN ein."</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Diese Sendung wurde als \"<xliff:g id="RATING">%1$s</xliff:g>\" eingestuft.\nUm sich diese Sendung anzusehen, drücke rechts und gib deine PIN ein."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Um sich diesen Kanal anzusehen, verwendest du die Standard-App für die Liveverfolgung von TV-Sendungen."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Um sich dieses Programm anzusehen, verwendest du die Standard-App für die Liveverfolgung von TV-Sendungen."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Diese Sendung hat keine Altersempfehlung.\nUm sie anzusehen, verwende die Standard-App für die Liveverfolgung von TV-Sendungen."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Diese Sendung wurde als \"<xliff:g id="RATING">%1$s</xliff:g>\" eingestuft.\nUm sich diese Sendung anzusehen, verwendest du die Standard-App für die Liveverfolgung von TV-Sendungen."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Das Programm wurde blockiert."</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Diese Sendung hat keine Altersempfehlung"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Diese Sendung wurde als \"<xliff:g id="RATING">%1$s</xliff:g>\" eingestuft."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Nur Audio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Schwaches Signal"</string>
<string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Keine Internetverbindung"</string>
<plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Dieser Kanal kann bis <xliff:g id="END_TIME_1">%1$s</xliff:g> nicht wiedergegeben werden, weil andere Kanäle aufgenommen werden. \n\nDrücken Sie rechts, um den Aufnahmeplan anzupassen.</item>
- <item quantity="one">Dieser Kanal kann bis <xliff:g id="END_TIME_0">%1$s</xliff:g> nicht wiedergegeben werden, weil ein anderer Kanal aufgenommen wird. \n\nDrücken Sie rechts, um den Aufnahmeplan anzupassen.</item>
+ <item quantity="other">Dieser Kanal kann bis <xliff:g id="END_TIME_1">%1$s</xliff:g> nicht wiedergegeben werden, weil andere Kanäle aufgenommen werden. \n\nDrücke rechts, um den Aufnahmeplan anzupassen.</item>
+ <item quantity="one">Dieser Kanal kann bis <xliff:g id="END_TIME_0">%1$s</xliff:g> nicht wiedergegeben werden, weil ein anderer Kanal aufgenommen wird. \n\nDrücke rechts, um den Aufnahmeplan anzupassen.</item>
</plurals>
<string name="channel_banner_no_title" msgid="8660301979190693176">"Kein Titel"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal blockiert"</string>
@@ -173,25 +166,23 @@
<string name="setup_store_action_title" msgid="4083402039720973414">"Weitere Quellen suchen"</string>
<string name="setup_store_action_description" msgid="6820482635042445297">"Nach Apps suchen, die Live-TV anbieten"</string>
<string name="new_sources_title" msgid="3878933676500061895">"Neue Kanalquellen verfügbar"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Neue Kanalquellen bieten weitere Kanäle an.\nDiese können Sie entweder jetzt oder später über die Einstellung \"Kanalquellen\" einrichten."</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Neue Kanalquellen bieten weitere Kanäle an.\nDiese kannst du entweder jetzt oder später über die Einstellung \"Kanalquellen\" einrichten."</string>
<string name="new_sources_action_setup" msgid="177693761664016811">"Jetzt einrichten"</string>
<string name="new_sources_action_skip" msgid="2501296961258184330">"OK"</string>
<!-- no translation found for intro_title (251772896916795556) -->
<skip />
- <string name="intro_description" msgid="7806473686446937307"><b>"Drücken Sie die Auswahltaste"</b>", um auf das TV-Menü zuzugreifen."</string>
+ <string name="intro_description" msgid="7806473686446937307"><b>"Drücke die Auswahltaste"</b>", um auf das TV-Menü zuzugreifen."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Kein TV-Eingang gefunden"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"TV-Eingang konnte nicht gefunden werden."</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP wird nicht unterstützt."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Es ist kein Eingang für die PIP-Anzeige verfügbar."</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tunertyp ungeeignet, bitte Live TV App für TV-Eingang des Tunertyps starten"</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Fehler beim Einstellen"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Für diese Aktion wurde keine App gefunden."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Alle Quellkanäle sind ausgeblendet.\nWählen Sie mindestens einen Kanal aus, den Sie anschauen möchten."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Alle Quellkanäle sind ausgeblendet.\nWähle mindestens einen Kanal aus, den du anschauen möchtest."</string>
<string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Das Video ist unerwarteterweise nicht verfügbar."</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"Die Taste \"Zurück\" gilt für das verbundene Gerät. Zum Beenden drücken Sie auf \"Startseite\"."</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"Die Taste \"Zurück\" gilt für das verbundene Gerät. Zum Beenden drücke auf \"Startseite\"."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Live TV benötigt einen Lesezugriff für die Kanalliste."</string>
<string name="setup_sources_text" msgid="4988039637873759839">"Quellen einrichten"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Bei Live-TV wird die Nutzererfahrung mit klassischen Fernsehsendern mit der von Streaming-Kanälen von Apps kombiniert.\n\nRichten Sie zuerst die bereits installierten Kanalquellen ein. Sie können auch im Google Play Store nach weiteren Apps suchen, die Live-TV anbieten."</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Bei Live-TV wird die Nutzererfahrung mit klassischen Fernsehsendern mit der von Streaming-Kanälen von Apps kombiniert.\n\nRichte zuerst die bereits installierten Kanalquellen ein. Du kannst auch im Google Play Store nach weiteren Apps suchen, die Live-TV anbieten."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Aufnahmen und Zeitpläne"</string>
<string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 Minuten"</string>
<string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 Minuten"</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d geplante Aufnahmen</item>
<item quantity="one">%1$d geplante Aufnahme</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Aufnahme abbrechen"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Aufnahme beenden"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Ansehen"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Von Anfang an abspielen"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Wiedergabe fortsetzen"</string>
@@ -236,7 +229,7 @@
<string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Aufnahmeplan"</string>
<string name="dvr_detail_read_more" msgid="2588920758094498544">"Weitere Infos"</string>
<string name="dvr_series_deletion_title" msgid="7672649492494507574">"Aufnahmen löschen"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Wählen Sie die Folgen aus, die gelöscht werden sollen. Eine Wiederherstellung ist nicht möglich."</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Wähle die Folgen aus, die gelöscht werden sollen. Eine Wiederherstellung ist nicht möglich."</string>
<string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Es sind keine Aufnahmen zum Löschen vorhanden."</string>
<string name="dvr_series_select_watched" msgid="3608122404146716502">"Angesehene Folgen auswählen"</string>
<string name="dvr_series_select_all" msgid="5415749261739544048">"Alle Folgen auswählen"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Wenn zu viele Programme gleichzeitig aufgenommen werden, werden nur die Programme mit höherer Priorität aufgenommen."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Speichern"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Einmalige Aufnahmen haben höchste Priorität"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Abbrechen"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Abbrechen"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Entfernen"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Beenden"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Aufnahmeplan ansehen"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Nur diese Folge"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Stattdessen diese Sendung aufnehmen"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Diesen Aufnahmeplan abbrechen"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Jetzt ansehen"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Aufnahmen löschen…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Kann aufgenommen werden"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Aufnahme geplant"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Konflikt bei der Aufnahme"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Aufnahme"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Aufnahme fehlgeschlagen"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Sendungen werden gelesen, um Aufnahmepläne zu erstellen"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Sendungen werden gelesen"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Sendungen werden gelesen"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Letzte Aufnahmen ansehen"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Die Aufnahme <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ist nicht abgeschlossen."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Die Aufnahmen <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> und <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> sind nicht abgeschlossen."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Die Aufnahmen <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> und <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> sind nicht abgeschlossen."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Die Aufnahme von <xliff:g id="PROGRAMNAME">%1$s</xliff:g> konnte nicht abgeschlossen werden, weil nicht genügend Speicher vorhanden ist."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Die Aufnahmen von <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> und <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> konnten nicht abgeschlossen werden, weil nicht genügend Speicher vorhanden ist."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Die Aufnahmen von <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> und <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> konnten nicht abgeschlossen werden, weil nicht genügend Speicher vorhanden ist."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR benötigt mehr Speicher"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Sie können mit DVR Sendungen aufnehmen, jedoch ist auf Ihrem Gerät momentan nicht ausreichend Speicherplatz vorhanden. Schließen Sie ein externes Laufwerk mit mindestens <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB freiem Speicher an und folgen Sie der Anleitung zur Formatierung als Gerätespeicher."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Du kannst mit DVR Sendungen aufnehmen, jedoch ist auf deinem Gerät momentan nicht ausreichend Speicherplatz vorhanden. Schließ ein externes Laufwerk mit mindestens <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB freiem Speicher an und folge der Anleitung zur Formatierung als Gerätespeicher."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Nicht genug Speicherplatz"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Diese Inhalte werden nicht aufgenommen, weil zu wenig Speicherplatz verfügbar ist. Du kannst Speicherplatz freigeben, indem du ein paar vorhandene Aufnahmen löschst."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Speicher nicht verfügbar"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Ein Teil des DVR-Speichers ist nicht verfügbar. Um DVR neu zu aktivieren, stellen Sie eine Verbindung zu dem externen Gerät her, das Sie zuvor verwendet haben. Sie können den Speicher auch entfernen, wenn er nicht mehr verfügbar ist."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Speicher entfernen?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Alle aufgenommenen Inhalte und Aufnahmepläne gehen verloren."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Aufnahme beenden?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Die aufgenommenen Inhalte werden gespeichert."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Die Aufzeichnung von <xliff:g id="PROGRAMNAME">%1$s</xliff:g> wird aufgrund eines Konflikts mit diesem Programm beendet. Der aufgezeichnete Inhalt wird gespeichert."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Aufnahme geplant, aber es liegen Konflikte vor"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Aufnahme wurde gestartet, aber es liegen Konflikte vor"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> wird aufgenommen."</string>
@@ -300,23 +293,35 @@
<item quantity="other">Teile von <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> und %3$d weiteren geplanten Aufnahmen werden nicht aufgenommen.</item>
<item quantity="one">Teile von <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> und %4$d weiteren geplanten Aufnahme werden nicht aufgenommen.</item>
</plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Was möchten Sie aufnehmen?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Wie lange möchten Sie aufnehmen?"</string>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Was möchtest du aufnehmen?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Wie lange möchtest du aufnehmen?"</string>
<string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Schon dem Aufnahmeplan hinzugefügt"</string>
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Diese Sendung wurde dem Aufnahmeplan schon hinzugefügt und wird um <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> aufgenommen."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Schon aufgenommen"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Diese Sendung wurde schon aufgenommen. Sie ist in der DVR-Bibliothek verfügbar."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Serienaufnahme geplant"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> Aufnahmen wurden für <xliff:g id="SERIESNAME_3">%2$s</xliff:g> geplant.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> Aufnahme wurde für <xliff:g id="SERIESNAME_1">%2$s</xliff:g> geplant.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> Aufnahmen wurden für <xliff:g id="SERIESNAME_3">%2$s</xliff:g> geplant. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> davon werden wegen Konflikten nicht aufgezeichnet.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> Aufnahme wurde für <xliff:g id="SERIESNAME_1">%2$s</xliff:g> geplant. Sie wird wegen Konflikten nicht aufgezeichnet.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> Aufnahmen wurden für <xliff:g id="SERIESNAME_4">%2$s</xliff:g> geplant. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> Folgen dieser Serie und anderer Serien werden wegen Konflikten nicht aufgezeichnet.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> Aufnahme wurde für <xliff:g id="SERIESNAME_1">%2$s</xliff:g> geplant. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> Folge dieser oder einer anderen Serie wird wegen Konflikten nicht aufgezeichnet.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> Aufnahmen wurden für <xliff:g id="SERIESNAME_3">%2$s</xliff:g> geplant. 1 Folge einer anderen Serie wird wegen Konflikten nicht aufgezeichnet.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> Aufnahme wurde für <xliff:g id="SERIESNAME_1">%2$s</xliff:g> geplant. 1 Folge einer anderen Serie wird wegen Konflikten nicht aufgezeichnet.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> Aufnahmen wurden für <xliff:g id="SERIESNAME_4">%2$s</xliff:g> geplant. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> Folgen anderer Serien werden wegen Konflikten nicht aufgezeichnet.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> Aufnahme wurde für <xliff:g id="SERIESNAME_1">%2$s</xliff:g> geplant. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> Folge einer anderen Serie wird wegen Konflikten nicht aufgezeichnet.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Aufgenommenes Programm wurde nicht gefunden."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Ähnliche Aufnahmen"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Keine Programmbeschreibung)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d Aufnahmen</item>
<item quantity="one">%1$d Aufnahme</item>
@@ -333,9 +338,10 @@
<string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Serieneinstellungen"</string>
<string name="dvr_series_schedules_start" msgid="8458768834047133835">"Serienaufnahme starten"</string>
<string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Serienaufnahme beenden"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Sie möchten die Serienaufnahme beenden?"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Du möchtest die Serienaufnahme beenden?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Die aufgenommenen Folgen werden in der DVR-Bibliothek gespeichert."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Beenden"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Momentan werden keine Folgen ausgestrahlt."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Keine Folgen verfügbar.\nSie werden aufgenommen, sobald sie verfügbar sind."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d Minuten)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Heute <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Morgen <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Punkte"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Aufgenommene Programme"</string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 9e8e042c..f9967894 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"μονοφων."</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"στερεοφ."</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Στοιχ. ελέγ. αναπαραγωής"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Πρόσφατα κανάλια"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Κανάλια"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Επιλογές TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Επιλογές PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Τα στοιχεία ελέγχου αναπαραγωγής δεν είναι διαθέσιμα γι\' αυτό το κανάλι"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Αναπαραγωγή ή παύση"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Γρήγορη προώθηση"</string>
@@ -35,37 +34,19 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Υπότιτλοι"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Τρόπος εμφάν."</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Ενεργό"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Ανενεργό"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Πολλαπλός ήχος"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Περισσότ. κανάλια"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Ρυθμίσεις"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Πηγή"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Ανταλλαγή"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Ενεργό"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Ανενεργό"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Ήχος"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Κύριο"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Παράθυρο PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Διάταξη"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Κάτω δεξιά"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Επάνω δεξιά"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Επάνω αριστερά"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Κάτω αριστερά"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Δίπλα"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Μέγεθος"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Μεγάλο"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Μικρό"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Πηγή εισόδου"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"Τηλεόραση (κεραία/καλωδιακή)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Δεν υπάρχουν πληροφορίες προγράμματος"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Δεν υπάρχουν πληροφορίες"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Αποκλεισμένο κανάλι"</string>
- <string name="default_language" msgid="4122326459624337928">"Άγνωστη γλώσσα"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Άγνωστη γλώσσα"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Υπότιτλοι %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Υπότιτλοι"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Ανενεργό"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Προσ. μορφοποίησης"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Ορίστε προτ. συστήματος για υπότιτλους"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Προτιμήσεις συστήματος για υπότιτλους"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"Τρόπος εμφάν."</string>
<string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Πολλαπλός ήχος"</string>
<string name="multi_audio_channel_mono" msgid="6229173848963557723">"μονοφωνικός ήχος"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Ομαδοποίηση κατά"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Αυτό το πρόγραμμα αποκλείστηκε"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Αυτό το πρόγραμμα δεν έχει αξιολόγηση"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Αυτό το πρόγραμμα αξιολογήθηκε ως <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Η είσοδος δεν υποστηρίζει την αυτόματη σάρωση"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Αδύνατη η εκκίνηση της αυτόματης σάρωσης για \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
@@ -92,7 +74,6 @@
<item quantity="one">Προστέθηκε %1$d κανάλι</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Δεν προστέθηκαν κανάλια"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Δέκτης"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Γονικός έλεγχος"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Ενεργό"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Ανενεργό"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Άλλες χώρες"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Κανένα"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Κανένα"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Χωρίς αξιολόγηση"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Αποκλ. προγραμ. χωρίς αξιολόγ."</string>
<string name="option_rating_none" msgid="5204552587760414879">"Κανένα"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Υψηλοί περιορισμοί"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Μεσαίοι περιορισμοί"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Εισαγάγετε PIN για να δείτε αυτό το κανάλι"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Εισαγάγετε PIN για να δείτε αυτό το πρόγραμμα"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Αυτό το πρόγραμμα αξιολογήθηκε ως <xliff:g id="RATING">%1$s</xliff:g>. Εισαγάγετε το PIN σας για το παρακολουθήσετε"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Αυτό το πρόγραμμα δεν έχει αξιολόγηση. Εισαγάγετε το PIN για να το παρακολουθήσετε"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Εισαγάγετε το PIN σας"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Για να ορίσετε γονικούς ελέγχους, δημιουργήστε ένα PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Εισαγωγή νέου κωδικού PIN"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Λάθος PIN. Δοκιμάστε ξανά."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Δοκιμάστε ξανά, δεν υπάρχει αντιστοιχία PIN"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Εισαγωγή ταχυδρομικού κώδικα"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Η εφαρμογή \"Ζωντανά κανάλια\" θα χρησιμοποιεί τον ταχυδρομικό κώδικα για να παρέχει έναν πλήρη οδηγό προγράμματος για τα τηλεοπτικά κανάλια."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Εισαγωγή ταχυδρομικού κώδικα"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Μη έγκυρος ταχυδρομ. κώδικας"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Ρυθμίσεις"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Προσαρμογή λίστας καναλιών"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Επιλέξτε κανάλια για τον οδηγό προγράμματος"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Πηγές καναλιών"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Νέα διαθέσιμα κανάλια"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Γονικοί έλεγχοι"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Χρονική μετατόπιση"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Κάντε εγγραφή ενώ παρακολουθείτε, για να μπορείτε να κάνετε παύση ή επαναφορά σε ζωντανά προγράμματα.\nΠροειδοποίηση: Αυτή η λειτουργία μπορεί να μειώσει τη χωρητικότητα του εσωτερικού αποθηκευτικού χώρου μέσω της εντατικής χρήσης του."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Άδειες λογισμικού ανοικτού κώδικα"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Άδειες λογισμικού ανοικτού κώδικα"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Αποστολή σχολίων"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Έκδοση"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Για να παρακολουθήσετε αυτό το κανάλι, πατήστε το δεξιά και εισαγάγετε το PIN σας"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Για να παρακολουθήσετε αυτό το πρόγραμμα, πατήστε δεξιά και εισαγάγετε το PIN σας"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Αυτό το πρόγραμμα δεν έχει αξιολόγηση.\nΓια να το παρακολουθήσετε, πατήστε το στοιχείο \"Δεξιά\" και εισαγάγετε το PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Αυτό το πρόγραμμα αξιολογήθηκε ως <xliff:g id="RATING">%1$s</xliff:g>.\nΓια να παρακολουθήσετε αυτό το πρόγραμμα, πατήστε δεξιά και εισαγάγετε το PIN σας"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Για να παρακολουθήσετε αυτό το κανάλι, χρησιμοποιήστε την προεπιλεγμένη εφαρμογή ζωντανής τηλεοπτικής μετάδοσης."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Για να παρακολουθήσετε αυτό το πρόγραμμα, χρησιμοποιήστε την προεπιλεγμένη εφαρμογή ζωντανής τηλεοπτικής μετάδοσης."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Αυτό το πρόγραμμα δεν έχει αξιολόγηση.\nΓια να παρακολουθήσετε αυτό το πρόγραμμα, χρησιμοποιήστε την προεπιλεγμένη εφαρμογή ζωντανής τηλεοπτικής μετάδοσης."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Αυτό το πρόγραμμα χαρακτηρίστηκε <xliff:g id="RATING">%1$s</xliff:g>.\nΓια να παρακολουθήσετε αυτό το πρόγραμμα, χρησιμοποιήστε την προεπιλεγμένη εφαρμογή ζωντανής τηλεοπτικής μετάδοσης."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Το πρόγραμμα αποκλείστηκε"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Αυτό το πρόγραμμα δεν έχει αξιολόγηση"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Αυτό το πρόγραμμα αξιολογήθηκε ως <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Μόνο ήχος"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Ασθενές σήμα"</string>
@@ -171,7 +164,7 @@
<string name="setup_input_new" msgid="3337725672277046798">"Νέα"</string>
<string name="setup_input_setup_now" msgid="1772000402336958967">"Δεν ρυθμίστηκε"</string>
<string name="setup_store_action_title" msgid="4083402039720973414">"Λήψη περισσότερων πηγών"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Περιήγηση σε εφαρμογές που προσφέρουν ζωντανά κανάλια"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Δείτε εφαρμογές με ζωντανά κανάλια"</string>
<string name="new_sources_title" msgid="3878933676500061895">"Υπάρχουν νέες διαθέσιμες πηγές καναλιών"</string>
<string name="new_sources_description" msgid="749649005588426813">"Οι νέες πηγές καναλιών προσφέρουν κανάλια.\nΡυθμίστε τες τώρα ή αργότερα μέσω των ρυθμίσεων πηγών καναλιών."</string>
<string name="new_sources_action_setup" msgid="177693761664016811">"Ρύθμιση τώρα"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Πατήστε το πλήκτρο SELECT"</b>" για να μεταβείτε στο μενού της τηλεόρασης."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Δεν βρέθηκε είσοδος τηλεόρασης"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Δεν είναι δυνατή η εύρεση εισόδου τηλεόρασης"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Το PIP δεν υποστηρίζεται"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Δεν υπάρχει διαθέσιμη είσοδος για εμφάνιση με PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Ακατάλληλος τύπος δέκτη. Εκκινήστε την εφαρμογή Κανάλια ζωντανά για είσοδο τύπου δέκτη τηλεόρασης."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Αποτυχία συντονισμού"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Δεν βρέθηκε εφαρμογή για τη διαχείριση αυτής της ενέργειας."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d προγραμματ. εγγραφές</item>
<item quantity="one">%1$d προγραμματ. εγγραφή</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Ακύρωση εγγραφής"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Διακοπή εγγραφής"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Παρακολούθηση"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Αναπαραγωγή από την αρχή"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Συνέχ. αναπαραγωγής"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Όταν υπάρχουν πολλά προγράμματα για εγγραφή την ίδια ώρα, θα γίνει εγγραφή μόνο των προγραμμάτων με τις υψηλότερες προτεραιότητες."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Αποθήκευση"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Οι εγγραφές μίας φοράς έχουν την υψηλότερη προτεραιότητα"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Ακύρωση"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Ακύρωση"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Διαγραφή"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Διακοπή"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Προβολή προγραμματισ. εγγραφών"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Αυτό το συγκεκριμένο επεισόδιο"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Αντί αυτού, εγγρ. αυτού του πρ."</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Ακύρωση αυτής της εγγραφής"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Προβολή τώρα"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Διαγραφή εγγραφών…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Με δυνατότητα εγγραφής"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Η εγγραφή προγραμματίστηκε"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Διένεξη εγγραφής"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Εγγραφή"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Αποτυχία εγγραφής"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Γίνεται ανάγνωση προγραμμάτων για δημιουργία προγραμματισμών εγγραφής"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Ανάγνωση προγραμμάτων"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Ανάγνωση προγραμμάτων"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Προβολή πρόσφατων εγγραφών"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Η εγγραφή του προγράμματος <xliff:g id="PROGRAMNAME">%1$s</xliff:g> δεν είναι ολοκληρωμένη."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Οι εγγραφές των προγραμμάτων <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> και <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> δεν είναι ολοκληρωμένες."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Οι εγγραφές των προγραμμάτων <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> και <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> δεν είναι ολοκληρωμένες."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Η εγγραφή του προγράμματος <xliff:g id="PROGRAMNAME">%1$s</xliff:g> δεν ολοκληρώθηκε, λόγω ανεπαρκούς αποθηκευτικού χώρου."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Οι εγγραφές των προγραμμάτων <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> και <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> δεν ολοκληρώθηκαν, λόγω ανεπαρκούς αποθηκευτικού χώρου."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Οι εγγραφές των προγραμμάτων <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> και <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> δεν ολοκληρώθηκαν, λόγω ανεπαρκούς αποθηκευτικού χώρου."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Το DVR χρειάζεται περισσότερο αποθηκευτικό χώρο"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Θα μπορείτε να εγγράψετε προγράμματα με το DVR. Ωστόσο, αυτήν τη στιγμή δεν υπάρχει αρκετός αποθηκευτικός χώρος στη συσκευή σας έτσι ώστε να λειτουργήσει το DVR. Συνδέστε έναν εξωτερικό δίσκο με χωρητικότητα <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB ή μεγαλύτερη και ακολουθήστε τα βήματα για να τον μορφοποιήσετε και να τον ορίσετε ως αποθηκευτικό χώρο της συσκευής."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Θα μπορείτε να εγγράψετε προγράμματα με το DVR. Ωστόσο, αυτήν τη στιγμή δεν υπάρχει αρκετός αποθηκευτικός χώρος στη συσκευή σας έτσι ώστε να λειτουργήσει το DVR. Συνδέστε έναν εξωτερικό δίσκο με χωρητικότητα <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB ή μεγαλύτερη και ακολουθήστε τα βήματα για να τον μορφοποιήσετε και να τον ορίσετε ως αποθηκευτικό χώρο της συσκευής."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Δεν υπάρχει αρκετός αποθηκευτικός χώρος"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Αυτό το πρόγραμμα δεν θα εγγραφεί, επειδή δεν υπάρχει αρκετός αποθηκευτικός χώρος. Δοκιμάστε να διαγράψετε ορισμένες υπάρχουσες εγγραφές."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Ο αποθηκευτικός χώρος λείπει"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Κάποιο τμήμα του αποθηκευτικού χώρου που χρησιμοποιείται από το DVR λείπει. Συνδέστε τον εξωτερικό δίσκο που χρησιμοποιήσατε στο παρελθόν για να ενεργοποιήσετε εκ νέου το DVR. Εναλλακτικά, μπορείτε να επιλέξετε να διαγράψετε τον αποθηκευτικό χώρο αν δεν είναι πλέον διαθέσιμος."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Να διαγραφεί ο αποθηκευτικός χώρος;"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Όλο το εγγεγραμμένο περιεχόμενο και τα χρονοδιαγράμματα θα χαθούν."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Να διακοπεί η εγγραφή;"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Θα γίνει αποθήκευση του περιεχομένου που έχει εγγραφεί."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Η εγγραφή του προγράμματος <xliff:g id="PROGRAMNAME">%1$s</xliff:g> θα τερματιστεί καθώς βρίσκεται σε διένεξη με αυτό το πρόγραμμα. Το περιεχόμενο που έχει εγγραφεί θα αποθηκευτεί."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Η εγγραφή προγραμματίστηκε, αλλά έχει διενέξεις"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Η εγγραφή ξεκίνησε αλλά υπάρχουν διενέξεις"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Θα γίνει εγγραφή του προγράμματος <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Το ίδιο πρόγραμμα έχει προγραμματιστεί για εγγραφή στις <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Έχει ήδη εγγραφεί"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Αυτό το πρόγραμμα έχει ήδη εγγραφεί. Είναι διαθέσιμο στη βιβλιοθήκη DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Η εγγραφή της σειράς προγραμματίστηκε"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> εγγραφές έχουν προγραμματιστεί για τη σειρά <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> εγγραφή έχει προγραμματιστεί για τη σειρά <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> εγγραφές έχουν προγραμματιστεί για τη σειρά <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> από αυτές δεν θα εγγραφούν εξαιτίας διενέξεων.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> εγγραφή έχει προγραμματιστεί για τη σειρά <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Δεν θα γίνει η εγγραφή εξαιτίας διενέξεων.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> εγγραφές έχουν προγραμματιστεί για τη σειρά <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> επεισόδια αυτής της σειράς και άλλης σειράς δεν θα εγγραφούν εξαιτίας διενέξεων.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> εγγραφή έχει προγραμματιστεί για τη σειρά <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> επεισόδια αυτής της σειράς και άλλης σειράς δεν θα εγγραφούν εξαιτίας διενέξεων.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> εγγραφές έχουν προγραμματιστεί για τη σειρά <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 επεισόδιο άλλης σειράς δεν θα εγγραφεί εξαιτίας διενέξεων.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> εγγραφή έχει προγραμματιστεί για τη σειρά <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 επεισόδιο άλλης σειράς δεν θα εγγραφεί εξαιτίας διενέξεων.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> εγγραφές έχουν προγραμματιστεί για τη σειρά <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> επεισόδια άλλης σειράς δεν θα εγγραφούν εξαιτίας διενέξεων.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> εγγραφή έχει προγραμματιστεί για τη σειρά <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> επεισόδια άλλης σειράς δεν θα εγγραφούν εξαιτίας διενέξεων.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Το εγγεγραμμένο πρόγραμμα δεν βρέθηκε."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Σχετικές εγγραφές"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Καμία περιγραφή προγράμματος)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d εγγραφές</item>
<item quantity="one">%1$d εγγραφή</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Διακοπή εγγραφής σειράς;"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Τα επεισόδια που έχουν εγγραφεί θα εξακολουθήσουν να είναι διαθέσιμα στη βιβλιοθήκη DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Διακοπή"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Δεν προβάλλονται επεισόδια ζωντανά αυτήν τη στιγμή."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Δεν υπάρχουν διαθέσιμα επεισόδια.\nΗ εγγραφή τους θα πραγματοποιηθεί όταν θα είναι διαθέσιμα."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d λεπτά)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> σήμερα"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> αύριο"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Μουσική επένδυση"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Εγγεγραμμένα προγράμματα"</string>
</resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index bda4e1ea..04a53da4 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Play controls"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Recent channels"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Channels"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV options"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP options"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Play controls unavailable for this channel"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Play or pause"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Fast-forward"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Closed captions"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Display mode"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"On"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Off"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Get more channels"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Settings"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Source"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Swap"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"On"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Off"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Sound"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Main"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP window"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Layout"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Bottom right"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Top right"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Top left"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Bottom left"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Side by side"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Size"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Big"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Small"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Input source"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (aerial/cable)"</string>
<string name="no_program_information" msgid="1049844207745145132">"No programme information"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"No information"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blocked channel"</string>
- <string name="default_language" msgid="4122326459624337928">"Unknown language"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Unknown language"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Closed captions %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Closed captions"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Off"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Customise formatting"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Group by"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"This programme is blocked"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"This program is unrated"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"The input doesn\'t support auto-scan"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Unable to start auto-scan for \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d channel added</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"No channels added"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Parental controls"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"On"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Off"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Other countries"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"None"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"None"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Unrated"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Block unrated programs"</string>
<string name="option_rating_none" msgid="5204552587760414879">"None"</string>
<string name="option_rating_high" msgid="8898400296730158893">"High restrictions"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Medium restrictions"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Enter your PIN to watch this channel"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Enter your PIN to watch this programme"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>. Enter your PIN to watch this programme"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"This program is unrated. Enter your PIN to watch this program"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Enter your PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"To set parental controls, create a PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Enter new PIN"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"That PIN was wrong. Try again."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Try again, PIN doesn\'t match"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Enter your postcode."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Live TV app will use the postcode to provide a complete programme guide for the TV channels."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Enter your postcode"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Invalid postcode"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Settings"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Customise channel list"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Choose channels for your programme guide"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Channel sources"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"New channels available"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Parental controls"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Record while watching so that you can pause or rewind live programmes.\nWarning: This may decrease the life of the internal storage by the intensive use of the storage."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Open-source licences"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Open-source licences"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Send feedback"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"To watch this channel, press Right and enter your PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"To watch this program, press Right and enter your PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"This program is unrated.\nTo watch this program, press Right and enter your PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>.\nTo watch this programme, press Right and enter your PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"To watch this channel, use the default Live TV app."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"To watch this programme, use the default Live TV app."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"This program is unrated.\nTo watch this program, use the default Live TV app."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>.\nTo watch this programme, use the default Live TV app."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programme is blocked"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"This program is unrated"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audio only"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Weak signal"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Press SELECT"</b>" to access the TV menu."</string>
<string name="msg_no_input" msgid="3897674146985427865">"No TV input found"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Cannot find the TV input"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP is not supported"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"There is no available input which can be shown with PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tuner type not suitable. Please launch Live TV app for tuner type TV input."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Tune failed"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"No app was found to handle this action."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d recordings scheduled</item>
<item quantity="one">%1$d recording scheduled</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Cancel recording"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Stop recording"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Watch"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Play from beginning"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Resume playing"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"When there are too many programmes to be recorded at the same time, only the ones with higher priorities will be recorded."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Save"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"One-time recordings have the highest priority"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Cancel"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Cancel"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Forget"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Stop"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"View recording schedule"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"This single programme"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Record this one instead"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Cancel this recording"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Watch now"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Delete recordings…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Recordable"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Recording scheduled"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Recording conflict"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Recording"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Recording failed"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Reading programs to create recording schedules"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Reading programmes"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Reading programmes"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"View recent recordings"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"The recording of <xliff:g id="PROGRAMNAME">%1$s</xliff:g> is incomplete."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> and <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> are incomplete."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> and <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> are incomplete."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"The recording of <xliff:g id="PROGRAMNAME">%1$s</xliff:g> didn\'t complete due to insufficient storage."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> and <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> didn\'t complete due to insufficient storage."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> and <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> didn\'t complete due to insufficient storage."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR needs more storage"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"You will be able to record programmes with DVR. At the moment there is not enough storage on your device for DVR to work. Please connect an external drive that is <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB or larger and follow the steps to format it as device storage."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"You will be able to record programmes with DVR. At the moment there is not enough storage on your device for DVR to work. Please connect an external drive that is <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB or larger and follow the steps to format it as device storage."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Not enough storage"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"This programme will not be recorded because there is not enough storage. Try deleting some existing recordings."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Missing storage"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Some of the storage used by DVR is missing. Please connect the external drive that you used before to re-enable DVR. Alternatively, you can choose to forget the storage if it\'s no longer available."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Forget storage?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"All your recorded content and schedules will be lost."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Stop recording?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"The recorded content will be saved."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"The recording of <xliff:g id="PROGRAMNAME">%1$s</xliff:g> will be stopped because it conflicts with this programme. The recorded content will be saved."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Recording scheduled but has conflicts"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Recording has started but has conflicts"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> will be recorded."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"The same programme has already been scheduled to be recorded at <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Already recorded"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"This programme has already been recorded. It’s available in the DVR library."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Series recording scheduled"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> of them will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. It will not be recorded due to conflicts.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodes of this series and other series will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodes of this series and other series will not be recorded due to conflicts.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 episode of other series will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 episode of other series will not be recorded due to conflicts.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodes of other series will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodes of other series will not be recorded due to conflicts.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Recorded programme not found."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Related recordings"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(No programme description)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d recordings</item>
<item quantity="one">%1$d recording</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Stop series recording?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Recorded episodes will remain available in the DVR library."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Stop"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"No episodes are on air now."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"No episodes are available.\nThey will be recorded once they are available."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minutes)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> today"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> tomorrow"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Score"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Recorded Programmes"</string>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index bda4e1ea..04a53da4 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Play controls"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Recent channels"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Channels"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV options"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP options"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Play controls unavailable for this channel"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Play or pause"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Fast-forward"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Closed captions"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Display mode"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"On"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Off"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Get more channels"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Settings"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Source"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Swap"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"On"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Off"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Sound"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Main"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP window"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Layout"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Bottom right"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Top right"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Top left"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Bottom left"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Side by side"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Size"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Big"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Small"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Input source"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (aerial/cable)"</string>
<string name="no_program_information" msgid="1049844207745145132">"No programme information"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"No information"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blocked channel"</string>
- <string name="default_language" msgid="4122326459624337928">"Unknown language"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Unknown language"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Closed captions %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Closed captions"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Off"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Customise formatting"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Group by"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"This programme is blocked"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"This program is unrated"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"The input doesn\'t support auto-scan"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Unable to start auto-scan for \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d channel added</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"No channels added"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Parental controls"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"On"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Off"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Other countries"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"None"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"None"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Unrated"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Block unrated programs"</string>
<string name="option_rating_none" msgid="5204552587760414879">"None"</string>
<string name="option_rating_high" msgid="8898400296730158893">"High restrictions"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Medium restrictions"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Enter your PIN to watch this channel"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Enter your PIN to watch this programme"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>. Enter your PIN to watch this programme"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"This program is unrated. Enter your PIN to watch this program"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Enter your PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"To set parental controls, create a PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Enter new PIN"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"That PIN was wrong. Try again."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Try again, PIN doesn\'t match"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Enter your postcode."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Live TV app will use the postcode to provide a complete programme guide for the TV channels."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Enter your postcode"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Invalid postcode"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Settings"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Customise channel list"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Choose channels for your programme guide"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Channel sources"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"New channels available"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Parental controls"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Record while watching so that you can pause or rewind live programmes.\nWarning: This may decrease the life of the internal storage by the intensive use of the storage."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Open-source licences"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Open-source licences"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Send feedback"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"To watch this channel, press Right and enter your PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"To watch this program, press Right and enter your PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"This program is unrated.\nTo watch this program, press Right and enter your PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>.\nTo watch this programme, press Right and enter your PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"To watch this channel, use the default Live TV app."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"To watch this programme, use the default Live TV app."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"This program is unrated.\nTo watch this program, use the default Live TV app."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>.\nTo watch this programme, use the default Live TV app."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programme is blocked"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"This program is unrated"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audio only"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Weak signal"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Press SELECT"</b>" to access the TV menu."</string>
<string name="msg_no_input" msgid="3897674146985427865">"No TV input found"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Cannot find the TV input"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP is not supported"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"There is no available input which can be shown with PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tuner type not suitable. Please launch Live TV app for tuner type TV input."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Tune failed"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"No app was found to handle this action."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d recordings scheduled</item>
<item quantity="one">%1$d recording scheduled</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Cancel recording"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Stop recording"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Watch"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Play from beginning"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Resume playing"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"When there are too many programmes to be recorded at the same time, only the ones with higher priorities will be recorded."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Save"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"One-time recordings have the highest priority"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Cancel"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Cancel"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Forget"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Stop"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"View recording schedule"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"This single programme"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Record this one instead"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Cancel this recording"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Watch now"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Delete recordings…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Recordable"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Recording scheduled"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Recording conflict"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Recording"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Recording failed"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Reading programs to create recording schedules"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Reading programmes"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Reading programmes"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"View recent recordings"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"The recording of <xliff:g id="PROGRAMNAME">%1$s</xliff:g> is incomplete."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> and <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> are incomplete."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> and <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> are incomplete."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"The recording of <xliff:g id="PROGRAMNAME">%1$s</xliff:g> didn\'t complete due to insufficient storage."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> and <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> didn\'t complete due to insufficient storage."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> and <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> didn\'t complete due to insufficient storage."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR needs more storage"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"You will be able to record programmes with DVR. At the moment there is not enough storage on your device for DVR to work. Please connect an external drive that is <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB or larger and follow the steps to format it as device storage."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"You will be able to record programmes with DVR. At the moment there is not enough storage on your device for DVR to work. Please connect an external drive that is <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB or larger and follow the steps to format it as device storage."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Not enough storage"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"This programme will not be recorded because there is not enough storage. Try deleting some existing recordings."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Missing storage"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Some of the storage used by DVR is missing. Please connect the external drive that you used before to re-enable DVR. Alternatively, you can choose to forget the storage if it\'s no longer available."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Forget storage?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"All your recorded content and schedules will be lost."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Stop recording?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"The recorded content will be saved."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"The recording of <xliff:g id="PROGRAMNAME">%1$s</xliff:g> will be stopped because it conflicts with this programme. The recorded content will be saved."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Recording scheduled but has conflicts"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Recording has started but has conflicts"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> will be recorded."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"The same programme has already been scheduled to be recorded at <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Already recorded"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"This programme has already been recorded. It’s available in the DVR library."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Series recording scheduled"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> of them will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. It will not be recorded due to conflicts.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodes of this series and other series will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodes of this series and other series will not be recorded due to conflicts.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 episode of other series will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 episode of other series will not be recorded due to conflicts.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodes of other series will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodes of other series will not be recorded due to conflicts.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Recorded programme not found."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Related recordings"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(No programme description)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d recordings</item>
<item quantity="one">%1$d recording</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Stop series recording?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Recorded episodes will remain available in the DVR library."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Stop"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"No episodes are on air now."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"No episodes are available.\nThey will be recorded once they are available."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minutes)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> today"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> tomorrow"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Score"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Recorded Programmes"</string>
</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index bda4e1ea..04a53da4 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Play controls"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Recent channels"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Channels"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV options"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP options"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Play controls unavailable for this channel"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Play or pause"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Fast-forward"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Closed captions"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Display mode"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"On"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Off"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Get more channels"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Settings"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Source"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Swap"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"On"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Off"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Sound"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Main"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP window"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Layout"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Bottom right"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Top right"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Top left"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Bottom left"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Side by side"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Size"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Big"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Small"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Input source"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (aerial/cable)"</string>
<string name="no_program_information" msgid="1049844207745145132">"No programme information"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"No information"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blocked channel"</string>
- <string name="default_language" msgid="4122326459624337928">"Unknown language"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Unknown language"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Closed captions %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Closed captions"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Off"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Customise formatting"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Group by"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"This programme is blocked"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"This program is unrated"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"The input doesn\'t support auto-scan"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Unable to start auto-scan for \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d channel added</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"No channels added"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Parental controls"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"On"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Off"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Other countries"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"None"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"None"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Unrated"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Block unrated programs"</string>
<string name="option_rating_none" msgid="5204552587760414879">"None"</string>
<string name="option_rating_high" msgid="8898400296730158893">"High restrictions"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Medium restrictions"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Enter your PIN to watch this channel"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Enter your PIN to watch this programme"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>. Enter your PIN to watch this programme"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"This program is unrated. Enter your PIN to watch this program"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Enter your PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"To set parental controls, create a PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Enter new PIN"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"That PIN was wrong. Try again."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Try again, PIN doesn\'t match"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Enter your postcode."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Live TV app will use the postcode to provide a complete programme guide for the TV channels."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Enter your postcode"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Invalid postcode"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Settings"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Customise channel list"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Choose channels for your programme guide"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Channel sources"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"New channels available"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Parental controls"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Record while watching so that you can pause or rewind live programmes.\nWarning: This may decrease the life of the internal storage by the intensive use of the storage."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Open-source licences"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Open-source licences"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Send feedback"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"To watch this channel, press Right and enter your PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"To watch this program, press Right and enter your PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"This program is unrated.\nTo watch this program, press Right and enter your PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>.\nTo watch this programme, press Right and enter your PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"To watch this channel, use the default Live TV app."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"To watch this programme, use the default Live TV app."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"This program is unrated.\nTo watch this program, use the default Live TV app."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>.\nTo watch this programme, use the default Live TV app."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programme is blocked"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"This program is unrated"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"This programme is rated <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audio only"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Weak signal"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Press SELECT"</b>" to access the TV menu."</string>
<string name="msg_no_input" msgid="3897674146985427865">"No TV input found"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Cannot find the TV input"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP is not supported"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"There is no available input which can be shown with PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tuner type not suitable. Please launch Live TV app for tuner type TV input."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Tune failed"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"No app was found to handle this action."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d recordings scheduled</item>
<item quantity="one">%1$d recording scheduled</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Cancel recording"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Stop recording"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Watch"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Play from beginning"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Resume playing"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"When there are too many programmes to be recorded at the same time, only the ones with higher priorities will be recorded."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Save"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"One-time recordings have the highest priority"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Cancel"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Cancel"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Forget"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Stop"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"View recording schedule"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"This single programme"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Record this one instead"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Cancel this recording"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Watch now"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Delete recordings…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Recordable"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Recording scheduled"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Recording conflict"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Recording"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Recording failed"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Reading programs to create recording schedules"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Reading programmes"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Reading programmes"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"View recent recordings"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"The recording of <xliff:g id="PROGRAMNAME">%1$s</xliff:g> is incomplete."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> and <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> are incomplete."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> and <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> are incomplete."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"The recording of <xliff:g id="PROGRAMNAME">%1$s</xliff:g> didn\'t complete due to insufficient storage."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> and <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> didn\'t complete due to insufficient storage."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"The recordings of <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> and <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> didn\'t complete due to insufficient storage."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR needs more storage"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"You will be able to record programmes with DVR. At the moment there is not enough storage on your device for DVR to work. Please connect an external drive that is <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB or larger and follow the steps to format it as device storage."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"You will be able to record programmes with DVR. At the moment there is not enough storage on your device for DVR to work. Please connect an external drive that is <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB or larger and follow the steps to format it as device storage."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Not enough storage"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"This programme will not be recorded because there is not enough storage. Try deleting some existing recordings."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Missing storage"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Some of the storage used by DVR is missing. Please connect the external drive that you used before to re-enable DVR. Alternatively, you can choose to forget the storage if it\'s no longer available."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Forget storage?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"All your recorded content and schedules will be lost."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Stop recording?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"The recorded content will be saved."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"The recording of <xliff:g id="PROGRAMNAME">%1$s</xliff:g> will be stopped because it conflicts with this programme. The recorded content will be saved."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Recording scheduled but has conflicts"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Recording has started but has conflicts"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> will be recorded."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"The same programme has already been scheduled to be recorded at <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Already recorded"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"This programme has already been recorded. It’s available in the DVR library."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Series recording scheduled"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> of them will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. It will not be recorded due to conflicts.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodes of this series and other series will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodes of this series and other series will not be recorded due to conflicts.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 episode of other series will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 episode of other series will not be recorded due to conflicts.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodes of other series will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> recording has been scheduled for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodes of other series will not be recorded due to conflicts.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Recorded programme not found."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Related recordings"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(No programme description)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d recordings</item>
<item quantity="one">%1$d recording</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Stop series recording?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Recorded episodes will remain available in the DVR library."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Stop"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"No episodes are on air now."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"No episodes are available.\nThey will be recorded once they are available."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minutes)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> today"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> tomorrow"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Score"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Recorded Programmes"</string>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 14e9f506..7e1c79dc 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"estéreo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Controles de reproducción"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Recientes"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Canales"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Opciones de TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opciones de PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Los controles de reproducción no están disponibles en este canal."</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Reproducir o pausar"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Avanzar"</string>
@@ -35,37 +34,19 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Subtítulos"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Modo pantalla"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Activada"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Desactivada"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Varios audios"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Obtener canales"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Configuración"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Fuente"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Cambiar"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Activada"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Desactivada"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Sonido"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Principal"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Ventana PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Diseño"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Abajo derecha"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Arriba derecha"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Arriba izqda."</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Abajo izquierda"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Lado a lado"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Tamaño"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Grande"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Pequeña"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Fuente de entrada"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"Televisión (antena/cable)"</string>
<string name="no_program_information" msgid="1049844207745145132">"No hay información del programa"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Sin información"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Canal bloqueado"</string>
- <string name="default_language" msgid="4122326459624337928">"Idioma desconocido"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Idioma desconocido"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Subtítulos opcionales en %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Subtítulos opcionales"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Desactivado"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Personalizar formato"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Preferencias sistema para los subtítulos"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Preferencias del sistema para los subtítulos"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"Modo de pantalla"</string>
<string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Varios audios"</string>
<string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Agrupar por"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Este programa está bloqueado."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Este programa no está clasificado"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Calificación de este programa: <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"La entrada no admite la búsqueda automática."</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"No se puede iniciar la búsqueda automática de \"<xliff:g id="TV_INPUT">%s</xliff:g>\"."</string>
@@ -92,7 +74,6 @@
<item quantity="one">Se agregó %1$d canal</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"No se agregaron canales."</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Sintonizador"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Control. parentales"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Activado"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Desactivado"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Otros países"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Ninguno"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ninguno"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Sin clasificar"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Bloquear progr. sin clasificar"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Ninguno"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Restricciones altas"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Restricciones medias"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Ingresa tu PIN para ver este canal"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Ingresa tu PIN para ver este programa"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>. Ingresa tu PIN para mirarlo."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Este programa no está clasificado. Ingresa tu PIN para verlo"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Ingresa tu PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Para configurar controles parentales, debes crear un PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Ingresar nuevo PIN"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"El PIN es incorrecto. Vuelve a intentarlo."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Inténtalo de nuevo, el PIN no coincide."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Ingresa tu código postal"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"La app de Live Channels usará el código postal para brindar la guía completa de programas de los canales de TV."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Ingresa tu código postal"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Código postal no válido"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Configuración"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personalizar lista de canales"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Seleccionar canales de la guía de programas"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Fuentes de canales"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nuevos canales disponibles"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Controles parentales"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Cambio de tiempo"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Graba el contenido mientras lo miras para poder pausar o retroceder los programas en vivo.\nAdvertencia: Es posible que esta función reduzca la vida útil del almacenamiento interno debido a su uso intensivo."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licencias de código abierto"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licencias de código abierto"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Envía comentarios"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versión"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Para mirar este canal, presiona la tecla hacia la derecha e ingresa el PIN."</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Para mirar este programa, presiona la tecla hacia la derecha e ingresa el PIN."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Este programa no está clasificado.\nPara verlo, presiona Derecha y, luego, ingresa tu PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Este programa se calificó como <xliff:g id="RATING">%1$s</xliff:g>.\nPara mirarlo, presiona la tecla hacia la derecha e ingresa el PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Para mirar este canal, usa la app de TV en vivo predeterminada."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Para mirar este programa, usa la app de TV en vivo predeterminada."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Este programa no está clasificado.\nPara verlo, usa la app predeterminada de TV en vivo."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Este programa está calificado como <xliff:g id="RATING">%1$s</xliff:g>.\nPara mirarlo, usa la app de TV en vivo predeterminada."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"El programa está bloqueado."</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Este programa no está clasificado"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Calificación de este programa: <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Solo audio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Señal débil"</string>
@@ -171,7 +164,7 @@
<string name="setup_input_new" msgid="3337725672277046798">"Nueva"</string>
<string name="setup_input_setup_now" msgid="1772000402336958967">"Sin configurar"</string>
<string name="setup_store_action_title" msgid="4083402039720973414">"Obtener más fuentes"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Explorar apps que ofrecen Canales en vivo"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Ver apps que ofrecen Canales en vivo"</string>
<string name="new_sources_title" msgid="3878933676500061895">"Nuevas fuentes de canales disponibles"</string>
<string name="new_sources_description" msgid="749649005588426813">"Nuevas fuentes de canales con canales disponibles.\nPuedes configurarlas ahora o más tarde en la configuración de fuentes de canales."</string>
<string name="new_sources_action_setup" msgid="177693761664016811">"Configurar ahora"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Presiona SELECCIONAR"</b>" para acceder al menú de la televisión."</string>
<string name="msg_no_input" msgid="3897674146985427865">"No se encontró ninguna entrada de TV."</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"No se puede encontrar la entrada de TV."</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"No se admite PIP."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"No hay entradas disponibles que se puedan mostrar con PIP."</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tipo de sintonizador no admitido. Abre la aplicación Canales en vivo para el tipo de sintonizador de entrada de TV."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Error al sintonizar"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"No se encontró ninguna aplicación que pueda realizar esta acción."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d grabaciones programadas</item>
<item quantity="one">%1$d grabación programada</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Cancelar grabación"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Detener grabación"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Mirar"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Reproducir desde comienzo"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Reanudar reproducción"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Cuando hay demasiados programas para grabar al mismo tiempo, solo se grabarán los que tengan mayor prioridad."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Guardar"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Las grabaciones únicas tienen mayor prioridad"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Cancelar"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Cancelar"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Borrar"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Detener"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Ver cronograma de grabación"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Solo este programa"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Grabar este programa en su lugar"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Cancelar esta grabación"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Mirar ahora"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Borrar grabaciones…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Se puede grabar"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Grabación programada"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Error de grabación"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Grabando"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Se produjo un error al grabar"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Leyendo programas para crear programaciones de grabación"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Leyendo programas"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Leyendo programas"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Ver grabaciones recientes"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"No se completó la grabación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g>"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"No se completó la grabación de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> y <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"No se completó la grabación de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> y <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"No se completó la grabación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> por falta de espacio de almacenamiento."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"No se completó la grabación de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> y <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> por falta de espacio de almacenamiento."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"No se completó la grabación de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> y <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> por falta de espacio de almacenamiento."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"El DVR necesita más espacio de almacenamiento"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Si bien puedes grabar programas con el DVR, no hay espacio de almacenamiento suficiente en tu dispositivo para usar esta opción. Conecta una unidad externa de <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB como mínimo y sigue los pasos para formatearla como almacenamiento del dispositivo."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Si bien puedes grabar programas con el DVR, no hay espacio de almacenamiento suficiente en tu dispositivo para usar esta opción. Conecta una unidad externa de <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB como mínimo y sigue los pasos para formatearla como almacenamiento del dispositivo."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"No hay suficiente espacio de almacenamiento"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"No se grabará este programa porque no hay suficiente espacio de almacenamiento. Intenta borrar algunas grabaciones existentes."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Falta almacenamiento"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Falta parte del almacenamiento que se usa para DVR. Conecta la unidad externa que usaste anteriormente para volver a habilitar esta función. También puedes borrar el almacenamiento si ya no está disponible."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"¿Borrar almacenamiento?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Se perderán todas las programaciones y los contenidos grabados."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"¿Deseas detener la grabación?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Se guardará el contenido grabado."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Se detendrá la grabación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> porque entra en conflicto con este programa. Sin embargo, se guardará el contenido grabado."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Grabación programada con conflictos"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Comenzó la grabación, pero tiene problemas"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Se grabará <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"El mismo programa se grabará a las <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Programa grabado"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Este programa ya está grabado. Está disponible en la biblioteca de DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Se programó la grabación de series"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">Se programaron <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> grabaciones de <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one">Se programó <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabación de <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">Se programaron <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> grabaciones de <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. No se grabarán <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> de ellas debido a algunos conflictos.</item>
+ <item quantity="one">Se programó <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabación de <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. No podrá completarse debido a algunos conflictos.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">Se programaron <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> grabaciones de <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. No se grabarán <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodios de esta serie y de otras debido a algunos conflictos.</item>
+ <item quantity="one">Se programó <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabación de <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. No se grabarán <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodios de esta serie y de otras debido a algunos conflictos.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">Se programaron <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> grabaciones de <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. No se grabará 1 episodio de otra serie debido a algunos conflictos.</item>
+ <item quantity="one">Se programó <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabación de <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. No se grabará 1 episodio de otra serie debido a algunos conflictos.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">Se programaron <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> grabaciones de <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. No se grabarán <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodios de otra serie debido a algunos conflictos.</item>
+ <item quantity="one">Se programó <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabación de <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. No se grabarán <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodios de otra serie debido a algunos conflictos.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"No se encontró el programa grabado."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Grabaciones relacionadas"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Sin descripción del programa)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d grabaciones</item>
<item quantity="one">%1$d grabación</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"¿Detener grabación de la serie?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Los episodios grabados estarán disponibles en la biblioteca de DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Detener"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"No hay episodios en vivo disponibles en este momento."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"No hay episodios disponibles.\nSe grabarán cuando lo estén."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minutos)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Hoy: <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Mañana: <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Puntuación"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programas grabados"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index badab6a4..b5d00be6 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"estéreo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Controles de reproducción"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Canales recientes"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Canales"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Opciones de TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opciones de PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Controles de reproducción no disponibles en este canal"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Reproducir o pausar"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Avance rápido"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Subtítulos"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Modo de pantalla"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Activado"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Desactivado"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Varios audios"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Más canales"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Ajustes"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Fuente"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Cambiar"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Activado"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Desactivado"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Sonido"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Principal"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Ventana PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Diseño"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Abajo derecha"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Arriba derecha"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Arriba izquierda"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Abajo izquierda"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"En paralelo"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Dimensiones"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Grande"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Pequeño"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Fuente de entrada"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/cable)"</string>
<string name="no_program_information" msgid="1049844207745145132">"No hay información del programa"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Sin información"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Canal bloqueado"</string>
- <string name="default_language" msgid="4122326459624337928">"Idioma desconocido"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Idioma desconocido"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Subtítulos en %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Subtítulos"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Desactivados"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Personalizar formato"</string>
@@ -73,7 +54,7 @@
<string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"envolvente 5.1"</string>
<string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"envolvente 7.1"</string>
<string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d canales"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Personalizar lista"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Personalizar lista de canales"</string>
<string name="edit_channels_item_select_group" msgid="4953000352257999703">"Seleccionar grupo"</string>
<string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Anular selección"</string>
<string name="edit_channels_item_group_by" msgid="7794571851966798199">"Agrupar por"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Agrupar por"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Este programa está bloqueado"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Este programa no se ha clasificado"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Este programa se ha clasificado como <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"La entrada no admite la búsqueda automática"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"No se puede iniciar la búsqueda automática de <xliff:g id="TV_INPUT">%s</xliff:g>"</string>
@@ -92,8 +74,7 @@
<item quantity="one">%1$d canal añadido</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"No se han añadido canales"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Sintonizador"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Controles parentales"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Control parental"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Activados"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Desactivados"</string>
<string name="option_channels_locked" msgid="5797855082297549907">"Canales bloqueados"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Otros países"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Ninguno"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ninguna"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Sin clasificar"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Bloquear progr. sin clasificar"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Ninguna"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Restricciones altas"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Restricciones medias"</string>
@@ -124,8 +107,9 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Introduce el PIN para ver este canal"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Introduce el PIN para ver este programa"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>. Introduce el PIN para verlo"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Este programa no se ha clasificado. Introduce tu PIN para verlo"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Introduce el número PIN"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Para establecer controles parentales, debes crear un PIN"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Para establecer control parental, debes crear un PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Introduce el nuevo PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirma el número PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Introduce el número PIN"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Ese PIN era incorrecto. Vuelve a intentarlo."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Vuelve a intentarlo, el PIN no coincide"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Introduce tu código postal"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"La aplicación TV en directo se basa en el código postal para ofrecer una programación completa de los canales de televisión disponibles."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Introduce tu código postal"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"El código postal no es válido"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Ajustes"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personalizar lista de canales"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Seleccionar canales de la programación"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Seleccionar canales para la guía de programas"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Fuentes de canales"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nuevos canales disponibles"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Control parental"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Licencias de software libre"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licencias software libre"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Cambio de tiempo"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Graba el contenido mientras lo ves para poder pausar o rebobinar los programas en directo.\nAdvertencia: Es posble que esta función reduzca la duración del almacenamiento interno debido a su uso intensivo de este."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Licencias de código abierto"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Enviar sugerencias"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versión"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Para ver este canal, pulsa la tecla hacia la derecha e introduce el número PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Para ver este programa, pulsa la tecla hacia la derecha e introduce el número PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Este programa no se ha clasificado.\nPara verlo, pulsa Derecha e introduce tu PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Este programa se ha clasificado como <xliff:g id="RATING">%1$s</xliff:g>.\nPara verlo, pulsa la tecla hacia la derecha e introduce el número PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Para ver este canal, utiliza la aplicación de TV en directo predeterminada."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Para ver este programa, utiliza la aplicación de TV en directo predeterminada."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Este programa no se ha clasificado.\nPara verlo, utiliza la aplicación de TV en directo predeterminada."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>.\nPara verlo, utiliza la aplicación de TV en directo predeterminada."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"El programa está bloqueado"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Este programa no se ha clasificado"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Este programa se ha clasificado como <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Solo audio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Señal débil"</string>
@@ -171,7 +164,7 @@
<string name="setup_input_new" msgid="3337725672277046798">"Nuevas"</string>
<string name="setup_input_setup_now" msgid="1772000402336958967">"Sin configurar"</string>
<string name="setup_store_action_title" msgid="4083402039720973414">"Obtener más fuentes"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Explorar aplicaciones que ofrecen TV en directo"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Ver aplicaciones de TV en directo"</string>
<string name="new_sources_title" msgid="3878933676500061895">"Nuevas fuentes de canales disponibles"</string>
<string name="new_sources_description" msgid="749649005588426813">"Hay canales disponibles en las nuevas fuentes de canales.\nPuedes configurarlos ahora o más tarde en los ajustes correspondientes."</string>
<string name="new_sources_action_setup" msgid="177693761664016811">"Configurar ahora"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Pulsa SELECCIONAR"</b>" para acceder al menú de la TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"No se han encontrado entradas de TV"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"No se puede encontrar la entrada de TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP no admitido"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"No hay entradas disponibles que se puedan mostrar con PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tipo de sintonizador inadecuado. Abre Canales en directo para seleccionar la entrada de TV del tipo de sintonizador."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Error al sintonizar"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"No se ha encontrado ninguna aplicación que pueda realizar esta acción."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d grabaciones programadas</item>
<item quantity="one">%1$d grabación programada</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Cancelar grabación"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Detener grabación"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Ver"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Reproducir desde inicio"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Reanudar reproducción"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Cuando haya demasiados programas que grabar al mismo tiempo, solo se grabarán aquellos con mayor prioridad."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Guardar"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Las grabaciones únicas son las que tienen mayor prioridad"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Cancelar"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Cancelar"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Olvidar"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Detener"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Ver programación de grabación"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Este programa"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Grabar esta en su lugar"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Cancelar esta grabación"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Ver ahora"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Eliminar grabaciones…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Se puede grabar"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Grabación programada"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Problema de grabación"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Grabación"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"No se ha podido grabar"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Leyendo programas para crear programaciones de grabación"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Leyendo programas"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Leyendo programas"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Ver grabaciones recientes"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"La grabación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> está incompleta."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Las grabaciones de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> y <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> están incompletas."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Las grabaciones de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> y <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> están incompletas."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"No se ha completado la grabación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> porque no hay espacio de almacenamiento suficiente."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"No se han completado las grabaciones de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> y <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> porque no hay espacio de almacenamiento suficiente."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"No se han completado las grabaciones de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> y <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> porque no hay espacio de almacenamiento suficiente."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Se necesita más almacenamiento para el DVR"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Puedes grabar programas con el DVR, pero no tienes suficiente espacio de almacenamiento en el dispositivo para que el DVR funcione. Conecta una unidad externa que tenga <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB como mínimo y sigue los pasos para formatearlo como almacenamiento del dispositivo."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Puedes grabar programas con el DVR, pero no tienes suficiente espacio de almacenamiento en el dispositivo para que el DVR funcione. Conecta una unidad externa que tenga <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB como mínimo y sigue los pasos para formatearlo como almacenamiento del dispositivo."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"No hay suficiente espacio de almacenamiento"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Este programa no se grabará porque no hay espacio de almacenamiento suficiente. Borra algunas grabaciones."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"No se puede acceder al almacenamiento"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"No se puede acceder a parte del almacenamiento utilizado por el DVR. Para volver a habilitarlo, conecta la unidad externa que has utilizado anteriormente. También puedes indicar que se olvide el almacenamiento si ya no está disponible."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"¿Olvidar almacenamiento?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Se perderán todo el contenido grabado y las programaciones."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"¿Detener grabación?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"El contenido grabado se guardará."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"La grabación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> se detendrá porque entra en conflicto con este programa. El contenido grabado se guardará."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Grabación programada con conflictos"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"La grabación se ha iniciado, pero tiene conflictos"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Se grabará <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Ya se ha programado la grabación del mismo programa para esta hora: <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Ya se ha grabado"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Este programa ya se ha grabado y está disponible en la colección del DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Grabación de series programada"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">Se han programado <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> grabaciones para <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one">Se ha programado <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabación para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">Se han programado <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> grabaciones para <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Episodios que no se grabarán debido a conflictos: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>.</item>
+ <item quantity="one">Se ha programado <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabación para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Debido a conflictos, no se grabará.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">Se han programado <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> grabaciones para <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Episodios de esta y otras series que no se grabarán debido a conflictos: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="one">Se ha programado <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabación para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Episodios de esta y otras series que no se grabarán debido a conflictos: <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">Se han programado <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> grabaciones para <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Debido a conflictos, no se grabará 1 episodio de otra serie.</item>
+ <item quantity="one">Se ha programado <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabación para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Debido a conflictos, no se grabará 1 episodio de otra serie.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">Se han programado <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> grabaciones para <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Episodios de otras series que no se grabarán debido a conflictos: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="one">Se ha programado <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabación para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Episodios de otras series que no se grabarán debido a conflictos: <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g>.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"No se ha encontrado el programa grabado."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Grabaciones relacionadas"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(No hay ninguna descripción)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d grabaciones</item>
<item quantity="one">%1$d grabación</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"¿Detener la grabación de series?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Los episodios grabados seguirán estando disponibles en la colección del DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Detener"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"No se está emitiendo ningún episodio."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"No hay episodios disponibles.\nSe grabarán cuando estén disponibles."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minutos)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Hoy de <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Mañana de <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Puntuación"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programas grabados"</string>
</resources>
diff --git a/res/values-et-v23/strings.xml b/res/values-et-rEE-v23/strings.xml
index e981deeb..e981deeb 100644
--- a/res/values-et-v23/strings.xml
+++ b/res/values-et-rEE-v23/strings.xml
diff --git a/res/values-et/arrays.xml b/res/values-et-rEE/arrays.xml
index 2d1d11fd..2d1d11fd 100644
--- a/res/values-et/arrays.xml
+++ b/res/values-et-rEE/arrays.xml
diff --git a/res/values-et/rating_system_strings.xml b/res/values-et-rEE/rating_system_strings.xml
index 5cee5abd..5cee5abd 100644
--- a/res/values-et/rating_system_strings.xml
+++ b/res/values-et-rEE/rating_system_strings.xml
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
new file mode 100644
index 00000000..77596a47
--- /dev/null
+++ b/res/values-et-rEE/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Esituse juhtnupud"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanalid"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"TV-valikud"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Esituse juhtelemendid ei ole selle kanali puhul saadaval"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Esitamine või peatamine"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Edasikerimine"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Tagasikerimine"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Järgmine"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Eelmine"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Saatekava"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Saadaval on uued kanalid"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Ava <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Subtiitrid"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Kuvarežiim"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Multiaudio"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Hangi kanaleid"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Seaded"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenn/kaabel)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Programmiteavet pole"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Teave puudub"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blokeeritud kanal"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Tundmatu keel"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Subtiitrid %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Subtiitrid"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Väljas"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Vormingu kohandamine"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Määrake subtiitrite süsteemiül. eelist."</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Kuvarežiim"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multiaudio"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"stereo"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"Ruumiline heli 5.1"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"Ruumiline heli 7.1"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d kanalit"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Kanaliloendi kohandam."</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Rühma valimine"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Rühma valiku tühist."</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Rühmitamisalus:"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Kanali allikas"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Rühmitamisalus:"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"See programm on blokeeritud"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Seda programmi ei ole hinnatud."</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Selle saate reiting on <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Sisend ei toeta automaatset skannimist"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Sisendi „<xliff:g id="TV_INPUT">%s</xliff:g>” automaatset skannimist ei saa alustada"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Subtiitrite süsteemiüleseid eelistusi ei saa käivitada."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">Lisatud on %1$d kanalit</item>
+ <item quantity="one">Lisatud on %1$d kanal</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Ühtegi kanalit ei lisatud"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Van. järelevalve"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Sees"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Väljas"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Blokeeritud kanalid"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Blokeeri kõik"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Deblokeeri kõik"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Peidetud kanalid"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Programmipiirangud"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"Muuda PIN-koodi"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Hinnangusüsteemid"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Hinnangud"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Kuva hinnangusüsteemid"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Muud riigid"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Puudub"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Puudub"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Hindamata"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Hindamata progr. blokeerimine"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Puudub"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Suured piirangud"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Keskmised piirangud"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Väikesed piirangud"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Kohandatud"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Sisu sobib lastele"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Sisu sobib vanematele lastele"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Sisu sobib teismelistele"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Käsitsi määratud piirangud"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s &amp; alamreitingud"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Alamreitingud"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Kanali vaatamiseks sisestage PIN-kood"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Saate vaatamiseks sisestage PIN-kood"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Selle saate reiting on <xliff:g id="RATING">%1$s</xliff:g>. Selle saate vaatamiseks sisestage oma PIN-kood"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Seda programmi ei ole hinnatud. Programmi vaatamiseks sisestage oma PIN-kood."</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"Sisestage PIN-kood"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Vanemliku järelevalve määramiseks looge PIN-kood"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Sisestage uus PIN-kood"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"Kinnitage PIN-kood"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Sisestage praegune PIN-kood"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Sisestasite vale PIN-koodi viis korda.\nProovige uuesti <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundi pärast.</item>
+ <item quantity="one">Sisestasite vale PIN-koodi viis korda.\nProovige uuesti <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> sekundi pärast.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"See PIN-kood oli vale. Proovige uuesti."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Proovige uuesti, PIN-kood pole õige"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Sisestage sihtnumber."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Rakendus Reaalajakanalid kasutab telekanalitele täieliku saatekava pakkumiseks sihtnumbrit."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Sisestage sihtnumber"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Sobimatu sihtnumber"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Seaded"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Kohanda kanaliloendit"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Kanalite valimine saatekava jaoks"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanali allikad"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Saadaval on uued kanalid"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Vanemlik järelevalve"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Ajanihe"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Salvestage vaatamise ajal, et saaksite otseülekande programme peatada või tagasi kerida.\nHoiatus: see võib vähendada sisemise salvestusruumi kasutusaega, kuna salvestusruumi kasutatakse intensiivselt."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Avatud lähtekoodi litsentsid"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Tagasiside saatmine"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versioon"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Kanali vaatamiseks vajutage paremale ja sisestage PIN-kood"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Saate vaatamiseks vajutage paremale ja sisestage PIN-kood"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Seda programmi ei ole hinnatud.\nSelle programmi vaatamiseks vajutage valikut Paremale ja sisestage oma PIN-kood"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Saate reiting on <xliff:g id="RATING">%1$s</xliff:g>\nSaate vaatamiseks vajutage valikut Paremale ja sisestage PIN-kood."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Selle kanali vaatamiseks kasutage otsesaadete vaikerakendust."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Selle saate vaatamiseks kasutage otsesaadete vaikerakendust."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Seda programmi ei ole hinnatud.\nSelle programmi vaatamiseks kasutage Live TV vaikerakendust."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Selle saate reiting on <xliff:g id="RATING">%1$s</xliff:g>.\nSelle saate vaatamiseks kasutage otsesaadete vaikerakendust."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Saade on blokeeritud"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Seda programmi ei ole hinnatud."</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Selle saate reiting on <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Ainult heli"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Nõrk signaal"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Interneti-ühendus puudub"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">Seda kanalit ei saa kuni kellani <xliff:g id="END_TIME_1">%1$s</xliff:g> esitada, kuna salvestatakse teisi kanaleid. \n\nSalvestamise ajakava kohandamiseks vajutage paremnoolt.</item>
+ <item quantity="one">Seda kanalit ei saa kuni kellani <xliff:g id="END_TIME_0">%1$s</xliff:g> esitada, kuna salvestatakse teist kanalit. \n\nSalvestamise ajakava kohandamiseks vajutage paremnoolt.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Pealkiri puudub"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal on blokeeritud"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Uus"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Allikad"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d kanalit</item>
+ <item quantity="one">%1$d kanal</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Ühtegi kanalit pole saadaval"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Uus"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Pole seadistatud"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Hankige rohkem allikaid"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Sirvige rakendusi, mis pakuvad reaalajakanaleid"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Saadaval on uued kanaliallikad"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Uutel kanaliallikatel on kanaleid pakkuda.\nSeadistage need kohe või tehke seda hiljem kanaliallikate seadetes."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Seadista kohe"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, selge"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"Teleri menüüle juurdepääsemiseks "<b>"vajutage nuppu SELECT"</b>"."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"TV-sisendit ei leitud"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"TV-sisendit ei õnnestu leida"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Sobimatu tuuneri tüüp. Käivitage tuuneri tüübi TV-sisendi jaoks rakendus Otseülekande kanalid."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Häälestamine ebaõnnestus"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Selle toimingu käsitlemiseks ei leitud ühtegi rakendust."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Kõik allikakanalid on peidetud.\nValige vaatamiseks vähemalt üks kanal."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Video pole ootamatult saadaval"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"Klahv TAGASI on mõeldud ühendatud seadme jaoks. Väljumiseks vajutage nuppu AVAEKRAAN."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Reaalajas kanalid vajavad telekavade lugemiseks luba."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Allikate seadistamine"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Reaalajakanalid ühendavad tavaliste telekanalite kasutuskogemuse ja rakendustes kanalite voogesitamise. \n\nAlustamiseks seadistage juba installitud kanaliallikad. Võite ka sirvida Google Play poodi, et hankida rakendusi, mis pakuvad reaalajakanaleid."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Salvestised ja ajakavad"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minutit"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minutit"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 tund"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 tundi"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Hiljutised"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Ajakavas´"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Seeria"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Muud"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Kanalit ei saa salvestada."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Programmi ei saa salvestada."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> on salvestamiseks ajastatud"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Saate <xliff:g id="PROGRAMNAME">%1$s</xliff:g> salvestamine praegusest kuni <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Kogu ajakava"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">Järgmised %1$d päeva</item>
+ <item quantity="one">Järgmine %1$d päev</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d minutit</item>
+ <item quantity="one">%1$d minut</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d uut salvestust</item>
+ <item quantity="one">%1$d uus salvestus</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d salvestust</item>
+ <item quantity="one">%1$d salvestus</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d salvestust on ajakavas</item>
+ <item quantity="one">%1$d salvestus on ajakavas</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Loobu salvestamisest"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Peata salvestamine"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Käekell"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Esita algusest"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Jätka esitust"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Kustuta"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Kustuta salvestised"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Jätka"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. hooaeg"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Kuva ajakava"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Lisateave"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Salvestuste kustutamine"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Valige jaod, mille soovite kustutada. Pärast kustutamist ei saa neid enam taastada."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Kustutamiseks pole salvestusi."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Vali vaadatud jaod"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Vali kõik jaod"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Tühista kõigi jagude valik"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> <xliff:g id="DURATION">%2$d</xliff:g>-st minutist on vaadatud"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> <xliff:g id="DURATION">%2$d</xliff:g>-st sekundist on vaadatud"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Pole kunagi vaadatud"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%1$d %2$d-st jaost kustutati</item>
+ <item quantity="one">%1$d %2$d-st jaost kustutati</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Prioriteet"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Kõige kõrgem"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Kõige madalam"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Nr <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Kanalid"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Kõik"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Prioriteedi valimine"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Kui samal ajal salvestamiseks on liiga palju programme, salvestatakse ainult prioriteetsed programmid."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Salvesta"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Ühekordsete salvestiste prioriteet on kõige kõrgem"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Peata"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Kuva salvestamise ajakava"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Ainult see saade"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"praegu kuni <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Kogu seeria …"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Lisa ikkagi ajakavva"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Salvesta hoopis see"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Tühista see salvestus"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Kuva nüüd"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Kustuta salvestised …"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Salvestatav"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Salvestamine on ajastatud"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Konflikt salvestamisel"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Salvestamine"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Salvestamine ebaõnnestus"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Programmide lugemine"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Kuva hiljutised salvestised"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Saate <xliff:g id="PROGRAMNAME">%1$s</xliff:g> salvestamine on pooleli."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Saadete <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ja <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> salvestamine on pooleli."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Saadete <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ja <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> salvestamine on pooleli."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Ebapiisava salvestusruumi tõttu ei viidud saate <xliff:g id="PROGRAMNAME">%1$s</xliff:g> salvestamist lõpule."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Ebapiisava salvestusruumi tõttu ei viidud saadete <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ja <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> salvestamist lõpule."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Ebapiisava salvestusruumi tõttu ei viidud saadete <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ja <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> salvestamist lõpule."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR vajab rohkem salvestusruumi"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Saateid saate salvestada DVR-iga. Praegu pole teie seadmes DVR-i töötamiseks siiski piisavalt salvestusruumi. Ühendage väline ketas, mille maht on vähemalt <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB, ja järgige juhiseid selle vormindamiseks salvestusseadmena."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Pole piisavalt mälu"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Programmi ei salvestata, kuna salvestusruumi on liiga vähe. Kustutage mõned olemasolevad salvestised."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Puuduv salvestusruum"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Kas peatada salvestamine?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Salvestatud sisu talletatakse."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Saate <xliff:g id="PROGRAMNAME">%1$s</xliff:g> salvestamine peatatakse, kuna see on selle saatega konfliktis. Salvestatud sisu salvestatakse."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Salvestamine on ajastatud, ent ilmnesid vastuolud"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Salvestamine on alanud, kuid ilmnesid vastuolud"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Saadet <xliff:g id="PROGRAMNAME">%1$s</xliff:g> salvestatakse."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"Kanalit <xliff:g id="CHANNELNAME">%1$s</xliff:g> salvestatakse."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Saate <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> teatud osi ei salvestata."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Saadete <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> ja <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> teatud osi ei salvestata."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Saadete <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ja veel ühe ajakava teatud osi ei salvestata."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other">Saadete <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ja veel %3$d ajakavade teatud osi ei salvestata.</item>
+ <item quantity="one">Saadete <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> ja veel %3$d ajakava teatud osi ei salvestata.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Mida soovite salvestada?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Kui kaua soovite salvestada?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Juba ajakavas"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Sama saate salvestus on juba lisatud ajakavva algusega <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Juba salvestatud"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"See saade on juba salvestatud. See on saadaval DVR-i kogus."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Sarja salvestamine lisati ajakavasse"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">Seeria <xliff:g id="SERIESNAME_3">%2$s</xliff:g> puhul lisati ajakavasse <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> salvestist.</item>
+ <item quantity="one">Seeria <xliff:g id="SERIESNAME_1">%2$s</xliff:g> puhul lisati ajakavasse <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> salvestis.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">Seeria <xliff:g id="SERIESNAME_3">%2$s</xliff:g> puhul lisati ajakavasse <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> salvestist. Konfliktide tõttu ei salvestata neist <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>.</item>
+ <item quantity="one">Seeria <xliff:g id="SERIESNAME_1">%2$s</xliff:g> puhul lisati ajakavasse <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> salvestis. Konfliktide tõttu seda ei salvestata.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">Seeria <xliff:g id="SERIESNAME_4">%2$s</xliff:g> puhul lisati ajakavasse <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> salvestist. Konfliktide tõttu ei salvestata selle seeria ja muude seeriate <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> jagu.</item>
+ <item quantity="one">Seeria <xliff:g id="SERIESNAME_1">%2$s</xliff:g> puhul lisati ajakavasse <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> salvestis. Konfliktide tõttu ei salvestata selle seeria ja muude seeriate <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> jagu.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">Seeria <xliff:g id="SERIESNAME_3">%2$s</xliff:g> puhul lisati ajakavasse <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> salvestist. Konfliktide tõttu ei salvestata muu seeria 1 jagu.</item>
+ <item quantity="one">Seeria <xliff:g id="SERIESNAME_1">%2$s</xliff:g> puhul lisati ajakavasse <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> salvestis. Konfliktide tõttu ei salvestata muu seeria 1 jagu.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">Seeria <xliff:g id="SERIESNAME_4">%2$s</xliff:g> puhul lisati ajakavasse <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> salvestist. Konfliktide tõttu ei salvestata muu seeria <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> jagu.</item>
+ <item quantity="one">Seeria <xliff:g id="SERIESNAME_1">%2$s</xliff:g> puhul lisati ajakavasse <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> salvestis. Konfliktide tõttu ei salvestata muu seeria <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> jagu.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Salvestatud programmi ei leitud."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Seotud salvestised"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d salvestist</item>
+ <item quantity="one">%1$d salvestis</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> on salvestamise ajakavast eemaldatud"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Salvestatakse tuuneri konfliktide tõttu osaliselt."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Ei salvestata tuuneri konfliktide tõttu."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Ajakavas ei ole veel salvestusi.\nSalvestuse saate ajakavva lisada saatekavas."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d salvestamise konflikti</item>
+ <item quantity="one">%1$d salvestamise konflikt</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Seeria seaded"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Alusta seeria salvestam."</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Peata seeria salvestamine"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Kas peatada seeria salvestamine?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Salvestatud jaod jäävad saadavale DVR-i kogusse."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Peata"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Ühtegi jagu pole praegu eetris."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Ükski osa pole saadaval.\nNeed salvestatakse siis, kui need kättesaadavaks muutuvad."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d minutit)</item>
+ <item quantity="one">(%1$d minut) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Täna"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Homme"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Eile"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"Täna vahemikus <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Homme vahemikus <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Tulemus"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Salvestatud programmid"</string>
+</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
deleted file mode 100644
index 83022b8e..00000000
--- a/res/values-et/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Esituse juhtnupud"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Viimas. kanalid"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"TV-valikud"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP-valikud"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Esituse juhtelemendid ei ole selle kanali puhul saadaval"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Esitamine või peatamine"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Edasikerimine"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Tagasikerimine"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Järgmine"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Eelmine"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Saatekava"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Saadaval on uued kanalid"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Ava <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Subtiitrid"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Kuvarežiim"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Sees"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Väljas"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Multiaudio"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Hangi kanaleid"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Seaded"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Allikas"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Vaheta"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Sees"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Väljas"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Heli"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Peamine"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP-aken"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Paigutus"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"All paremal"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Ülal paremal"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Ülal vasakul"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"All vasakul"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Kõrvuti"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Suurus"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Suur"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Väike"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Sisendallikas"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenn/kaabel)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Programmiteavet pole"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Teave puudub"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blokeeritud kanal"</string>
- <string name="default_language" msgid="4122326459624337928">"Tundmatu keel"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Subtiitrid"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Väljas"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Vormingu kohandamine"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Määrake subtiitrite süsteemiül. eelist."</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Kuvarežiim"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multiaudio"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"stereo"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"Ruumiline heli 5.1"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"Ruumiline heli 7.1"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d kanalit"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Kanaliloendi kohandam."</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Rühma valimine"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Rühma valiku tühist."</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Rühmitamisalus:"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Kanali allikas"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Rühmitamisalus:"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"See programm on blokeeritud"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Selle saate reiting on <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Sisend ei toeta automaatset skannimist"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Sisendi „<xliff:g id="TV_INPUT">%s</xliff:g>” automaatset skannimist ei saa alustada"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Subtiitrite süsteemiüleseid eelistusi ei saa käivitada."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">Lisatud on %1$d kanalit</item>
- <item quantity="one">Lisatud on %1$d kanal</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Ühtegi kanalit ei lisatud"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuuner"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Van. järelevalve"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Sees"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Väljas"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Blokeeritud kanalid"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Blokeeri kõik"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Deblokeeri kõik"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Peidetud kanalid"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Programmipiirangud"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"Muuda PIN-koodi"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Hinnangusüsteemid"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Hinnangud"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Kuva hinnangusüsteemid"</string>
- <string name="other_countries" msgid="8342216398676184749">"Muud riigid"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Puudub"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Puudub"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Puudub"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Suured piirangud"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Keskmised piirangud"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Väikesed piirangud"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Kohandatud"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Sisu sobib lastele"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Sisu sobib vanematele lastele"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Sisu sobib teismelistele"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Käsitsi määratud piirangud"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s &amp; alamreitingud"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Alamreitingud"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Kanali vaatamiseks sisestage PIN-kood"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Saate vaatamiseks sisestage PIN-kood"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Selle saate reiting on <xliff:g id="RATING">%1$s</xliff:g>. Selle saate vaatamiseks sisestage oma PIN-kood"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"Sisestage PIN-kood"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Vanemliku järelevalve määramiseks looge PIN-kood"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Sisestage uus PIN-kood"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"Kinnitage PIN-kood"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Sisestage praegune PIN-kood"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">Sisestasite vale PIN-koodi viis korda.\nProovige uuesti <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekundi pärast.</item>
- <item quantity="one">Sisestasite vale PIN-koodi viis korda.\nProovige uuesti <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> sekundi pärast.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"See PIN-kood oli vale. Proovige uuesti."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Proovige uuesti, PIN-kood pole õige"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Seaded"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Kohanda kanaliloendit"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Kanalite valimine saatekava jaoks"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanali allikad"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Saadaval on uued kanalid"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Vanemlik järelevalve"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Avatud lähtekoodi litsentsid"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Avatud lähtekoodi litsentsid"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Versioon"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Kanali vaatamiseks vajutage paremale ja sisestage PIN-kood"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Saate vaatamiseks vajutage paremale ja sisestage PIN-kood"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Saate reiting on <xliff:g id="RATING">%1$s</xliff:g>\nSaate vaatamiseks vajutage valikut Paremale ja sisestage PIN-kood."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Selle kanali vaatamiseks kasutage otsesaadete vaikerakendust."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Selle saate vaatamiseks kasutage otsesaadete vaikerakendust."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Selle saate reiting on <xliff:g id="RATING">%1$s</xliff:g>.\nSelle saate vaatamiseks kasutage otsesaadete vaikerakendust."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Saade on blokeeritud"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Selle saate reiting on <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Ainult heli"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Nõrk signaal"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Interneti-ühendus puudub"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Seda kanalit ei saa kuni kellani <xliff:g id="END_TIME_1">%1$s</xliff:g> esitada, kuna salvestatakse teisi kanaleid. \n\nSalvestamise ajakava kohandamiseks vajutage paremnoolt.</item>
- <item quantity="one">Seda kanalit ei saa kuni kellani <xliff:g id="END_TIME_0">%1$s</xliff:g> esitada, kuna salvestatakse teist kanalit. \n\nSalvestamise ajakava kohandamiseks vajutage paremnoolt.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Pealkiri puudub"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal on blokeeritud"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Uus"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Allikad"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d kanalit</item>
- <item quantity="one">%1$d kanal</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Ühtegi kanalit pole saadaval"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Uus"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Pole seadistatud"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Hankige rohkem allikaid"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Sirvige rakendusi, mis pakuvad reaalajakanaleid"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Saadaval on uued kanaliallikad"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Uutel kanaliallikatel on kanaleid pakkuda.\nSeadistage need kohe või tehke seda hiljem kanaliallikate seadetes."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Seadista kohe"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"OK, selge"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"Teleri menüüle juurdepääsemiseks "<b>"vajutage nuppu SELECT"</b>"."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"TV-sisendit ei leitud"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"TV-sisendit ei õnnestu leida"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP-d ei toetata"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Pole ühtegi sisendit, mida saab näidata koos PIP-ga"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Sobimatu tuuneri tüüp. Käivitage tuuneri tüübi TV-sisendi jaoks rakendus Otseülekande kanalid."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Häälestamine ebaõnnestus"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Selle toimingu käsitlemiseks ei leitud ühtegi rakendust."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Kõik allikakanalid on peidetud.\nValige vaatamiseks vähemalt üks kanal."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Video pole ootamatult saadaval"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"Klahv TAGASI on mõeldud ühendatud seadme jaoks. Väljumiseks vajutage nuppu AVAEKRAAN."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Reaalajas kanalid vajavad telekavade lugemiseks luba."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Allikate seadistamine"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Reaalajakanalid ühendavad tavaliste telekanalite kasutuskogemuse ja rakendustes kanalite voogesitamise. \n\nAlustamiseks seadistage juba installitud kanaliallikad. Võite ka sirvida Google Play poodi, et hankida rakendusi, mis pakuvad reaalajakanaleid."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Salvestised ja ajakavad"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minutit"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minutit"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 tund"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 tundi"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Hiljutised"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Ajakavas´"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Seeria"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Muud"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Kanalit ei saa salvestada."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Programmi ei saa salvestada."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> on salvestamiseks ajastatud"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Saate <xliff:g id="PROGRAMNAME">%1$s</xliff:g> salvestamine praegusest kuni <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Kogu ajakava"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">Järgmised %1$d päeva</item>
- <item quantity="one">Järgmine %1$d päev</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d minutit</item>
- <item quantity="one">%1$d minut</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d uut salvestust</item>
- <item quantity="one">%1$d uus salvestus</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d salvestust</item>
- <item quantity="one">%1$d salvestus</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d salvestust on ajakavas</item>
- <item quantity="one">%1$d salvestus on ajakavas</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Käekell"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Esita algusest"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Jätka esitust"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Kustuta"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Kustuta salvestised"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Jätka"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. hooaeg"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Kuva ajakava"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Lisateave"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Salvestuste kustutamine"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Valige jaod, mille soovite kustutada. Pärast kustutamist ei saa neid enam taastada."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Kustutamiseks pole salvestusi."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Vali vaadatud jaod"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Vali kõik jaod"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Tühista kõigi jagude valik"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> <xliff:g id="DURATION">%2$d</xliff:g>-st minutist on vaadatud"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> <xliff:g id="DURATION">%2$d</xliff:g>-st sekundist on vaadatud"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Pole kunagi vaadatud"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%1$d %2$d-st jaost kustutati</item>
- <item quantity="one">%1$d %2$d-st jaost kustutati</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Prioriteet"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Kõige kõrgem"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Kõige madalam"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Nr <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Kanalid"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Kõik"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Prioriteedi valimine"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Kui samal ajal salvestamiseks on liiga palju programme, salvestatakse ainult prioriteetsed programmid."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Salvesta"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Ühekordsete salvestiste prioriteet on kõige kõrgem"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Tühista"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Tühista"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Unusta"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Peata"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Kuva salvestamise ajakava"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Ainult see saade"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"praegu kuni <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Kogu seeria …"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Lisa ikkagi ajakavva"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Salvesta hoopis see"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Tühista see salvestus"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Kuva nüüd"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Salvestatav"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Salvestamine on ajastatud"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Konflikt salvestamisel"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Salvestamine"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Salvestamine ebaõnnestus"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Programmide lugemine salvestusajakavade loomiseks"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Programmide lugemine"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR vajab rohkem salvestusruumi"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Saateid saate salvestada DVR-iga. Praegu pole teie seadmes DVR-i töötamiseks siiski piisavalt salvestusruumi. Ühendage väline ketas, mille maht on vähemalt <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB, ja järgige juhiseid selle vormindamiseks salvestusseadmena."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Puuduv salvestusruum"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Osa DVR-i kasutatavast salvestusruumist on puudu. DVR-i uuesti lubamiseks ühendage väline ketas, mida varem kasutasite. Teise võimalusena saate salvestusruumi unustada, kui see enam saadaval pole."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Kas unustada salvestusruum?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Kogu teie salvestatud sisu ja ajakavad lähevad kaotsi."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Kas peatada salvestamine?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Salvestatud sisu talletatakse."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Salvestamine on ajastatud, ent ilmnesid vastuolud"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Salvestamine on alanud, kuid ilmnesid vastuolud"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Saadet <xliff:g id="PROGRAMNAME">%1$s</xliff:g> salvestatakse."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"Kanalit <xliff:g id="CHANNELNAME">%1$s</xliff:g> salvestatakse."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Saate <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> teatud osi ei salvestata."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Saadete <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> ja <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> teatud osi ei salvestata."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Saadete <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ja veel ühe ajakava teatud osi ei salvestata."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other">Saadete <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ja veel %3$d ajakavade teatud osi ei salvestata.</item>
- <item quantity="one">Saadete <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> ja veel %3$d ajakava teatud osi ei salvestata.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Mida soovite salvestada?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Kui kaua soovite salvestada?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Juba ajakavas"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Sama saate salvestus on juba lisatud ajakavva algusega <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Juba salvestatud"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"See saade on juba salvestatud. See on saadaval DVR-i kogus."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Salvestatud programmi ei leitud."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Seotud salvestised"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Programmi kirjeldust pole)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d salvestist</item>
- <item quantity="one">%1$d salvestis</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> on salvestamise ajakavast eemaldatud"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Salvestatakse tuuneri konfliktide tõttu osaliselt."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Ei salvestata tuuneri konfliktide tõttu."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Ajakavas ei ole veel salvestusi.\nSalvestuse saate ajakavva lisada saatekavas."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d salvestamise konflikti</item>
- <item quantity="one">%1$d salvestamise konflikt</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Seeria seaded"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Alusta seeria salvestam."</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Peata seeria salvestamine"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Kas peatada seeria salvestamine?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Salvestatud jaod jäävad saadavale DVR-i kogusse."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Peata"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Ükski osa pole saadaval.\nNeed salvestatakse siis, kui need kättesaadavaks muutuvad."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d minutit)</item>
- <item quantity="one">(%1$d minut) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Täna"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Homme"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Eile"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"Täna vahemikus <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Homme vahemikus <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Tulemus"</string>
-</resources>
diff --git a/res/values-eu-v23/strings.xml b/res/values-eu-rES-v23/strings.xml
index 86f40b71..86f40b71 100644
--- a/res/values-eu-v23/strings.xml
+++ b/res/values-eu-rES-v23/strings.xml
diff --git a/res/values-eu/arrays.xml b/res/values-eu-rES/arrays.xml
index 89b32135..89b32135 100644
--- a/res/values-eu/arrays.xml
+++ b/res/values-eu-rES/arrays.xml
diff --git a/res/values-eu/rating_system_strings.xml b/res/values-eu-rES/rating_system_strings.xml
index ae0d84d4..ae0d84d4 100644
--- a/res/values-eu/rating_system_strings.xml
+++ b/res/values-eu-rES/rating_system_strings.xml
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
new file mode 100644
index 00000000..ca3d61a6
--- /dev/null
+++ b/res/values-eu-rES/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"estereo"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Erreprodukzioa kontrolatzeko aukerak"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanalak"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"Telebistaren aukerak"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Erreprodukzioa kontrolatzeko aukerak ez daude erabilgarri kanal honetan"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Erreproduzitu edo pausatu"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Aurreratu"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Atzeratu"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Hurrengoa"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Aurrekoa"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Telesaioen gida"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Kanal berriak daude"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Ireki <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Azpitituluak"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Bistaratzeko modua"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"Pantaila txikia"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Audio anitza"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Kanal gehiago"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Ezarpenak"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"Telebista (antena/digitala)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Ez dago telesaioei buruzko informaziorik"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Ez dago informaziorik"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blokeatutako kanala"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Hizkuntza ezezaguna"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Azpitituluak - %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Azpitituluak"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Desaktibatuta"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Pertsonalizatu formatua"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Zehaztu azpitituluen hobespen orokorrak"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Bistaratzeko modua"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Audio anitza"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"monoa"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"estereoa"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 inguratzailea"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 inguratzailea"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d kanal"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Pertsonalizatu zerrenda"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Hautatu taldea"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Desautatu taldea"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Taldekatzeko irizpidea"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Kanalen iturburua"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"Bereizmen handia eta estandarra"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Bereizmen handia"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Bereizmen estandarra"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Taldekatzeko irizpidea"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Telesaio hau blokeatuta dago"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Programa honek ez du adin-sailkapenik"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Telesaioa \"<xliff:g id="RATING">%1$s</xliff:g>\" gisa sailkatu da"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Sarrerak ez du automatikoki sintonizatzeko aukera onartzen"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Ezin da hasi \"<xliff:g id="TV_INPUT">%s</xliff:g>\" automatikoki sintonizatzen"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Ezin dira ireki sistemaren azpitituluen hobespenak."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d kanal gehitu dira</item>
+ <item quantity="one">%1$d kanal gehitu da</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Ez da gehitu kanalik"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Gurasoen ezarpenak"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Aktibatuta"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Desaktibatuta"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Kanalak blokeatuta"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Blokeatu guztiak"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Desblokeatu guztiak"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Ezkutuko kanalak"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Telesaioen murrizk."</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"Aldatu PIN kodea"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Sailkapen-sistemak"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Balorazioak"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Sailkapen-sistema guztiak"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Beste herrialdeak"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Bat ere ez"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Bat ere ez"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Ez du adin-sailkapenik"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blokeatu adin-sailkapenik gabeko programak"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Bat ere ez"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Murrizketa asko"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Erdi-mailako murriztapenak"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Murriztapen gutxi"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Pertsonalizatua"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Edukia egokia da umeentzat"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Edukia egokia da beste ume batzuentzat"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Edukia egokia da nerabeentzat"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Eskuzko murrizketak"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s eta azpisailkapenak"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Azpisailkapenak"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Kanal hau ikusi nahi baduzu, idatzi PIN kodea."</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Telesaio hau ikusi nahi baduzu, idatzi PIN kodea."</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Programaren balorazioa: <xliff:g id="RATING">%1$s</xliff:g>. Idatzi PIN kodea programa ikusteko."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Programa honek ez du adin-sailkapenik. Programa ikusteko, idatzi PIN kodea."</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"Idatzi PIN kodea"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Gurasoen kontrol-aukerak zehazteko, sortu PIN kode bat"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Idatzi PIN kode berria"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"Berretsi PIN kodea"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Idatzi uneko PIN kodea"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Bost aldiz oker idatzi duzu PIN kodea.\nSaiatu berriro <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundo barru.</item>
+ <item quantity="one">Bost aldiz oker idatzi duzu PIN kodea.\nSaiatu berriro <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> segundo barru.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN kodea ez da zuzena. Saiatu berriro."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"PIN kodeak ez datoz bat. Saiatu berriro."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Idatzi posta-kodea."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"\"Telebista zuzenean\" aplikazioak posta-kodea erabiliko du telebistako kanalen programen gida osoa eskaintzeko."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Idatzi posta-kodea"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Posta-kodeak ez du balio"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Ezarpenak"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Pertsonalizatu zerrenda"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Aukeratu telesaioen gidako kanalak"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanalen iturburuak"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Kanal berriak daude eskuragarri"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Gurasoen ezarpenak"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Zuzeneko igorpenetan erreprodukzioa kontrolatzeko aukera"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Grabatu ikusten ari zarena, zuzeneko igorpenak unean bertan pausatu edo atzeratu ahal izateko.\nAbisua: hori egiteko memoria asko erabiltzen denez, aukera hau erabiltzeak barneko memoriaren iraupena murritz lezake."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Kode irekiko lizentziak"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Bidali iritzia"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Bertsioa"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Kanal hau ikusteko, sakatu Eskuinera tekla eta idatzi PIN kodea."</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Telesaio hau ikusteko, sakatu Eskuinera tekla eta idatzi PIN kodea."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Programa honek ez du adin-sailkapenik.\nPrograma hau ikusteko, sakatu Eskuinera tekla eta idatzi PIN kodea."</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Telesaioa \"<xliff:g id="RATING">%1$s</xliff:g>\" gisa sailkatu da.\nIkusi ahal izateko, sakatu Eskuinera tekla eta idatzi PIN kodea."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Kanala ikusteko, erabili telebista zuzenean ikusteko aplikazio lehenetsia."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Telesaioa ikusi ahal izateko, erabili telebista zuzenean ikusteko aplikazio lehenetsia."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Programa honek ez du adin-sailkapenik.\nPrograma hau ikusteko, erabili telebista zuzenean ikusteko aplikazio lehenetsia."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Telesaioa <xliff:g id="RATING">%1$s</xliff:g> gisa sailkatu da.\nIkusi ahal izateko, erabili telebista zuzenean ikusteko aplikazio lehenetsia."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Telesaioa blokeatuta dago"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Programa honek ez du adin-sailkapenik"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Telesaioa \"<xliff:g id="RATING">%1$s</xliff:g>\" gisa sailkatu da"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audioa soilik"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Seinale ahula"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Ez zaude Internetera konektatuta"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">Kanal hau ezin da erreproduzitu <xliff:g id="END_TIME_1">%1$s</xliff:g> arte, beste kanal batzuk grabatzen ari garelako. \n\nGrabaketaren orduak aldatzeko, sakatu Eskuinera tekla.</item>
+ <item quantity="one">Kanal hau ezin da erreproduzitu <xliff:g id="END_TIME_0">%1$s</xliff:g> arte, beste kanal bat ari garelako grabatzen. \n\nGrabaketaren orduak aldatzeko, sakatu Eskuinera tekla.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Izenik ez"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanala blokeatuta dago"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Berriak"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Iturburuak"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d kanal</item>
+ <item quantity="one">%1$d kanal</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Ez dago kanalik erabilgarri"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Berriak"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Konfiguratu gabe"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Lortu iturburu gehiago"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Arakatu edukia zuzenean igortzen duten kanalak eskaintzen dituzten aplikazioak"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Kanalen iturburu berriak daude erabilgarri"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Beste kanal batzuk eskaintzen dituzten iturburu berriak dituzu eskura.\nKonfigura itzazu oraintxe bertan edo egin ezazu beste uneren batean kanalen iturburuen ezarpenera joanda."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Konfiguratu"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Ados"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>"Telebistaren menua atzitzeko, sakatu HAUTATU"</b></string>
+ <string name="msg_no_input" msgid="3897674146985427865">"Ez da telebista-sarrerarik aurkitu"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"Ezin da aurkitu telebista-sarrera"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Sintonizagailua ez da egokia. Abiarazi Telebista zuzenean aplikazioa sintonizagailua telebistaren sarrera gisa erabiltzeko."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Ezin izan da sintonizatu"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Ez da aurkitu ekintza gauza dezakeen aplikaziorik."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Iturburuko kanal guztiak ezkutuan daude.\nHautatu gutxienez kanal bat ikusteko."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Bideoa ez dago erabilgarri"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"Atzera tekla konektatutako gailuari dagokio. Irteteko, sakatu Hasiera botoia."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Telebista zuzenean aplikazioak baimena behar du telebistako programazioa irakurtzeko."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Konfiguratu iturburuak"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Telebista zuzenean zerbitzuarekin, aplikazioek zuzenean erreproduzitzen dituzten kanalak ohiko telebistaren moduan ikus ditzakezu. \n\nLehen urratsak emateko, konfiguratu instalatutako kanal-iturburuak. Bestela, arakatu Google Play Store denda zuzeneko kanalak eskaintzen dituzten aplikazio gehiago aurkitzeko."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Grabaketak eta grabaketen programazioa"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minutu"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minutu"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ordu"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ordu"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Azkenak"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Programatutakoak"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Telesailak"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Beste batzuk"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Ezin da grabatu kanal hau."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Ezin da grabatu programa hau."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> grabatzeko programatu da"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> grabatuko da <xliff:g id="ENDTIME">%2$s</xliff:g> arte"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Programazio osoa"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">Beste %1$d egun</item>
+ <item quantity="one">Beste %1$d egun</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d minutu</item>
+ <item quantity="one">%1$d minutu</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d grabaketa berri</item>
+ <item quantity="one">%1$d grabaketa berri</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d grabaketa</item>
+ <item quantity="one">%1$d grabaketa</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d grabaketa antolatuta</item>
+ <item quantity="one">%1$d grabaketa antolatuta</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Ez grabatu"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Gelditu grabaketa"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Ikusi"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Erreproduzitu hasieratik"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Berrekin"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Ezabatu"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Ezabatu grabaketak"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Berrekin"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. denboraldia"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Ikusi agenda"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Irakurri gehiago"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Ezabatu grabaketak"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Hautatu ezabatu nahi dituzun atalak. Ezabatu ondoren, ezingo dituzu berreskuratu."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Ez dago ezaba daitekeen grabaketarik."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Hautatu ikusitako atalak"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Hautatu atal guztiak"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Ezabatu atal guztiak"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g>/<xliff:g id="DURATION">%2$d</xliff:g> minutu ikusi dituzu"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g>/<xliff:g id="DURATION">%2$d</xliff:g> segundo ikusi dituzu"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Inoiz ikusi gabe"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%1$d/%2$d atal ezabatu dira</item>
+ <item quantity="one">%1$d/%2$d atal ezabatu da</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Lehentasuna"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Handiena"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Txikiena"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"<xliff:g id="RANK">%1$d</xliff:g>.a"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Kanalak"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Edozein"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Aukeratu lehentasuna"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Aldi berean programa gehiegi grabatu behar badira, lehentasun handieneko programak bakarrik grabatuko dira."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Gorde"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Grabaketa solteek dute lehentasun handiena"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Gelditu"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Ikusi grabaketen agenda"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Programa hau bakarrik"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"orain – <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Telesail osoa…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Programatu, hala ere"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Grabatu beste hau haren ordez"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Utzi grabaketa hau bertan behera"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Ikusi"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Ezabatu grabaketak…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Graba daiteke"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Grabatzeko programatuta"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Grabatzeko gatazka"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Grabatzen"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Ezin izan da grabatu"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Programazioa irakurtzen"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Ikusi azken grabaketak"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Ezin izan da osorik grabatu <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Ezin izan dira osorik grabatu <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> eta <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Ezin izan dira osorik grabatu <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> eta <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Ezin izan da osorik grabatu <xliff:g id="PROGRAMNAME">%1$s</xliff:g>, memoria agortu delako."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Ezin izan dira osorik grabatu <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> eta <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, memoria agortu delako."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Ezin izan dira osorik grabatu <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> eta <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>, memoria agortu delako."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Bideo-grabagailu digitalak ez dauka behar adina memoria erabilgarri"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Bideo-grabagailu digitalarekin programak grabatu ahal izango dituzu. Dena dela, une honetan ez daukazu bideo-grabagailua erabili ahal izateko behar adina memoria erabilgarri. Konektatu <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB edo gehiago dituen unitate aldagarri bat eta formatea ezazu gailuaren memoria gisa erabiltzeko."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Ez dago behar adina toki"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Ezingo dugu grabatu telesaio hau, ez delako behar adina toki geratzen. Ezabatu grabaketa batzuk tokia egiteko."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Memoria-unitatea falta da"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Grabaketa gelditu nahi duzu?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Grabatutako edukia gordeta geratuko da."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> grabatzeari utziko zaio programa honekin gatazkan dagoelako. Gorde egingo da grabatutako edukia."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Grabatzeko programatu da baina gatazkan dago beste grabaketa batzuekin"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Grabatzen hasi da, baina gatazkak ditu"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> grabatuko da."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> grabatzen ari da."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ez da osorik grabatuko."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> eta <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ez dira osorik grabatuko."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> eta grabatzeko programatuta dagoen beste saio bat ez dira osorik grabatuko."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> eta grabatzeko programatuta dauden beste %3$d saio ez dira osorik grabatuko.</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> eta grabatzeko programatuta dagoen beste %3$d saio ez dira osorik grabatuko.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Zer grabatu nahi duzu?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Zenbat denboran grabatu nahi duzu?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Programatuta dago dagoeneko"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Programa hau bera grabatzeko programatu duzu dagoeneko (<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>)."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Grabatuta dago dagoeneko"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Programa hau grabatuta daukazu dagoeneko. DVR liburutegian duzu ikusgai."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Telesaila grabatzeko antolatuta dago"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> grabaketa antolatu dira (<xliff:g id="SERIESNAME_3">%2$s</xliff:g>).</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabaketa antolatu da (<xliff:g id="SERIESNAME_1">%2$s</xliff:g>).</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> grabaketa antolatu dira (<xliff:g id="SERIESNAME_3">%2$s</xliff:g>). Haietako <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> ezin izango dira grabatu gatazkak daudelako.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabaketa antolatu da (<xliff:g id="SERIESNAME_1">%2$s</xliff:g>). Ezin izango da grabatu gatazkak daudelako.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> grabaketa antolatu dira (<xliff:g id="SERIESNAME_4">%2$s</xliff:g>). Telesail horren eta beste batzuen <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> atal ezin izango dira grabatu gatazkak daudelako.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabaketa antolatu da (<xliff:g id="SERIESNAME_1">%2$s</xliff:g>). Telesail horren eta beste batzuen <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> atal ezin izango dira grabatu gatazkak daudelako.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> grabaketa antolatu dira (<xliff:g id="SERIESNAME_3">%2$s</xliff:g>). Beste telesail baten atal bat ezin izango da grabatu gatazkak daudelako.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabaketa antolatu da (<xliff:g id="SERIESNAME_1">%2$s</xliff:g>). Beste telesail baten atal bat ezin izango da grabatu gatazkak daudelako.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> grabaketa antolatu dira (<xliff:g id="SERIESNAME_4">%2$s</xliff:g>). Beste telesail batzuen <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> atal ezin izango dira grabatu gatazkak daudelako.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> grabaketa antolatu da (<xliff:g id="SERIESNAME_1">%2$s</xliff:g>). Beste telesail batzuen <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> atal ezin izango dira grabatu gatazkak daudelako.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Ez da aurkitu grabatutako programa."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Erlazionatutako grabaketak"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d grabaketa</item>
+ <item quantity="one">%1$d grabaketa</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> kendu egin da programatutako grabaketen zerrendatik"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Partzialki grabatuko da, sintonizadoreak gatazkak baititu."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Ez da grabatuko, sintonizadoreak gatazkak baititu."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Oraindik ez duzu programatu grabaketarik.\nProgramazio-gidan programa ditzakezu grabaketak."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d grabaketa-gatazka</item>
+ <item quantity="one">%1$d grabaketa-gatazka</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Seriearen ezarpenak"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Hasi seriea grabatzen"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Utzi seriea grabatzeari"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Seriea grabatzeari utzi nahi diozu?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"DVR liburutegian gordeta geratuko dira grabatutako atalak."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Gelditu"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Une honetan ez dira ari atalik igortzen."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Ez dago atalik ikusgai.\nIkusgai ezartzen dituztenean grabatuko ditugu."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d minutu)</item>
+ <item quantity="one">(%1$d minutu) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Gaur"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Bihar"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Atzo"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"Gaur, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Bihar, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Puntuazioa"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Grabatutako programak"</string>
+</resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
deleted file mode 100644
index 19a00433..00000000
--- a/res/values-eu/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"estereo"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Erreprodukzioa kontrolatzeko aukerak"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Azken kanalak"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"Telebistaren aukerak"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Pantaila txikia"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Erreprodukzioa kontrolatzeko aukerak ez daude erabilgarri kanal honetan"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Erreproduzitu edo pausatu"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Aurreratu"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Atzeratu"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Hurrengoa"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Aurrekoa"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Telesaioen gida"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Kanal berriak daude"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Ireki <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Azpitituluak"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Bistaratzeko modua"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"Pantaila txikia"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Aktibatuta"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Desaktibatuta"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Audio anitza"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Kanal gehiago"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Ezarpenak"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Iturburua"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Aldatu"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Aktibatuta"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Desaktibatuta"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Soinua"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Nagusia"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Pantaila txikia"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Diseinua"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Behean eskuinean"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Goian eskuinean"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Goian ezkerrean"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Behean ezkerrean"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Alboz albo"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Tamaina"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Handia"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Txikia"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Sarrera-iturburua"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"Telebista (antena/digitala)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Ez dago telesaioei buruzko informaziorik"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Ez dago informaziorik"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blokeatutako kanala"</string>
- <string name="default_language" msgid="4122326459624337928">"Hizkuntza ezezaguna"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Azpitituluak"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Desaktibatuta"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Pertsonalizatu formatua"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Zehaztu azpitituluen hobespen orokorrak"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Bistaratzeko modua"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Audio anitza"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"monoa"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"estereoa"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 inguratzailea"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 inguratzailea"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d kanal"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Pertsonalizatu zerrenda"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Hautatu taldea"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Desautatu taldea"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Taldekatzeko irizpidea"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Kanalen iturburua"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"Bereizmen handia eta estandarra"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Bereizmen handia"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Bereizmen estandarra"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Taldekatzeko irizpidea"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Telesaio hau blokeatuta dago"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Telesaioa \"<xliff:g id="RATING">%1$s</xliff:g>\" gisa sailkatu da"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Sarrerak ez du automatikoki sintonizatzeko aukera onartzen"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Ezin da hasi \"<xliff:g id="TV_INPUT">%s</xliff:g>\" automatikoki sintonizatzen"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Ezin dira ireki sistemaren azpitituluen hobespenak."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d kanal gehitu dira</item>
- <item quantity="one">%1$d kanal gehitu da</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Ez da gehitu kanalik"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Sintonizadorea"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Gurasoen ezarpenak"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Aktibatuta"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Desaktibatuta"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Kanalak blokeatuta"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Blokeatu guztiak"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Desblokeatu guztiak"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Ezkutuko kanalak"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Telesaioen murrizk."</string>
- <string name="option_change_pin" msgid="2881594075631152566">"Aldatu PIN kodea"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Sailkapen-sistemak"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Balorazioak"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Sailkapen-sistema guztiak"</string>
- <string name="other_countries" msgid="8342216398676184749">"Beste herrialdeak"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Bat ere ez"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Bat ere ez"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Bat ere ez"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Murrizketa asko"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Erdi-mailako murriztapenak"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Murriztapen gutxi"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Pertsonalizatua"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Edukia egokia da umeentzat"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Edukia egokia da beste ume batzuentzat"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Edukia egokia da nerabeentzat"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Eskuzko murrizketak"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s eta azpisailkapenak"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Azpisailkapenak"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Kanal hau ikusi nahi baduzu, idatzi PIN kodea."</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Telesaio hau ikusi nahi baduzu, idatzi PIN kodea."</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Programaren balorazioa: <xliff:g id="RATING">%1$s</xliff:g>. Idatzi PIN kodea programa ikusteko."</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"Idatzi PIN kodea"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Gurasoen kontrol-aukerak zehazteko, sortu PIN kode bat"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Idatzi PIN kode berria"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"Berretsi PIN kodea"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Idatzi uneko PIN kodea"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">Bost aldiz oker idatzi duzu PIN kodea.\nSaiatu berriro <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundo barru.</item>
- <item quantity="one">Bost aldiz oker idatzi duzu PIN kodea.\nSaiatu berriro <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> segundo barru.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN kodea ez da zuzena. Saiatu berriro."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"PIN kodeak ez datoz bat. Saiatu berriro."</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Ezarpenak"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Pertsonalizatu zerrenda"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Aukeratu telesaioen gidako kanalak"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanalen iturburuak"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Kanal berriak daude eskuragarri"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Gurasoen ezarpenak"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Kode irekiko lizentziak"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Kode irekiko lizentziak"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Bertsioa"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Kanal hau ikusteko, sakatu Eskuinera tekla eta idatzi PIN kodea."</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Telesaio hau ikusteko, sakatu Eskuinera tekla eta idatzi PIN kodea."</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Telesaioa \"<xliff:g id="RATING">%1$s</xliff:g>\" gisa sailkatu da.\nIkusi ahal izateko, sakatu Eskuinera tekla eta idatzi PIN kodea."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Kanala ikusteko, erabili telebista zuzenean ikusteko aplikazio lehenetsia."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Telesaioa ikusi ahal izateko, erabili telebista zuzenean ikusteko aplikazio lehenetsia."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Telesaioa <xliff:g id="RATING">%1$s</xliff:g> gisa sailkatu da.\nIkusi ahal izateko, erabili telebista zuzenean ikusteko aplikazio lehenetsia."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Telesaioa blokeatuta dago"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Telesaioa \"<xliff:g id="RATING">%1$s</xliff:g>\" gisa sailkatu da"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audioa soilik"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Seinale ahula"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Ez zaude Internetera konektatuta"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Kanal hau ezin da erreproduzitu <xliff:g id="END_TIME_1">%1$s</xliff:g> arte, beste kanal batzuk grabatzen ari garelako. \n\nGrabaketaren orduak aldatzeko, sakatu Eskuinera tekla.</item>
- <item quantity="one">Kanal hau ezin da erreproduzitu <xliff:g id="END_TIME_0">%1$s</xliff:g> arte, beste kanal bat ari garelako grabatzen. \n\nGrabaketaren orduak aldatzeko, sakatu Eskuinera tekla.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Izenik ez"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanala blokeatuta dago"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Berriak"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Iturburuak"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d kanal</item>
- <item quantity="one">%1$d kanal</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Ez dago kanalik erabilgarri"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Berriak"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Konfiguratu gabe"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Lortu iturburu gehiago"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Arakatu edukia zuzenean igortzen duten kanalak eskaintzen dituzten aplikazioak"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Kanalen iturburu berriak daude erabilgarri"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Beste kanal batzuk eskaintzen dituzten iturburu berriak dituzu eskura.\nKonfigura itzazu oraintxe bertan edo egin ezazu beste uneren batean kanalen iturburuen ezarpenera joanda."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Konfiguratu"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"Ados"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307"><b>"Telebistaren menua atzitzeko, sakatu HAUTATU"</b></string>
- <string name="msg_no_input" msgid="3897674146985427865">"Ez da telebista-sarrerarik aurkitu"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"Ezin da aurkitu telebista-sarrera"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Ez da pantaila txikia erabiltzea onartzen"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Ez dago pantaila txikian erakuts daitekeen sarrerarik"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Sintonizagailua ez da egokia. Abiarazi zuzeneko kanalen aplikazioa sintonizagailua telebistaren sarrera gisa erabiltzeko."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Ezin izan da sintonizatu"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Ez da aurkitu ekintza gauza dezakeen aplikaziorik."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Iturburuko kanal guztiak ezkutuan daude.\nHautatu gutxienez kanal bat ikusteko."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Bideoa ez dago erabilgarri"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"Atzera tekla konektatutako gailuari dagokio. Irteteko, sakatu Hasiera botoia."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Zuzeneko kanalak aplikazioak baimena behar du telebistako programazioa irakurtzeko."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Konfiguratu iturburuak"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Telebista zuzenean zerbitzuarekin, aplikazioek zuzenean erreproduzitzen dituzten kanalak ohiko telebistaren moduan ikus ditzakezu. \n\nLehen urratsak emateko, konfiguratu instalatutako kanal-iturburuak. Bestela, arakatu Google Play Store denda zuzeneko kanalak eskaintzen dituzten aplikazio gehiago aurkitzeko."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Grabaketak eta grabaketen programazioa"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minutu"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minutu"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ordu"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ordu"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Azkenak"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Programatutakoak"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Telesailak"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Beste batzuk"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Ezin da grabatu kanal hau."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Ezin da grabatu programa hau."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> grabatzeko programatu da"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> grabatuko da <xliff:g id="ENDTIME">%2$s</xliff:g> arte"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Programazio osoa"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">Beste %1$d egun</item>
- <item quantity="one">Beste %1$d egun</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d minutu</item>
- <item quantity="one">%1$d minutu</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d grabaketa berri</item>
- <item quantity="one">%1$d grabaketa berri</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d grabaketa</item>
- <item quantity="one">%1$d grabaketa</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d grabaketa antolatuta</item>
- <item quantity="one">%1$d grabaketa antolatuta</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Ikusi"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Erreproduzitu hasieratik"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Berrekin"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Ezabatu"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Ezabatu grabaketak"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Berrekin"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>. denboraldia"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Ikusi agenda"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Irakurri gehiago"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Ezabatu grabaketak"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Hautatu ezabatu nahi dituzun atalak. Ezabatu ondoren, ezingo dituzu berreskuratu."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Ez dago ezaba daitekeen grabaketarik."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Hautatu ikusitako atalak"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Hautatu atal guztiak"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Ezabatu atal guztiak"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g>/<xliff:g id="DURATION">%2$d</xliff:g> minutu ikusi dituzu"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g>/<xliff:g id="DURATION">%2$d</xliff:g> segundo ikusi dituzu"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Inoiz ikusi gabe"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%1$d/%2$d atal ezabatu dira</item>
- <item quantity="one">%1$d/%2$d atal ezabatu da</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Lehentasuna"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Handiena"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Txikiena"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"<xliff:g id="RANK">%1$d</xliff:g>.a"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Kanalak"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Edozein"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Aukeratu lehentasuna"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Aldi berean programa gehiegi grabatu behar badira, lehentasun handieneko programak bakarrik grabatuko dira."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Gorde"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Grabaketa solteek dute lehentasun handiena"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Utzi"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Utzi"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Ahaztu"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Gelditu"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Ikusi grabaketen agenda"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Programa hau bakarrik"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"orain – <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Telesail osoa…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Programatu, hala ere"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Grabatu beste hau haren ordez"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Utzi grabaketa hau bertan behera"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Ikusi"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Graba daiteke"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Grabatzeko antolatuta"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Grabatzeko gatazka"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Grabatzen"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Ezin izan da grabatu"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Programak irakurtzen ari gara grabaketa-ordutegiak sortzeko"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Programazioa irakurtzen"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Bideo-grabagailu digitalak ez dauka behar adina memoria erabilgarri"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Bideo-grabagailu digitalarekin programak grabatu ahal izango dituzu. Dena dela, une honetan ez daukazu bideo-grabagailua erabili ahal izateko behar adina memoria erabilgarri. Konektatu <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB edo gehiago dituen unitate aldagarri bat eta formatea ezazu gailuaren memoria gisa erabiltzeko."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Memoria-unitatea falta da"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Bideo-grabagailu digitalak erabili duen memoria-unitateren bat falta da. Bideo-grabagailu digitala gaitu ahal izateko, konektatu aurrez erabilitako unitate aldagarria. Memoria-unitate hura eskura ez baduzu, berriz, aukera ezazu unitatea ahazteko aukera."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Memoria-unitate hau ahaztea nahi duzu?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Grabatuta edo programatuta duzun eduki guztia galduko da."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Grabaketa gelditu nahi duzu?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Grabatutako edukia gordeta geratuko da."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Grabatzeko programatu da baina gatazkan dago beste grabaketa batzuekin"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Grabatzen hasi da, baina gatazkak ditu"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> grabatuko da."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> grabatzen ari da."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ez da osorik grabatuko."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> eta <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ez dira osorik grabatuko."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> eta grabatzeko programatuta dagoen beste saio bat ez dira osorik grabatuko."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> eta grabatzeko programatuta dauden beste %3$d saio ez dira osorik grabatuko.</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> eta grabatzeko programatuta dagoen beste %3$d saio ez dira osorik grabatuko.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Zer grabatu nahi duzu?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Zenbat denboran grabatu nahi duzu?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Programatuta dago dagoeneko"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Programa hau bera grabatzeko programatu duzu dagoeneko (<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>)."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Grabatuta dago dagoeneko"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Programa hau grabatuta daukazu dagoeneko. DVR liburutegian duzu ikusgai."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Ez da aurkitu grabatutako programa."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Erlazionatutako grabaketak"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Ez dago programaren azalpenik)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d grabaketa</item>
- <item quantity="one">%1$d grabaketa</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> kendu egin da programatutako grabaketen zerrendatik"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Partzialki grabatuko da, sintonizadoreak gatazkak baititu."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Ez da grabatuko, sintonizadoreak gatazkak baititu."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Oraindik ez duzu programatu grabaketarik.\nProgramazio-gidan programa ditzakezu grabaketak."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d grabaketa-gatazka</item>
- <item quantity="one">%1$d grabaketa-gatazka</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Seriearen ezarpenak"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Hasi seriea grabatzen"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Utzi seriea grabatzeari"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Seriea grabatzeari utzi nahi diozu?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"DVR liburutegian gordeta geratuko dira grabatutako atalak."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Gelditu"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Ez dago atalik ikusgai.\nIkusgai ezartzen dituztenean grabatuko ditugu."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d minutu)</item>
- <item quantity="one">(%1$d minutu) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Gaur"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Bihar"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Atzo"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"Gaur, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Bihar, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Puntuazioa"</string>
-</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 7dd59c28..752f93e0 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"مونو"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"استریو"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"کنترل‌های پخش"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"کانال‌های اخیر"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"کانال‌ها"</string>
<string name="menu_title_options" msgid="7184594626814914022">"گزینه‌‌ تلویزیون"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"‏گزینه‌های PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"دسترسی به کنترل‌های پخش برای این کانال امکان‌پذیر نیست"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"پخش یا مکث"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"جلو بردن سریع"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"زیرنویس‌ها"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"حالت نمایش"</string>
<string name="options_item_pip" msgid="3951350386626879645">"تصویر در تصویر"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"روشن"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"خاموش"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"چند صدایی"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"دریافت کانا‌ل‌های بیشتر"</string>
<string name="options_item_settings" msgid="7623205838542400074">"تنظیمات"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"منبع"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"تعویض"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"روشن"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"خاموش"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"صدا"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"اصلی"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"پنجره تصویردرتصویر"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"طرح‌بندی"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"پایین سمت راست"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"بالا سمت راست"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"بالا سمت چپ"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"پایین سمت چپ"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"پهلو به پهلو"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"اندازه"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"بزرگ"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"کوچک"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"منبع ورودی"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"تلویزیون (آنتنی/کابلی)"</string>
<string name="no_program_information" msgid="1049844207745145132">"هیچ اطلاعات برنامه‌ای وجود ندارد"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"هیچ اطلاعاتی موجود نیست"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"کانال مسدود شده"</string>
- <string name="default_language" msgid="4122326459624337928">"زبان نامشخص"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"زبان نامشخص"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"‏زیرنویس %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"زیرنویس"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"خاموش"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"سفارشی کردن قالب‌بندی"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"وضوح استاندارد"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"گروه‌بندی براساس"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"این برنامه مسدود است"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"این برنامه رتبه‌بندی نشده است"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"رتبه‌بندی این برنامه <xliff:g id="RATING">%1$s</xliff:g> است."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"ورودی از اسکن خودکار پشتیبانی نمی‌کند"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"اسکن خودکار «<xliff:g id="TV_INPUT">%s</xliff:g>» شروع نمی‌شود"</string>
@@ -92,7 +74,6 @@
<item quantity="other">‏%1$d کانال اضافه شد</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"هیچ کانالی اضافه نشد"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"تیونر"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"کنترل‌های والدین"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"روشن"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"خاموش"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"کشورهای دیگر"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"هیچ‌‌کدام"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"هیچ‌‌کدام"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"بدون رتبه‌بندی"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"مسدود کردن برنامه‌های رتبه‌بندی‌نشده"</string>
<string name="option_rating_none" msgid="5204552587760414879">"هیچ‌‌کدام"</string>
<string name="option_rating_high" msgid="8898400296730158893">"محدودیت‌های زیاد"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"محدودیت‌های متوسط"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"برای تماشای این کانال، پین خودتان را وارد کنید"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"برای تماشای این برنامه، پین خودتان را وارد کنید"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"به این برنامه <xliff:g id="RATING">%1$s</xliff:g> رتبه داده شده است. برای تماشای این برنامه کد پین را وارد کنید"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"این برنامه رتبه‌بندی نشده است. برای تماشای این برنامه باید پین خود را وارد کنید."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"پین خودتان را وارد کنید"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"برای تنظیم کنترل‌های والدین، پین ایجاد کنید"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"پین جدید را وارد کنید"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"این پین اشتباه بود. دوباره امتحان کنید."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"دوباره امتحان کنید، پین منطبق نیست"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"زیپ‌کدتان را وارد کنید."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"برنامه «کانال‌های زنده» از زیپ‌کد جهت ارائه یک راهنمای برنامه کامل برای کانال‌های تلویزیونی استفاده می‌کند."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"زیپ‌کدتان را وارد کنید"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"زیپ‌کد نامعتبر است"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"تنظیمات"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"سفارشی کردن فهرست کانال‌ها"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"کانال‌ها را برای راهنمای برنامه‌تان انتخاب کنید"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"منابع کانال"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"کانال‌های جدید در دسترس است"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"کنترل‌های والدین"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"تایم شیفت"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"درحین تماشا ضبط کنید، به‌این‌ترتیب می‌توانید برنامه‌های زنده را موقتاً متوقف کنید یا به عقب برگردانید.\nاخطار: این قابلیت ممکن است به دلیل استفاده بیش‌ازحد از فضای ذخیره‌سازی، باعث کاهش عمرمفید حافظه داخلی شود."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"مجوزهای منبع آزاد"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"مجوزهای منبع آزاد"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"ارسال بازخورد"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"نسخه"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"برای مشاهده این کانال، راست را فشار دهید و پین خودتان را وارد کنید"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"برای مشاهده این برنامه، راست را فشار دهید و پین خودتان را وارد کنید"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"‏این برنامه رتبه‌بندی نشده است.\nبرای تماشای این برنامه، Right (راست) را فشار دهید و پین خود را وارد کنید"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"‏رتبه‌بندی این برنامه <xliff:g id="RATING">%1$s</xliff:g> است.\nبرای تماشای این برنامه، Right (راست) را فشار دهید و پین خودتان را وارد کنید."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"برای تماشای این کانال، از برنامه «پخش مستقیم» پیش‌فرض استفاده کنید."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"برای تماشای این برنامه، از برنامه «پخش مستقیم» پیش‌فرض استفاده کنید."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"این برنامه رتبه‌بندی نشده است.\nبرای تماشای این برنامه، از برنامه «پخش مستقیم» پیش‌فرض استفاده کنید."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"به این برنامه رتبه <xliff:g id="RATING">%1$s</xliff:g> داده شده است.\n برای تماشای این برنامه، از برنامه «پخش مستقیم» استفاده کنید."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"برنامه مسدود شده است"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"این برنامه رتبه‌بندی نشده است"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"رتبه‌بندی این برنامه <xliff:g id="RATING">%1$s</xliff:g> است."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"فقط صدا"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"سیگنال ضعیف است"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307">"‏برای دسترسی به منوی تلویزیون، "<b>"SELECT (انتخاب) را فشار دهید"</b>"."</string>
<string name="msg_no_input" msgid="3897674146985427865">"هیچ ورودی تلویزیون یافت نشد"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"نمی‌توان ورودی تلویزیون پیدا کرد"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"تصویر در تصویر پشتیبانی نمی‌شود."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"ورودی قابل نمایش با تصویر در تصویر، در دسترس نیست."</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"نوع تیونر مناسب نیست. لطفاً برنامه‌ «کانال‌های مستقیم» را برای ورودی تلویزیون نوع تیونر، راه‌اندازی کنید."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"تنظیم نشد"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"برنامه‌ای برای انجام این اقدام پیدا نشد."</string>
@@ -226,6 +217,8 @@
<item quantity="one">‏%1$d ضبط زمان‌بندی‌شده</item>
<item quantity="other">‏%1$d ضبط زمان‌بندی‌شده</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"لغو ضبط"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"توقف ضبط"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"ساعت مچی"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"پخش از اول"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"ازسرگیری پخش"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"اگر برنامه‌های زیادی برای ضبط هم‌زمان وجود داشته باشد، فقط برنامه‌های با بیشترین اولویت ضبط خواهند شد."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"ذخیره"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ضبط‌های تکی بالاترین اولویت را دارند"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"لغو"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"لغو"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"فراموش شود"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"توقف"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"مشاهده زمان‌بندی ضبط"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"فقط همین برنامه"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"درعوض این مورد ضبط شود"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"لغو این ضبط"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"اکنون تماشا کنید"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"درحال حذف موارد ضبط‌شده…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"قابل ضبط"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ضبط برنامه‌ریزی‌شده"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ضبط متناقض با زمان‌بندی"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"درحال ضبط"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ضبط ناموفق بود"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"درحال خواندن برنامه‌ها برای ایجاد زمان‌بندی ضبط"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"درحال خواندن برنامه‌ها"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"درحال خواندن برنامه‌ها"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"مشاهده موارد ضبط‌شده اخیر"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"ضبط <xliff:g id="PROGRAMNAME">%1$s</xliff:g> کامل نشده است."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"ضبط <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> و <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> کامل نشده است."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"ضبط <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>، <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> و <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> کامل نشده است."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"به دلیل حافظه ناکافی، ضبط <xliff:g id="PROGRAMNAME">%1$s</xliff:g> کامل نشد."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"به دلیل حافظه ناکافی، ضبط <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> و<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> کامل نشد."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"به دلیل حافظه ناکافی، ضبط <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>، <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> و <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> کامل نشد."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"‏DVR به فضای بیشتری نیاز دارد"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"‏با DVR می‌توانید برنامه‌ها را ضبط کنید. اما اکنون فضای ذخیره‌سازی کافی در دستگاهتان وجود ندارد و DVR کار نمی‌کند. لطفاً درایو خارجی‌‌ای با حجم <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> گیگابایت یا بیشتر متصل کنید و برای قالب‌بندی آن‌ به‌عنوان حافظه دستگاه این مراحل را دنبال کنید."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"‏با DVR می‌توانید برنامه‌ها را ضبط کنید. اما اکنون فضای ذخیره‌سازی کافی در دستگاهتان وجود ندارد و DVR کار نمی‌کند. لطفاً درایو خارجی‌‌ای با حجم <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> گیگابایت یا بیشتر متصل کنید و برای قالب‌بندی آن‌ به‌عنوان حافظه دستگاه این مراحل را دنبال کنید."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"حافظه ذخیره‌سازی کافی نیست"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"این برنامه ضبط نخوادهد شد، زیرا حافظه ذخیره‌سازی وجود ندارد. برخی از موارد ضبط‌‌شده قبلی را حذف کنید."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"حافظه دردسترس نیست"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"‏مقداری از حافظه‌ای که توسط DVR استفاده می‌شود از بین می‌رود. لطفاً برای فعال‌سازی مجدد DVR، درایو خارجی را که قبلاً‌ استفاده کردید متصل کنید. یا اگر این حافظه دیگر دردسترس نیست می‌توانید انتخاب کنید فراموش شود."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"حافظه فراموش شود؟"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"همه زمان‌بندی‌ها و محتوای ضبط‌شده‌ شما از دست می‌رود."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ضبط متوقف شود؟"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"محتوای ضبط‌شده ذخیره خواهد شد."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"ضبط <xliff:g id="PROGRAMNAME">%1$s</xliff:g> به دلیل تناقض با این برنامه متوقف خواهد شد. محتوای ضبط‌شده ذخیره می‌شود."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ضبط، زمان‌بندی شده است اما متناقض است"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ضبط شروع شده است اما متناقض است"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ضبط خواهد شد."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"این برنامه قبلاً‌ برای ضبط در <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> زمان‌بندی شده است."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"قبلاً‌ ضبط شده است"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"‏این برنامه قبلاً‌ ضبط شده است و در کتابخانه DVR موجود است."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"ضبط مجموعه زمان‌بندی شد"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ضبط برای <xliff:g id="SERIESNAME_3">%2$s</xliff:g> زمان‌بندی شده است.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ضبط برای <xliff:g id="SERIESNAME_3">%2$s</xliff:g> زمان‌بندی شده است.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ضبط برای <xliff:g id="SERIESNAME_3">%2$s</xliff:g> زمان‌بندی شده است. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> از آن‌ها به دلیل تناقض ضبط نخواهد شد.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ضبط برای <xliff:g id="SERIESNAME_3">%2$s</xliff:g> زمان‌بندی شده است. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> از آن‌ها به دلیل تناقض ضبط نخواهد شد.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ضبط برای <xliff:g id="SERIESNAME_4">%2$s</xliff:g> زمان‌بندی شده است. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> قسمت این مجموعه و مجموعه‌های دیگر به دلیل تناقض ضبط نخواهند شد.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ضبط برای <xliff:g id="SERIESNAME_4">%2$s</xliff:g> زمان‌بندی شده است. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> قسمت این مجموعه و مجموعه‌های دیگر به دلیل تناقض ضبط نخواهند شد.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ضبط برای <xliff:g id="SERIESNAME_3">%2$s</xliff:g> زمان‌بندی شده است. ۱ قسمت مجموعه‌های دیگر به دلیل تناقض ضبط نخواهد شد.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ضبط برای <xliff:g id="SERIESNAME_3">%2$s</xliff:g> زمان‌بندی شده است. ۱ قسمت مجموعه‌های دیگر به دلیل تناقض ضبط نخواهد شد.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ضبط برای <xliff:g id="SERIESNAME_4">%2$s</xliff:g> زمان‌بندی شده است. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> قسمت مجموعه‌های دیگر به دلیل تناقض ضبط نخواهند شد.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ضبط برای <xliff:g id="SERIESNAME_4">%2$s</xliff:g> زمان‌بندی شده است. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> قسمت مجموعه‌های دیگر به دلیل تناقض ضبط نخواهند شد.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"برنامه ضبط‌شده پیدا نشد."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ضبط‌های مرتبط"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(بدون شرح برنامه)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">‏%1$d ضبط</item>
<item quantity="other">‏%1$d ضبط</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"ضبط مجموعه متوقف شود؟"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"‏قسمت‌های ضبط‌شده در کتابخانه DVR دردسترس باقی می‌ماند."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"توقف"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"درحال‌حاضر قسمتی پخش مستقیم نمی‌شود."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"هیچ قسمتی موجود نیست.\nهر قسمتی در دسترس قرار بگیرد ضبط خواهد شد."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">‏(%1$d دقیقه)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> امروز"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> فردا"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"امتیاز"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"برنامه‌های ضبط‌شده"</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index b6f5fb7e..eba0cc63 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Toistosäätimet"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Viim. kanavat"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanavat"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV-asetukset"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP-asetukset"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Toistosäätimet eivät ole käytettävissä tällä kanavalla."</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Toisto tai keskeytys"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Kelaa eteenpäin"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Tekstitykset"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Näyttötila"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Käytössä"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Ei käytössä"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Moniääni"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Lisää kanavia"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Asetukset"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Lähde"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Vaihda"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Käytössä"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Ei käytössä"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Ääni"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Ensisijainen"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP-ikkuna"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Asettelu"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Alaoikealla"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Yläoikealla"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Ylävasemmalla"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Alavasemmalla"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Vierekkäin"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Mitat"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Suuri"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Pieni"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Syötteen lähde"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenni/kaapeli)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Ei ohjelmatietoja"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Ei tietoja"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Estetty kanava"</string>
- <string name="default_language" msgid="4122326459624337928">"Tuntematon kieli"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Tuntematon kieli"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Tekstitykset %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Tekstitykset"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Ei käytössä"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Muokkaa muotoilua"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Ryhmittely:"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ohjelma on estetty."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ohjelmalla ei ole ikärajaa."</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Tämän ohjelman luokitus on <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Tulo ei tue automaattista skannausta."</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Tulon <xliff:g id="TV_INPUT">%s</xliff:g> automaattista skannausta ei voi käynnistää"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d kanava lisätty</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Kanavia ei lisätty"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Viritin"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Lapsilukko"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Käytössä"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Ei käytössä"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Muut maat"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Ei mitään"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ei mitään"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Ei ikärajaa"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Estä ikärajattomat ohjelmat"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Ei mitään"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Suuret rajoitukset"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Keskim. rajoitukset"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Anna PIN-koodi, jotta voit katsella tätä kanavaa"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Anna PIN-koodi, jotta voit katsella tätä ohjelmaa"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Tämän ohjelman ikärajoitus on <xliff:g id="RATING">%1$s</xliff:g>. Anna PIN-koodi, jos haluat katsoa tätä ohjelmaa."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Tälle ohjelmalle ei ole määritetty ikärajaa. Anna PIN-koodi, jos haluat katsoa sen."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Anna PIN-koodi"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Aseta lapsilukko luomalla PIN-koodi"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Anna uusi PIN-koodi"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Väärä PIN-koodi. Yritä uudelleen."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"PIN-koodit ovat erilaiset, yritä uudelleen"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Anna postinumero"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Live-kanavat-sovellus tarjoaa postinumeron avulla kaikkien alueellasi näkyvien TV-kanavien ohjelmaoppaan."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Anna postinumero"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Virheellinen postinumero"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Asetukset"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Muokkaa kanavaluetteloa"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Valitse kanavat ohjelmaoppaaseen"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanavalähteet"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Uusia kanavia saatavilla"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Lapsilukko"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Ajansiirto"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Tallentaa katsottavaa ohjelmaa, jolloin lähetettävän ohjelman voi keskeyttää tai sitä voi kelata.\nVaroitus: tämä voi lyhentää sisäisen tallennustilan käyttöikää runsaan käytön vuoksi."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Avoimen lähdekoodin käyttöluvat"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Avoimen lähdekoodin käyttöluvat"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Lähetä palautetta"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versio"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Katsele tätä kanavaa painamalla näppäimellä oikealle ja antamalla PIN-koodi"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Katsele tämä ohjelma painamalla näppäimellä oikealle ja antamalla PIN-koodi"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Tälle ohjelmalle ei ole määritetty ikärajaa.\nPaina oikeaa painiketta ja anna PIN-koodi, jos haluat katsoa sen."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Tämän ohjelman luokitus on <xliff:g id="RATING">%1$s</xliff:g>.\nKatso ohjelma painamalla näppäimellä oikealle ja antamalla PIN-koodi."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Katsele tätä kanavaa TV-lähetyksien oletussovelluksessa."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Katsele tätä ohjelmaa TV-lähetyksien oletussovelluksessa."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Tälle ohjelmalle ei ole määritetty ikärajaa.\nKäytä suoran TV-sisällön oletussovellusta, jos haluat katsoa sen."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Tämän ohjelman ikärajoitus on <xliff:g id="RATING">%1$s</xliff:g>.\nKatsele tätä ohjelmaa TV-lähetyksien oletussovelluksessa."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Ohjelma on estetty"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ohjelmalla ei ole ikärajaa."</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Tämän ohjelman luokitus on <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Vain ääni"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Heikko signaali"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307">"Avaa TV-valikko "<b>"painamalla VALITSE"</b>"."</string>
<string name="msg_no_input" msgid="3897674146985427865">"TV-tuloa ei löytynyt."</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"TV-tuloa ei löydy."</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP:tä ei tueta."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Käytettävissä ei ole syötettä, joka voitaisiin näyttää PIP:ssä."</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Viritintä ei tueta. Voit käyttää viritintä käynnistämällä Live-kanavat-sovelluksen."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Viritys epäonnistui."</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Tätä toimintoa käsittelevää sovellusta ei löydy."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d tallenn. ajastettu</item>
<item quantity="one">%1$d tallennus ajastettu</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Peruuta tallennus"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Lopeta tallennus"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Katso"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Toista alusta"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Jatka toistoa"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Jos ohjelmia on ajastettu enemmän kuin samalla kertaa voidaan tallentaa, vain tärkeimmät ohjelmat tallennetaan."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Tallenna"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Kertaluotoiset tallennukset ovat tärkeimpiä."</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Peruuta"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Peruuta"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Unohda"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Lopeta"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Näytä tallennusaikataulu"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Vain tämä jakso"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Nauhoita tämä sen sijaan"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Peruuta tämä nauhoitus"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Katso nyt"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Poista tallenteita…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Tallennettavissa"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Tallennus ajastettu"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Tallennusristiriita"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Tallennetaan"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Nauhoitus epäonnistui"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Luetaan ohjelmatietoja tallennusaikataulujen luomista varten."</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Luetaan ohjelmatietoja"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Luetaan ohjelmatietoja"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Näytä uusimmat tallenteet"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Kohdetta <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ei nauhoitettu loppuun."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Kohteita <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ja <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ei nauhoitettu loppuun."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Kohteita <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ja <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ei nauhoitettu loppuun."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Kohdetta <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ei nauhoitettu loppuun, koska tallennustila ei riitä."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Kohteita <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ja <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ei nauhoitettu loppuun, koska tallennustila ei riitä."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Kohteita <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ja <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ei nauhoitettu loppuun, koska tallennustila ei riitä."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR tarvitsee lisää tilaa"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Voit tallentaa ohjelmia DVR:llä. Laitteellasi ei kuitenkaan ole tarpeeksi tilaa DVR:n käyttöön. Yhdistä vähintään <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> Gt:n kokoinen ulkoinen tallennuslaite ja alusta se laitteen tallennustilaksi ohjeiden mukaisesti."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Voit tallentaa ohjelmia DVR:llä. Laitteellasi ei kuitenkaan ole tarpeeksi tilaa DVR:n käyttöön. Yhdistä vähintään <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> Gt:n kokoinen ulkoinen tallennuslaite ja alusta se laitteen tallennustilaksi ohjeiden mukaisesti."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Tallennustila ei riitä"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Tätä ohjelmaa ei tallenneta, koska tallennustila ei riitä. Kokeile poistaa joitakin nykyisiä tallenteita."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Tallennustila puuttuu"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Osa DVR:n käytössä olleesta tallennustilasta puuttuu. Palauta DVR käyttöön liittämällä aiemmin käyttämäsi ulkoinen asema. Voit myös unohtaa tallennustilan, jos asema ei ole enää käytettävissä."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Unohdetaanko tallennustila?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Kaikki tallennettu sisältö ja aikataulut menetetään."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Lopetetaanko tallennus?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Tallennettu sisältö lisätään kirjastoon."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Ohjelman <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nauhoitus pysäytetään, koska se on ristiriidassa tämän ohjelman kanssa. Nauhoitettu sisältö tallennetaan."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Tallennus ajastettu – ristiriitoja havaittu"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Tallennus käynnissä – ristiriitoja havaittu"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> tallennetaan"</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Sama ohjelma on jo ajastettu nauhoitettavaksi klo <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Jo nauhoitettu"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Tämä ohjelma on jo nauhoitettu. Se on käytettävissä DVR-kirjastossa."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Sarjan nauhoitus ajastettu"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> sarjan <xliff:g id="SERIESNAME_3">%2$s</xliff:g> nauhoitusta lisätty.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> sarjan <xliff:g id="SERIESNAME_1">%2$s</xliff:g> nauhoitus lisätty.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> sarjan <xliff:g id="SERIESNAME_3">%2$s</xliff:g> nauhoitusta lisätty. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> niistä jätetään nauhoittamatta ristiriidan takia.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> sarjan <xliff:g id="SERIESNAME_1">%2$s</xliff:g> nauhoitus lisätty. Se jätetään nauhoittamatta ristiriidan takia.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> sarjan <xliff:g id="SERIESNAME_4">%2$s</xliff:g> nauhoitusta lisätty. Tämän sarjan ja muiden sarjojen <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> jaksoa jätetään nauhoittamatta ristiriidan takia.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> sarjan <xliff:g id="SERIESNAME_1">%2$s</xliff:g> nauhoitus lisätty. Tämän sarjan ja muiden sarjojen <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> jaksoa jätetään nauhoittamatta ristiriidan takia.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> sarjan <xliff:g id="SERIESNAME_3">%2$s</xliff:g> nauhoitusta lisätty. Yksi toisen sarjan jakso jätetään nauhoittamatta ristiriidan takia.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> sarjan <xliff:g id="SERIESNAME_1">%2$s</xliff:g> nauhoitus lisätty. Yksi toisen sarjan jakso jätetään nauhoittamatta ristiriidan takia.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> sarjan <xliff:g id="SERIESNAME_4">%2$s</xliff:g> nauhoitusta lisätty. Muiden sarjojen <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> jaksoa jätetään nauhoittamatta ristiriidan takia.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> sarjan <xliff:g id="SERIESNAME_1">%2$s</xliff:g> nauhoitus lisätty. Muiden sarjojen <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> jaksoa jätetään nauhoittamatta ristiriidan takia.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Tallennettua ohjelmaa ei löytynyt."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Aiheeseen liittyvät tallenteet"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Ohjelmalla ei ole kuvausta.)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d tallennetta</item>
<item quantity="one">%1$d tallenne</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Lopetetaanko sarjan tallennus?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Tallennettuja osia voi edelleen katsella DVR:n kirjastossa."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Lopeta"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Jaksoja ei ole tällä hetkellä saatavilla."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Yhtään jaksoa ei ole saatavilla.\nNe nauhoitetaan, kun ne ovat saatavilla."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minuuttia)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> tänään"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> huomenna"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Arvosana"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Tallennetut ohjelmat"</string>
</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 1fc794e3..80fac2d6 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stéréo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Commandes de lecture"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Chaînes récentes"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Chaînes"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Options télé"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Options IDI"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Les commandes de lecture ne sont pas disponibles pour cette chaîne"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Lire ou mettre en pause"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Avance rapide"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Sous-titres"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Mode d\'affichage"</string>
<string name="options_item_pip" msgid="3951350386626879645">"IDI"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Activé"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Désactivé"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Plus de chaînes"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Paramètres"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Source"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Basculer"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Activé"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Désactivé"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Son"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Principale"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Fenêtre IDI"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Disposition"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"En bas à droite"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"En haut à droite"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"En haut à gauche"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"En bas à gauche"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Côte à côte"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Taille"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Grande"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Petite"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Source de l\'entrée"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"Télévision (antenne/câble)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Aucune information sur le programme"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Pas d\'information"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Chaîne bloquée"</string>
- <string name="default_language" msgid="4122326459624337928">"Langue : indéterminée"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Langue indéterminée"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Sous-titres en %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Sous-titres"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Désactivé"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Personnaliser format"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Grouper par"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ce programme est bloqué"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ce programme n\'est pas classé"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Ce programme est classé « <xliff:g id="RATING">%1$s</xliff:g> »"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"L\'entrée ne prend pas en charge la recherche automatique"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Impossible de lancer la recherche automatique pour « <xliff:g id="TV_INPUT">%s</xliff:g> »."</string>
@@ -92,7 +74,6 @@
<item quantity="other">%1$d chaînes ajoutées</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Aucune chaîne ajoutée"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Syntoniseur"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Contrôle parental"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Activer"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Désactivé"</string>
@@ -108,7 +89,9 @@
<string name="other_countries" msgid="8342216398676184749">"Autres pays"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Aucune"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Aucun"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Aucune"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Non classé"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Bloquer programmes non classés"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Aucun"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Restrictions élevées"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Restrictions moy."</string>
<string name="option_rating_low" msgid="5800146024503377969">"Restrictions faibles"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Entrez votre NIP pour regarder cette chaîne"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Entrez votre NIP pour regarder ce programme"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Ce programme est classé <xliff:g id="RATING">%1$s</xliff:g>. Entrez votre NIP pour regarder ce programme"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Ce programme n\'est pas classé. Entrez votre NIP pour le regarder"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Entrez votre NIP"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Créez un NIP pour régler les contrôles parentaux"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Entrez le nouveau NIP"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Ce NIP est incorrect. Veuillez réessayer."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Le NIP est incorrect. Veuillez réessayer."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Entrez votre code postal."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"L\'application Télé en direct utilisera le code postal pour vous présenter un guide complet des stations de télévision dans votre région."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Entrez votre code postal"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Code postal non valide"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Paramètres"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personnaliser la liste chaînes"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Choisir des chaînes pour le guide des programmes"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Sources des chaînes"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"De nouvelles chaînes sont disponibles"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Contrôles parentaux"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Décalage temporel"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Enregistrez des programmes en direct tout en les regardant afin de pouvoir les mettre en pause ou les rembobiner.\nAvertissement : Cette opération peut réduire la durée de vie de la mémoire de stockage interne en raison de son utilisation intensive."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licences de logiciels libres"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licences de logiciels libres"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Envoyer un commentaire"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Pour regarder cette chaîne, touchez la droite, puis entrez votre NIP."</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Pour regarder ce programme, touchez la droite, puis entrez votre NIP."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Ce programme n\'est pas classé.\nPour le regarder, appuyez sur le bouton Droite, puis entrez votre NIP"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Ce programme est classé « <xliff:g id="RATING">%1$s</xliff:g> ». \nPour le regarder, touchez la droite, puis entrez votre NIP."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Pour regarder cette chaîne, utilisez l\'application de télévision en direct par défaut."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Pour regarder ce programme, utilisez l\'application de télévision en direct par défaut."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Ce programme n\'est pas classé.\nPour le regarder, utilisez l\'application de télévision en direct par défaut."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Ce programme est classé <xliff:g id="RATING">%1$s</xliff:g>.\nPour le regarder, utilisez l\'application de télévision en direct par défaut."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programme bloqué"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ce programme n\'est pas classé"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Ce programme est classé « <xliff:g id="RATING">%1$s</xliff:g> »"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audio uniquement"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Signal faible"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307">"Appuyez sur la touche "<b>"Sélectionner"</b>" pour accéder au menu Télévision."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Aucune entrée trouvée"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Entrée introuvable"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Le mode Image dans image n\'est pas pris en charge"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Aucune entrée ne pouvant être affichée en mode IDI"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Le type d\'entrée ne convient pas. Veuillez lancer l\'application Chaînes en direct pour une entrée de type syntoniseur."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Échec des réglages"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Aucune application pouvant gérer cette action n\'a été trouvée."</string>
@@ -190,7 +181,7 @@
<string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Indisponibilité inattendue de la vidéo"</string>
<string name="msg_back_key_guide" msgid="7404682718828721924">"La touche RETOUR concerne l\'appareil connecté. Appuyez sur le bouton ACCUEIL pour quitter."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Les chaînes en direct ont besoin de l\'autorisation nécessaire pour lire les programmes télé."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Configurez vos sources"</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Configurer vos sources"</string>
<string name="setup_sources_description" msgid="5695518946225445202">"Avec Télé en direct, diffusez les chaînes proposées par des applications comme s\'il s\'agissait de chaînes de télévision traditionnelles. \n\nCommencez par configurer les sources de chaînes déjà installées. Vous pouvez également parcourir la boutique Google Play Store et rechercher d\'autres applications qui proposent des chaînes en direct."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Enregistrements et horaires"</string>
<string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minutes"</string>
@@ -226,6 +217,8 @@
<item quantity="one">%1$d enreg. programmé</item>
<item quantity="other">%1$d enreg. programmés</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Annuler l\'enregistrement"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Arrêter l\'enregistrement"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Regarder"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Lire du début"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Reprendre la lecture"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Quand il y a trop de programmes à enregistrer en même temps, seuls ceux aux priorités les plus élevées sont enregistrés."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Enregistrer"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Les enregistrements ponctuels ont la plus haute priorité"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Annuler"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Annuler"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Supprimer"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Arrêter"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Voir le programme d\'enregistrement"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Uniquement ce programme"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Enregistrez celui-ci à la place"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Annuler cet enregistrement"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Regarder"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Supprimer des enregistrements"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Enregistrable"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Enregistrement programmé"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Conflit d\'enregistrement"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Enregistrement en cours"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Échec de l\'enregistrement"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Lecture des programmes pour créer des horaires d\'enregistrement…"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Lecture des programmes en cours…"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Lecture des programmes en cours…"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Afficher les enregistrements récents"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"L\'enregistrement de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> est incomplet."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Les enregistrements de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> et <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> sont incomplets."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Les enregistrements de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> et <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> sont incomplets."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"L\'enregistrement de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> n\'a pas été terminé à cause d\'un espace de stockage insuffisant."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"L\'enregistrement de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> et <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> n\'a pas été terminé à cause d\'un espace de stockage insuffisant."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"L\'enregistrement de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> et <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> n\'a pas été terminé à cause d\'un espace de stockage insuffisant."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Le magnétoscope numérique a besoin de plus d\'espace"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Vous pourrez enregistrer des programmes avec le magnétoscope numérique. Toutefois, l\'espace de stockage est insuffisant sur votre appareil pour que le magnétoscope numérique puisse fonctionner actuellement. Veuillez brancher un disque externe d\'au moins <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> Go ou suivez les étapes pour le formater en tant qu\'espace de stockage de l\'appareil."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Vous pourrez enregistrer des programmes avec le magnétoscope numérique. Toutefois, l\'espace de stockage est insuffisant sur votre appareil pour que le magnétoscope numérique puisse fonctionner actuellement. Veuillez brancher un disque externe d\'au moins <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> Go ou suivez les étapes pour le formater en tant qu\'espace de stockage de l\'appareil."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Espace de stockage insuffisant"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Ce programme ne sera pas enregistré, car l\'espace de stockage disponible est insuffisant. Essayez de supprimer certains enregistrements."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Espace de stockage manquant"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Une partie de l\'espace de stockage utilisé par le magnétoscope numérique est manquante. Veuillez connecter de nouveau le disque externe que vous avez utilisé auparavant afin de réactiver le magnétoscope numérique. Vous pouvez également supprimer cet espace de stockage s\'il n\'est plus disponible."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Supprimer l\'espace de stockage?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Tous vos contenus enregistrés et vos enregistrements planifiés seront perdus."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Arrêter l\'enregistrement?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Le contenu enregistré sera gardé."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"L\'enregistrement de « <xliff:g id="PROGRAMNAME">%1$s</xliff:g> » sera interrompu, car il crée un conflit avec ce programme. Le contenu enregistré sera conservé."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Enregistrement planifié, mais d\'autres enregistrements sont prévus en même temps."</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"L\'enregistrement a commencé, mais d\'autres enregistrements sont prévus en même temps"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Le programme « <xliff:g id="PROGRAMNAME">%1$s</xliff:g> » sera enregistré."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Vous avez déjà planifié l\'enregistrement de ce programme à <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Déjà enregistré"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Ce programme a déjà été enregistré. Il est accessible dans la bibliothèque du magnétoscope numérique."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"L\'enregistrement de la série est programmé"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrement a été programmé pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrements ont été programmés pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrement a été programmé pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. L\'enregistrement (<xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>) ne sera pas effectué en raison de conflits.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrements ont été programmés pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> d\'entre eux ne seront pas effectués en raison de conflits.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> enregistrement a été programmé pour <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> épisodes de cette série et d\'une autre série ne seront pas enregistrés en raison de conflits.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> enregistrements ont été programmés pour <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> épisodes de cette série et d\'une autre série ne seront pas enregistrés en raison de conflits.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrement a été programmé pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Un épisode d\'une autre série ne sera pas enregistré en raison de conflits.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrements ont été programmés pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Un épisode d\'une autre série ne sera pas enregistré en raison de conflits.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> enregistrement a été programmé pour <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> épisodes d\'une autre série ne seront pas enregistrés en raison de conflits.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> enregistrements ont été programmés pour <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> épisodes d\'une autre série ne seront pas enregistrés en raison de conflits.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Programme enregistré non trouvé."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Enregistrements connexes"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Programme sans description)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d enregistrement</item>
<item quantity="other">%1$d enregistrements</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Arrêter l\'enregistrement de la série?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Les épisodes enregistrés resteront accessibles dans la bibliothèque du magnétoscope numérique."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Arrêter"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Aucun épisode n\'est diffusé en ce moment."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Aucun épisode.\nLes épisodes seront enregistrés lorsqu\'ils seront diffusés."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d minute)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Aujourd\'hui, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Demain, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Note"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programmes enregistrés"</string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index c140aa62..d290b144 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stéréo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Commandes de lecture"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Chaînes récentes"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Chaînes"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Options TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Options PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Commandes de lecture indisponibles pour cette chaîne."</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Lire ou mettre en pause"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Avance rapide"</string>
@@ -35,36 +34,18 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Sous-titres"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Mode d\'affichage"</string>
<string name="options_item_pip" msgid="3951350386626879645">"Mode PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Activé"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Désactivé"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Plus de chaînes"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Paramètres"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Source"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Permuter"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Activé"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Désactivé"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Son"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Principale"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Fenêtre mode PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Mise en page"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"En bas à droite"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"En haut à droite"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"En haut à gauche"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"En bas à gauche"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Côte à côte"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Taille"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Grande"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Petite"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Source d\'entrée"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"Téléviseur (antenne/câble)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Aucune information sur le programme."</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Aucune information"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Chaîne bloquée"</string>
- <string name="default_language" msgid="4122326459624337928">"Langue inconnue"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Langue inconnue"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Sous-titres %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Sous-titres"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Désactivé"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Personnaliser le formatage"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Personnaliser le format"</string>
<string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Configurer les paramètres du système pour les sous-titres"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"Mode d\'affichage"</string>
<string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multi-audio"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Grouper par"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ce programme est bloqué."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ce programme n\'a pas de classification"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Classification de ce programme : <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"L\'entrée n\'est pas compatible avec la recherche automatique."</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Impossible de lancer la recherche automatique pour \"<xliff:g id="TV_INPUT">%s</xliff:g>\"."</string>
@@ -92,7 +74,6 @@
<item quantity="other">%1$d chaînes ont bien été ajoutées.</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Aucune chaîne ajoutée."</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Contrôle parental"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Activé"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Désactivé"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Autres pays"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Aucune"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Aucun"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Aucune classification"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Bloquer si sans classification"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Aucun"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Restrictions élevées"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Restrictions moyennes"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Saisir votre code d\'accès pour regarder cette chaîne"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Saisir votre code d\'accès pour regarder ce programme"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Classification de ce programme : <xliff:g id="RATING">%1$s</xliff:g>. Saisissez votre code pour le regarder."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Ce programme n\'a pas de classification. Saisissez votre code pour le regarder."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Saisir votre code d\'accès"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Créer un code d\'accès pour paramétrer le contrôle parental"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Saisir le nouveau code d\'accès"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Ce code d\'accès est incorrect. Veuillez réessayer."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Le code est incorrect. Veuillez réessayer."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Saisissez votre code postal."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"L\'application TV en direct utilise le code postal pour fournir un guide des programmes complet pour les chaînes de télévision."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Saisissez votre code postal"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Code postal incorrect"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Paramètres"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personnaliser liste chaînes"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Choisir des chaînes pour le guide des programmes"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Sources des chaînes"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nouvelles chaînes disponibles"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Contrôle parental"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Contrôle du direct"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Enregistrez des programmes en direct tout en les regardant afin de pouvoir les mettre en pause ou les rembobiner.\nAvertissement : Cette opération peut réduire la durée de vie de la mémoire de stockage interne en raison de son utilisation intensive."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licences Open Source"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licences Open Source"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Envoyer des commentaires"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Pour regarder cette chaîne, appuyez sur le bouton droit, puis saisissez votre code d\'accès."</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Pour regarder ce programme, appuyez sur la droite, puis saisissez votre code d\'accès."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Ce programme n\'a pas de classification.\nPour le regarder, appuyez sur la touche droite, puis saisissez votre code."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Classification de ce programme : <xliff:g id="RATING">%1$s</xliff:g>.\nPour le regarder, appuyez sur la touche droite, puis saisissez votre code d\'accès."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Pour regarder cette chaîne, utilisez l\'application de télévision en direct par défaut."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Pour regarder ce programme, utilisez l\'application de télévision en direct par défaut."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Ce programme n\'a pas de classification.\nPour le regarder, utilisez l\'application de télévision en direct par défaut."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Classification de ce programme : <xliff:g id="RATING">%1$s</xliff:g>.\nPour regarder ce programme, utilisez l\'application de télévision en direct par défaut."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programme bloqué"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ce programme n\'a pas de classification"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Classification de ce programme : <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audio uniquement"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Signal faible"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Appuyez sur SÉLECTIONNER"</b>" pour accéder au menu de la télévision."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Aucune entrée TV trouvée."</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Entrée TV introuvable."</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Le mode PIP n\'est pas compatible."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Aucune entrée disponible ne peut être affichée en mode PIP."</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Type de tuner non adapté. Veuillez lancer l\'application Chaînes en direct pour l\'entrée TV de type tuner."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Échec des réglages."</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Aucune application trouvée pour gérer cette action."</string>
@@ -190,7 +181,7 @@
<string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Indisponibilité inattendue de la vidéo"</string>
<string name="msg_back_key_guide" msgid="7404682718828721924">"La touche RETOUR concerne l\'appareil connecté. Appuyez sur le bouton ACCUEIL pour quitter."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"L\'application Chaînes en direct a besoin d\'une autorisation pour accéder au programme TV."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Configurez vos sources."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Configurez vos sources"</string>
<string name="setup_sources_description" msgid="5695518946225445202">"Avec TV en direct, regardez en streaming les chaînes proposées par des applications comme s\'il s\'agissait de chaînes de télévision traditionnelles. \n\nCommencez par configurer les sources de chaînes déjà installées. Vous pouvez également parcourir le Google Play Store et rechercher d\'autres applications qui proposent des chaînes en direct."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Enregistrements et plannings"</string>
<string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minutes"</string>
@@ -226,6 +217,8 @@
<item quantity="one">%1$d enregistr. planifié</item>
<item quantity="other">%1$d enregistr. planifiés</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Annuler l\'enregistrement"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Arrêter enregistrement"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Regarder"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Lire depuis le début"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Reprendre la lecture"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Lorsqu\'il y a trop de programmes à enregistrer simultanément, seuls les programmes aux priorités les plus élevées sont enregistrés."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Enregistrer"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Les enregistrements ponctuels ont la plus haute priorité."</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Annuler"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Annuler"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Supprimer"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Arrêter"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Voir planning d\'enregistrement"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Ce programme uniquement"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Enregistrer ce programme"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Annuler cet enregistrement"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Regarder"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Supprimer des enregistrements"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Enregistrable"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Enregistrement programmé"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Conflit d\'enregistrement"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Enregistrement…"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Échec de l\'enregistrement"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Lecture des programmes pour créer des plannings d\'enregistrement…"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Lecture des programmes…"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Lecture des programmes…"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Afficher les enregistrements récents"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"L\'enregistrement de \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" est incomplet"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Les enregistrements de \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\" et de \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" sont incomplets"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Les enregistrements de \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\", de \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" et de \"<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>\" sont incomplets"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"L\'enregistrement de \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" n\'a pas été effectué en raison d\'un espace de stockage insuffisant."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Les enregistrements de \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\" et de \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" n\'ont pas été effectués en raison d\'un espace de stockage insuffisant."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Les enregistrements de \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\", de \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" et de \"<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>\" n\'ont pas été effectués en raison d\'un espace de stockage insuffisant."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Le magnétoscope numérique a besoin de plus d\'espace"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Vous pourrez enregistrer des programmes avec le magnétoscope numérique. Toutefois, l\'espace de stockage est insuffisant sur votre appareil pour que le magnétoscope numérique puisse fonctionner actuellement. Veuillez brancher un disque externe d\'au moins <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> Go ou suivre les étapes pour le formater en tant qu\'espace de stockage de l\'appareil."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Vous pourrez enregistrer des programmes avec le magnétoscope numérique. Toutefois, l\'espace de stockage est insuffisant sur votre appareil pour que le magnétoscope numérique puisse fonctionner actuellement. Veuillez brancher un disque externe d\'au moins <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> Go ou suivre les étapes pour le formater en tant qu\'espace de stockage de l\'appareil."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Espace de stockage insuffisant"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Ce programme ne sera pas enregistré, car l\'espace de stockage disponible est insuffisant. Essayez de supprimer certains enregistrements."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Espace de stockage manquant"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Une partie de l\'espace de stockage utilisé par le magnétoscope numérique est manquante. Veuillez connecter de nouveau le disque externe que vous avez utilisé auparavant afin de réactiver le magnétoscope numérique. Vous pouvez également supprimer cet espace de stockage s\'il n\'est plus disponible."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Supprimer l\'espace de stockage ?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Tous vos contenus enregistrés et vos enregistrements planifiés seront perdus."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Arrêter l\'enregistrement ?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Le contenu enregistré sera sauvegardé."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"L\'enregistrement de \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" va être interrompu, car il crée un conflit avec ce programme. Le contenu enregistré sera conservé."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Enregistrement planifié, mais d\'autres enregistrements sont prévus en même temps."</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"L\'enregistrement a commencé, mais présente des conflits"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Le programme \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" sera enregistré."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Vous avez déjà planifié l\'enregistrement de ce programme à <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Déjà enregistré"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Ce programme a déjà été enregistré. Il est disponible dans la bibliothèque DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Enregistrement de la série programmé"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrement a été programmé pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrements ont été programmés pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrement a été programmé pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. L\'enregistrement (<xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>) ne sera pas effectué en raison de conflits.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrements ont été programmés pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> enregistrements ne seront pas effectués en raison de conflits.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> enregistrement a été programmé pour <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> épisodes de cette série et d\'une autre série ne seront pas enregistrés en raison de conflits.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> enregistrements ont été programmés pour <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> épisodes de cette série et d\'une autre série ne seront pas enregistrés en raison de conflits.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrement a été programmé pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 épisode d\'une autre série ne sera pas enregistré en raison de conflits.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> enregistrements ont été programmés pour <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 épisode d\'une autre série ne sera pas enregistré en raison de conflits.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> enregistrement a été programmé pour <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> épisodes d\'une autre série ne seront pas enregistrés en raison de conflits.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> enregistrements ont été programmés pour <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> épisodes d\'une autre série ne seront pas enregistrés en raison de conflits.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Programme enregistré introuvable."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Enregistrements associés"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Programme sans description)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d enregistrement</item>
<item quantity="other">%1$d enregistrements</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Arrêter l\'enregistrement de la série ?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Les épisodes enregistrés resteront disponibles dans la bibliothèque DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Arrêter"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Aucun épisode n\'est diffusé actuellement."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Aucun épisode disponible.\nLes épisodes seront enregistrés lorsqu\'ils seront disponibles."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d minute)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> aujourd\'hui"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> demain"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Score"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programmes enregistrés"</string>
</resources>
diff --git a/res/values-gl-v23/strings.xml b/res/values-gl-rES-v23/strings.xml
index 7cb59c66..7cb59c66 100644
--- a/res/values-gl-v23/strings.xml
+++ b/res/values-gl-rES-v23/strings.xml
diff --git a/res/values-gl/arrays.xml b/res/values-gl-rES/arrays.xml
index 0bbc3853..0bbc3853 100644
--- a/res/values-gl/arrays.xml
+++ b/res/values-gl-rES/arrays.xml
diff --git a/res/values-gl/rating_system_strings.xml b/res/values-gl-rES/rating_system_strings.xml
index 20456b34..20456b34 100644
--- a/res/values-gl/rating_system_strings.xml
+++ b/res/values-gl-rES/rating_system_strings.xml
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
new file mode 100644
index 00000000..1eea83a6
--- /dev/null
+++ b/res/values-gl-rES/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"estéreo"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Controis de reprodución"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Canles"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"Opcións de TV"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Os controis de reprodución non están dispoñibles nesta canle"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Reprodución ou pausa"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Avance rápido"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Rebobinado"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Seguinte"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Anterior"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Guía de programas"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Novas canles dispoñib."</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Abrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Subtítulos"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Modo visualiz."</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Multiaudio"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Obter máis canles"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Configuración"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/cable)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Non hai información do programa"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Non hai información"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Canle bloqueada"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Idioma descoñecido"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Subtítulos en %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Subtítulos"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Desactivado"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Personalizar formato"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Definir pref. do sistema para subtítulos"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Modo visualiz."</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multiaudio"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"estéreo"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"Surround 5.1"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"Surround 7.1"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d canles"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Personalizar lista"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Seleccionar grupo"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Anular a selección"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Agrupar por"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Fonte de canles"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"Alta definición/definición estándar"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Alta definición"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Definición estándar"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Agrupar por"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Este programa está bloqueado"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Este programa está sen clasificar"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>."</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"A entrada non admite a busca automática"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Non é posible iniciar a busca automática para \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Non se poden iniciar as preferencias de todo o sistema para os subtítulos."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">Engadíronse %1$d canles</item>
+ <item quantity="one">Engadiuse %1$d canle</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Non se engadiron canles"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Controis parentais"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Activados"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Desactivados"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Canles bloqueadas"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Bloquear todo"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Desbloquear todo"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Canles ocultas"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Restricións prog."</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"Cambiar PIN"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Sistemas clasific."</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Valoracións"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Ver sistemas clasif."</string>
+ <string name="other_countries" msgid="8342216398676184749">"Outros países"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Ningunha"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ningunha"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Sen clasificar"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Bloquear progr. sen clasificar"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Ningún"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Restricións altas"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Restricións medias"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Restricións baixas"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Personalizada"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Contido adecuado para nenos"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Contido adecuado para nenos máis vellos"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Contido adecuado para adolescentes"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Restricións manuais"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s e subclasific."</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Subclasificacións"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Introduce o teu PIN para ver esta canle"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Introduce o teu PIN para ver este programa"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>. Para velo, introduce o teu PIN"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Este programa está sen clasificar. Para velo, introduce o PIN"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"Introduce o teu PIN"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Para definir controis parentais, crea un PIN"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Introduce o novo PIN"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"Confirma o teu PIN"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Introduce o teu PIN actual"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Introduciches 5 veces un PIN incorrecto.\nTéntao de novo en <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundos.</item>
+ <item quantity="one">Introduciches 5 veces un PIN incorrecto.\nTéntao de novo en <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> segundo.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"О PIN era incorrecto. Téntao de novo."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Téntao de novo. O PIN non coincide."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Introduce o teu código postal."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"A aplicación TV en directo usará o teu código postal para ofrecer unha guía de programas completa para as canles da televisión."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Introduce o teu código postal"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"O código postal non é válido"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Configuración"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personalizar lista de canles"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Selecciona canles para a túa guía de programas"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Fontes de canles"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Novas canles dispoñibles"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Controis parentais"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Modo en diferido"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Grava o contido mentres o ves para poder pausar ou rebobinar os programas en directo.\nAdvertencia: Con esta acción pode reducirse a duración do almacenamento interno debido ao seu uso intensivo."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Licenzas de código aberto"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Enviar comentarios"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versión"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Para ver esta canle, preme na tecla cara á dereita e introduce o PIN"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Para ver esta programa, preme na tecla cara á dereita e introduce o PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Este programa está sen clasificar.\nPara velo, preme na tecla cara á dereita e introduce o PIN"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>.\nPara ver esta programa, preme na tecla cara á dereita e introduce o PIN."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Para ver esta canle, utiliza a aplicación predeterminada TV en directo."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Para ver este programa, utiliza a aplicación predeterminada TV en directo."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Este programa está sen clasificar.\nPara velo, utiliza a aplicación predeterminada de televisión en directo."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>.\nPara velo, utiliza a aplicación predeterminada TV en directo."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"O programa está bloqueado"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Este programa está sen clasificar"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>."</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Só audio"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Sinal feble"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Non hai conexión a Internet"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">Esta canle non se pode reproducir ata as <xliff:g id="END_TIME_1">%1$s</xliff:g> porque se están gravando outras canles. \n\nPreme na tecla cara á dereita para axustar o programa de gravación.</item>
+ <item quantity="one">Esta canle non se pode reproducir ata as <xliff:g id="END_TIME_0">%1$s</xliff:g> porque se está gravando outra canle. \n\nPreme na tecla cara á dereita para axustar o programa de gravación.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Sen título"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Canle bloqueada"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Novas"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Fontes"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d canles</item>
+ <item quantity="one">%1$d canle</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Non hai canles dispoñibles"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Novo"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Sen configurar"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Obter máis fontes"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Examina aplicacións que ofrecen canles en directo"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Novas fontes de canles dispoñibles"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Hai novas fontes de canles que teñen canles para ofrecer.\nConfigúraas agora ou faino máis tarde nos axustes das fontes de canles."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Configurar agora"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"De acordo"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>"Preme SELECCIONAR"</b>" para acceder ao menú da televisión."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"Non se atopou ningunha entrada de televisión"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"Non se pode atopar a entrada de televisión"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tipo de sintonizador non adecuado. Inicia a aplicación Canles en directo para a entrada de TV do tipo de sintonizador."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Erro de sintonización"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Non se encontrou ningunha aplicación para procesar esta acción."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Todas as canles de orixe están ocultas.\nSelecciona polo menos unha canle para ver."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"O vídeo deixou de estar dispoñible de forma inesperada"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"A tecla Atrás aplícase ao dispositivo conectado. Preme o botón de inicio para saír."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"As canles en directo necesitan permiso para ler a programación da televisión."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Configura as túas fontes"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"As canles en directo combinan a experiencia das canles de televisión tradicionais coas canles de emisión que proporcionan as aplicacións. \n\nComeza configurando as fontes de canles que xa están instaladas ou ben examina Google Play Store para obter máis aplicacións que ofrezan canles en directo."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Gravacións e programacións"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minutos"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minutos"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 hora"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 horas"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Recentes"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Programados"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Series"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Outros"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Non se pode gravar a canle."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Non se pode gravar o programa."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"Programouse a gravación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g>"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Gravarase <xliff:g id="PROGRAMNAME">%1$s</xliff:g> desde agora ata as <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Programación completa"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">%1$d días</item>
+ <item quantity="one">%1$d día</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d minutos</item>
+ <item quantity="one">%1$d minuto</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d gravacións novas</item>
+ <item quantity="one">%1$d gravación nova</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d gravacións</item>
+ <item quantity="one">%1$d gravación</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d gravacións programadas</item>
+ <item quantity="one">%1$d gravación programada</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Cancelar gravación"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Deter gravación"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Visualizar"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Reproducir desde o inicio"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Retomar reprodución"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Eliminar"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Eliminar gravacións"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Retomar"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Tempada <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Ver programac."</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Máis información"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Eliminar gravacións"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Selecciona os vídeos que queres eliminar e ten en conta que non se poden recuperar unha vez eliminados."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Non hai gravacións para eliminar."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Seleccionar episodios vistos"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Seleccionar todos os episodios"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Desmarcar todos os episodios"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> de <xliff:g id="DURATION">%2$d</xliff:g> minutos vistos"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> de <xliff:g id="DURATION">%2$d</xliff:g> segundos vistos"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Gravacións nunca vistas"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">Elimináronse %1$d de %2$d episodios</item>
+ <item quantity="one">Eliminouse %1$d de %2$d episodio</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Prioridade"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Máis alta"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Máis baixa"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Non. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Canles"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Calquera"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Seleccionar prioridade"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Cando hai demasiados programas para gravar á vez, só se gravarán os programas con máis prioridade."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Gardar"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"As gravacións realizadas unha soa vez teñen máis prioridade"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Deter"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Ver programación de gravación"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Só este programa"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"agora - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Toda a serie…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Programar de todas formas"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Gravar isto no seu lugar"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Cancelar esta gravación"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Visualizar agora"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Eliminar gravacións..."</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Gravable"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Gravación programada"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Conflito de gravación"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Gravando"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Erro na gravación"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Lendo programas"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Ver gravacións recentes"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"A gravación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> non está completa."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"As gravacións de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> e <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> non están completas."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"As gravacións de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> e <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> non están completas."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"A gravación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> non se completou por falta de almacenamento suficiente."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"As gravacións de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> e <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> non se completaron por falta de almacenamento suficiente."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"As gravacións de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> e <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> non se completaron por falta de almacenamento suficiente."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"O DVR precisa máis almacenamento"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Poderás gravar programas con DVR. Non obstante, o teu dispositivo non ten almacenamento suficiente para que funcione DVR. Conecta unha unidade externa de <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB ou máis e sigue os pasos para formatala como almacenamento do dispositivo."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Non hai almacenamento suficiente"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Este programa non se gravará porque non hai almacenamento suficiente. Proba a eliminar algunhas gravacións."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Falta o almacenamento"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Queres deter a gravación?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Gardarase o contido gravado."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Deterase a gravación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> porque supón un conflito con este programa. Gardarase o contido gravado."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Programouse a gravación, pero presenta conflitos"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Iniciouse a gravación pero presenta conflitos"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Gravarase <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"Estase gravando <xliff:g id="CHANNELNAME">%1$s</xliff:g>."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Non se gravarán algunhas partes de <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g>."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Non se gravarán algunhas partes de <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> e <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Non se gravarán algunhas partes de <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> e unha programación máis."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other">Non se gravarán algunhas partes de <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> e %3$d programacións máis.</item>
+ <item quantity="one">Non se gravarán algunhas partes de <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> e %3$d programación máis.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Que che gustaría gravar?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Canto tempo queres gravar?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Xa se programou"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Xa se programou a gravación do mesmo programa para a seguinte hora: <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Xa está gravado"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Este programa xa está gravado e está dispoñible na mediateca de DVR."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Programouse a gravación da serie"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">Programáronse <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravacións para <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one">Programouse <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> gravación para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">Programáronse <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravacións para <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Non se gravarán <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> delas por causa dun conflito.</item>
+ <item quantity="one">Programouse <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> gravación para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Non se gravará por causa dun conflito.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">Programáronse <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> gravacións para <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Non se gravarán <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodios destas series nin doutras por causa dun conflito.</item>
+ <item quantity="one">Programouse <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> gravación para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Non se gravarán <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodios destas series nin doutras por causa dun conflito.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">Programáronse <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravacións para <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Non se gravará 1 episodio doutras series por causa dun conflito.</item>
+ <item quantity="one">Programouse <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> gravación para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Non se gravará 1 episodio doutras series por causa dun conflito.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">Programáronse <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> gravacións para <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Non se gravarán <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodios doutras series por causa dun conflito.</item>
+ <item quantity="one">Programouse <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> gravación para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Non se gravarán <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episodios doutras series por causa dun conflito.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Non se atopou o programa gravado."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Gravacións relacionadas"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d gravacións</item>
+ <item quantity="one">%1$d gravación</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"Eliminouse <xliff:g id="PROGRAMNAME">%1$s</xliff:g> da programación de gravación"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Gravarase parcialmente debido aos conflitos co sintonizador."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Non se gravará debido aos conflitos co sintonizador."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Aínda non hai gravacións programadas.\nPodes programalas desde a guía de programas."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d conflitos de gravación</item>
+ <item quantity="one">%1$d conflito de gravación</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Configuración da serie"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Iniciar gravación serie"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Deter gravación da serie"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Queres deter a gravación da serie?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Os episodios gravados seguirán dispoñibles na mediateca de DVR."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Deter"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Agora non hai episodios en directo."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Non hai episodios dispoñibles.\nGravaranse unha vez que estean dispoñibles."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d minutos)</item>
+ <item quantity="one">(%1$d minuto) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Hoxe"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Mañá"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Onte"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> hoxe"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> mañá"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Puntuación"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programas gravados"</string>
+</resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
deleted file mode 100644
index 7ce0ac2d..00000000
--- a/res/values-gl/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"estéreo"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Controis de reprodución"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Canles recentes"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"Opcións de TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opcións de PIP"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Os controis de reprodución non están dispoñibles nesta canle"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Reprodución ou pausa"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Avance rápido"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Rebobinado"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Seguinte"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Anterior"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Guía de programas"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Novas canles dispoñib."</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Abrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Subtítulos"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Modo visualiz."</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Activado"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Desactivado"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Multiaudio"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Obter máis canles"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Configuración"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Fonte"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Cambiar"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Activado"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Desactivado"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Son"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Principal"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Ventá de PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Deseño"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Abaixo dereita"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Arriba dereita"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Arriba esquerda"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Abaixo esquerda"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"En paralelo"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Tamaño"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Grande"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Pequeno"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Fonte de entrada"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/cable)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Non hai información do programa"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Non hai información"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Canle bloqueada"</string>
- <string name="default_language" msgid="4122326459624337928">"Idioma descoñecido"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Subtítulos"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Desactivado"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Personalizar formato"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Definir pref. do sistema para subtítulos"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Modo visualiz."</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multiaudio"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"estéreo"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"Surround 5.1"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"Surround 7.1"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d canles"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Personalizar lista"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Seleccionar grupo"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Anular a selección"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Agrupar por"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Fonte de canles"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"Alta definición/definición estándar"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Alta definición"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Definición estándar"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Agrupar por"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Este programa está bloqueado"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>."</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"A entrada non admite a busca automática"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Non é posible iniciar a busca automática para \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Non se poden iniciar as preferencias de todo o sistema para os subtítulos."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">Engadíronse %1$d canles</item>
- <item quantity="one">Engadiuse %1$d canle</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Non se engadiron canles"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Sintonizador"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Controis parentais"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Activados"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Desactivados"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Canles bloqueadas"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Bloquear todo"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Desbloquear todo"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Canles ocultas"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Restricións prog."</string>
- <string name="option_change_pin" msgid="2881594075631152566">"Cambiar PIN"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Sistemas clasific."</string>
- <string name="option_ratings" msgid="4009116954188688616">"Valoracións"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Ver sistemas clasif."</string>
- <string name="other_countries" msgid="8342216398676184749">"Outros países"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Ningunha"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ningunha"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Ningún"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Restricións altas"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Restricións medias"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Restricións baixas"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Personalizada"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Contido adecuado para nenos"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Contido adecuado para nenos máis vellos"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Contido adecuado para adolescentes"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Restricións manuais"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s e subclasific."</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Subclasificacións"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Introduce o teu PIN para ver esta canle"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Introduce o teu PIN para ver este programa"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>. Para velo, introduce o teu PIN"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"Introduce o teu PIN"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Para definir controis parentais, crea un PIN"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Introduce o novo PIN"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"Confirma o teu PIN"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Introduce o teu PIN actual"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">Introduciches 5 veces un PIN incorrecto.\nTéntao de novo en <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundos.</item>
- <item quantity="one">Introduciches 5 veces un PIN incorrecto.\nTéntao de novo en <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> segundo.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"О PIN era incorrecto. Téntao de novo."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Téntao de novo. O PIN non coincide."</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Configuración"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personalizar lista de canles"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Selecciona canles para a túa guía de programas"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Fontes de canles"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Novas canles dispoñibles"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Controis parentais"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Licenzas de código aberto"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licenzas de código aberto"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Versión"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Para ver esta canle, preme na tecla cara á dereita e introduce o PIN"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Para ver esta programa, preme na tecla cara á dereita e introduce o PIN"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>.\nPara ver esta programa, preme na tecla cara á dereita e introduce o PIN."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Para ver esta canle, utiliza a aplicación predeterminada TV en directo."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Para ver este programa, utiliza a aplicación predeterminada TV en directo."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>.\nPara velo, utiliza a aplicación predeterminada TV en directo."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"O programa está bloqueado"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Este programa está clasificado como <xliff:g id="RATING">%1$s</xliff:g>."</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Só audio"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Sinal feble"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Non hai conexión a Internet"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Esta canle non se pode reproducir ata as <xliff:g id="END_TIME_1">%1$s</xliff:g> porque se están gravando outras canles. \n\nPreme na tecla cara á dereita para axustar o programa de gravación.</item>
- <item quantity="one">Esta canle non se pode reproducir ata as <xliff:g id="END_TIME_0">%1$s</xliff:g> porque se está gravando outra canle. \n\nPreme na tecla cara á dereita para axustar o programa de gravación.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Sen título"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Canle bloqueada"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Novas"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Fontes"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d canles</item>
- <item quantity="one">%1$d canle</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Non hai canles dispoñibles"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Novo"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Sen configurar"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Obter máis fontes"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Examina aplicacións que ofrecen canles en directo"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Novas fontes de canles dispoñibles"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Hai novas fontes de canles que teñen canles para ofrecer.\nConfigúraas agora ou faino máis tarde nos axustes das fontes de canles."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Configurar agora"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"De acordo"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307"><b>"Preme SELECCIONAR"</b>" para acceder ao menú da televisión."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"Non se atopou ningunha entrada de televisión"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"Non se pode atopar a entrada de televisión"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP non é compatible"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Non hai ningunha entrada que se poida mostrar con PIP"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tipo de sintonizador non adecuado. Inicia a aplicación Canles en directo para a entrada de TV do tipo de sintonizador."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Erro de sintonización"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Non se encontrou ningunha aplicación para procesar esta acción."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Todas as canles de orixe están ocultas.\nSelecciona polo menos unha canle para ver."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"O vídeo deixou de estar dispoñible de forma inesperada"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"A tecla Atrás aplícase ao dispositivo conectado. Preme o botón de inicio para saír."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"As canles en directo necesitan permiso para ler a programación da televisión."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Configura as túas fontes"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"As canles en directo combinan a experiencia das canles de televisión tradicionais coas canles de emisión que proporcionan as aplicacións. \n\nComeza configurando as fontes de canles que xa están instaladas ou ben examina Google Play Store para obter máis aplicacións que ofrezan canles en directo."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Gravacións e programacións"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minutos"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minutos"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 hora"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 horas"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Recentes"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Programados"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Series"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Outros"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Non se pode gravar a canle."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Non se pode gravar o programa."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"Programouse a gravación de <xliff:g id="PROGRAMNAME">%1$s</xliff:g>"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Gravarase <xliff:g id="PROGRAMNAME">%1$s</xliff:g> desde agora ata as <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Programación completa"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">%1$d días</item>
- <item quantity="one">%1$d día</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d minutos</item>
- <item quantity="one">%1$d minuto</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d gravacións novas</item>
- <item quantity="one">%1$d gravación nova</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d gravacións</item>
- <item quantity="one">%1$d gravación</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d gravacións programadas</item>
- <item quantity="one">%1$d gravación programada</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Visualizar"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Reproducir desde o inicio"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Retomar reprodución"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Eliminar"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Eliminar gravacións"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Retomar"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Tempada <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Ver programac."</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Máis información"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Eliminar gravacións"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Selecciona os vídeos que queres eliminar e ten en conta que non se poden recuperar unha vez eliminados."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Non hai gravacións para eliminar."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Seleccionar episodios vistos"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Seleccionar todos os episodios"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Desmarcar todos os episodios"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> de <xliff:g id="DURATION">%2$d</xliff:g> minutos vistos"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> de <xliff:g id="DURATION">%2$d</xliff:g> segundos vistos"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Gravacións nunca vistas"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">Elimináronse %1$d de %2$d episodios</item>
- <item quantity="one">Eliminouse %1$d de %2$d episodio</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Prioridade"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Máis alta"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Máis baixa"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Non. <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Canles"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Calquera"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Seleccionar prioridade"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Cando hai demasiados programas para gravar á vez, só se gravarán os programas con máis prioridade."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Gardar"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"As gravacións realizadas unha soa vez teñen máis prioridade"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Cancelar"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Cancelar"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Borrar"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Deter"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Ver programación de gravación"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Só este programa"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"agora - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Toda a serie…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Programar de todas formas"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Gravar isto no seu lugar"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Cancelar esta gravación"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Visualizar agora"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Gravable"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Gravación programada"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Conflito de gravación"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Gravando"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Erro na gravación"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Lendo programas para crear programacións de gravacións"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Lendo programas"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"O DVR precisa máis almacenamento"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Poderás gravar programas con DVR. Non obstante, o teu dispositivo non ten almacenamento suficiente para que funcione DVR. Conecta unha unidade externa de <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB ou máis e sigue os pasos para formatala como almacenamento do dispositivo."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Falta o almacenamento"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Falta parte do almacenamento que utiliza DVR. Conecta a unidade externa que utilizaches antes para volver activar DVR. Tamén podes decidir borrar o almacenamento se xa non está dispoñible."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Queres borrar o almacenamento?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Perderase toda a programación e o contido gravados."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Queres deter a gravación?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Gardarase o contido gravado."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Programouse a gravación, pero presenta conflitos"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Iniciouse a gravación pero presenta conflitos"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Gravarase <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"Estase gravando <xliff:g id="CHANNELNAME">%1$s</xliff:g>."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Non se gravarán algunhas partes de <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g>."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Non se gravarán algunhas partes de <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> e <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Non se gravarán algunhas partes de <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> e unha programación máis."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other">Non se gravarán algunhas partes de <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> e %3$d programacións máis.</item>
- <item quantity="one">Non se gravarán algunhas partes de <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> e %3$d programación máis.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Que che gustaría gravar?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Canto tempo queres gravar?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Xa se programou"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Xa se programou a gravación do mesmo programa para a seguinte hora: <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Xa está gravado"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Este programa xa está gravado e está dispoñible na mediateca de DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Non se atopou o programa gravado."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Gravacións relacionadas"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Non hai descrición do programa)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d gravacións</item>
- <item quantity="one">%1$d gravación</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"Eliminouse <xliff:g id="PROGRAMNAME">%1$s</xliff:g> da programación de gravación"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Gravarase parcialmente debido aos conflitos co sintonizador."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Non se gravará debido aos conflitos co sintonizador."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Aínda non hai gravacións programadas.\nPodes programalas desde a guía de programas."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d conflitos de gravación</item>
- <item quantity="one">%1$d conflito de gravación</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Configuración da serie"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Iniciar gravación serie"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Deter gravación da serie"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Queres deter a gravación da serie?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Os episodios gravados seguirán dispoñibles na mediateca de DVR."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Deter"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Non hai episodios dispoñibles.\nGravaranse unha vez que estean dispoñibles."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d minutos)</item>
- <item quantity="one">(%1$d minuto) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Hoxe"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Mañá"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Onte"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> hoxe"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> mañá"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Puntuación"</string>
-</resources>
diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu-rIN/strings.xml
new file mode 100644
index 00000000..d635088f
--- /dev/null
+++ b/res/values-gu-rIN/strings.xml
@@ -0,0 +1,356 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"મૉનો"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"સ્ટીરિઓ"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"ચલાવવાનાં નિયંત્રણો"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"ચૅનલો"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"TV વિકલ્પો"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"આ ચૅનલો માટે ચલાવવાનાં નિયંત્રણો ઉપલબ્ધ નથી"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ચલાવો અથવા થોભાવો"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ઝડપી ફોરવર્ડ કરો"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"રીવાઇન્ડ કરો"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"આગલું"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"પહેલાંનું"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"પ્રોગ્રામ માર્ગદર્શિકા"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"નવી ચૅનલો ઉપલબ્ધ છે"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ખોલો"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"ઉપશીર્ષક"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"પ્રદર્શન મોડ"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"બહુ-ઑડિઓ"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"વધુ ચૅનલો મેળવો"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"સેટિંગ્સ"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (એન્ટેના/કેબલ)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"કોઈ પ્રોગ્રામ માહિતી નથી"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"કોઈ માહિતી નથી"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"અવરોધિત કરેલ ચૅનલ"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"અજાણ ભાષા"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"ઉપશીર્ષક %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"ઉપશીર્ષક"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"બંધ"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"કસ્ટમાઇઝ ફૉર્મેટિંગ"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"ઉપશીર્ષક માટે સિસ્ટમ-વ્યાપી પસંદગીઓ સેટ કરો"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"પ્રદર્શન મોડ"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"બહુ-ઑડિઓ"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"મૉનો"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"સ્ટીરિઓ"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 સરાઉન્ડ"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 સરાઉન્ડ"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ચૅનલ"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ચૅનલની સૂચિ કસ્ટમાઇઝ કરો"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"જૂથ પસંદ કરો"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"જૂથની પસંદગી દૂર કરો"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"આ દ્વારા જૂથબદ્ધ કરો"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ચૅનલ સ્રોત"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"આ દ્વારા જૂથબદ્ધ કરો"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"આ પ્રોગ્રામ અવરોધિત કરેલ છે"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"આ પ્રોગ્રામ અનરેટેડ છે"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"આ પ્રોગ્રામને <xliff:g id="RATING">%1$s</xliff:g> રેટ કરેલ છે"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"ઇનપુટ સ્વતઃ સ્કૅનને સમર્થન આપતું નથી"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' માટે સ્વતઃ સ્કૅન શરૂ કરવામાં અસમર્થ"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"ઉપશીર્ષક માટે સિસ્ટમ-વ્યાપી પસંદગીઓ શરૂ કરવામાં અસમર્થ."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d ચૅનલ ઉમેરી</item>
+ <item quantity="other">%1$d ચૅનલ ઉમેરી</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"કોઈ ચૅનલો ઉમેરી નથી"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"માતા પિતા યોગ્ય નિયંત્રણો"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ચાલુ"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"બંધ"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"અવરોધિત કરેલ ચૅનલો"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"તમામને અવરોધિત કરો"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"તમામને અનાવરોધિત કરો"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"છુપાયેલ ચૅનલો"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"પ્રોગ્રામ પ્રતિબંધો"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN બદલો"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"રેટિંગ સિસ્ટમ"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"રેટિંગ"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"તમામ રેટિંંગ સિસ્ટમ જુઓ"</string>
+ <string name="other_countries" msgid="8342216398676184749">"અન્ય દેશો"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"કોઈ નહીં"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"કોઈ નહીં"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"અનરેટેડ"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"અનરેટેડ પ્રોગ્રામ બ્લૉક કરો"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"કોઈ નહીં"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"વધુ પ્રતિબંધો"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"મધ્યમ પ્રતિબંધો"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"ઓછા પ્રતિબંધો"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"કસ્ટમ"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"સામગ્રી બાળકો માટે યોગ્ય છે"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"સામગ્રી મોટા બાળકો માટે યોગ્ય છે"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"સામગ્રી કિશોરો માટે યોગ્ય છે"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"મેન્યુઅલ પ્રતિબંધો"</string>
+ <string name="option_attribution" msgid="2967657807178951562">"વર્ણનોને રેટ કરવા માટે સ્રોતો"</string>
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s અને પેટા-રેટિંગ"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"પેટા-રેટિંગ"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"આ ચૅનલ જોવા માટે તમારો PIN દાખલ કરો"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"આ પ્રોગ્રામ જોવા માટે તમારો PIN દાખલ કરો"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"આ પ્રોગ્રામ <xliff:g id="RATING">%1$s</xliff:g> રેટ કરેલ છે. આ પ્રોગ્રામ જોવા માટે તમારો PIN દાખલ કરો"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"આ પ્રોગ્રામ અનરેટેડ છે. આ પ્રોગ્રામ જોવા માટે તમારો પિન દાખલ કરો"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"તમારો PIN દાખલ કરો"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"માતા પિતા યોગ્ય નિયંત્રણો સેટ કરવા માટે, એક PIN બનાવો"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"નવો PIN દાખલ કરો"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"તમારા PIN ની પુષ્ટિ કરો"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"તમારો વર્તમાન PIN દાખલ કરો"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">તમે 5 વખત ખોટો PIN દાખલ કર્યો.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> સેકન્ડમાંં ફરી પ્રયાસ કરો.</item>
+ <item quantity="other">તમે 5 વખત ખોટો PIN દાખલ કર્યો.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> સેકન્ડમાંં ફરી પ્રયાસ કરો.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"તે PIN ખોટો હતો. ફરી પ્રયાસ કરો."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"ફરીથી પ્રયાસ કરો, PIN મેળ ખાતો નથી"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"તમારો પિન કોડ દાખલ કરો."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"TV ચૅનલો માટે એક સંપૂર્ણ પ્રોગ્રામ માર્ગદર્શિકા પ્રદાન કરવા માટે લાઇવ ચૅનલ ઍપ્લિકેશન પિન કોડનો ઉપયોગ કરશે."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"તમારો પિન કોડ દાખલ કરો"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"અમાન્ય પિન કોડ"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"સેટિંગ્સ"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ચૅનલની સૂચિ કસ્ટમાઇઝ કરો"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"તમારી પ્રોગ્રામ માર્ગદર્શિકા માટે ચૅનલો પસંદ કરો"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ચૅનલ સ્રોત"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"નવી ચૅનલો ઉપલબ્ધ છે"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"માતા પિતા યોગ્ય નિયંત્રણો"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"સમય અંતરાલ"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"જોતી વખતે રેકોર્ડ કરો, જેથી તમે લાઇવ પ્રોગ્રામને થોભાવી અથવા રીવાઇન્ડ કરી શકો છો.\nચેતવણી: સ્ટૉરેજનાં સઘન ઉપયોગને કારણે આ આંતરિક સ્ટૉરેજની આવરદાને ઘટાડી શકે છે."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"ખુલ્લા સ્ત્રોત લાઇસન્સ"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"પ્રતિસાદ મોકલો"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"સંસ્કરણ"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"આ ચૅનલ જોવા માટે, જમણે દબાવો અને તમારો PIN દાખલ કરો."</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"આ પ્રોગ્રામ જોવા માટે, જમણે દબાવો અને તમારો PIN દાખલ કરો."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"આ પ્રોગ્રામ અનરેટેડ છે.\nઆ પ્રોગ્રામ જોવા માટે, જમણે દબાવો અને તમારો પિન દાખલ કરો"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"આ પ્રોગ્રામને <xliff:g id="RATING">%1$s</xliff:g> રેેેટ કરેલ છે.\nઆ પ્રોગ્રામ જોવા માટે, જમણે દબાવો અને તમારો PIN દાખલ કરો."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"આ ચૅનલ જોવા માટે, ડિફૉલ્ટ લાઇવ TV ઍપ્લિકેશનનો ઉપયોગ કરો."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"આ પ્રોગ્રામ જોવા માટે, ડિફૉલ્ટ લાઇવ TV ઍપ્લિકેશનનો ઉપયોગ કરો."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"આ પ્રોગ્રામ અનરેટેડ છે.\nઆ પ્રોગ્રામ જોવા માટે, ડિફૉલ્ટ લાઇવ TV ઍપનો ઉપયોગ કરો."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"આ પ્રોગ્રામને <xliff:g id="RATING">%1$s</xliff:g> રેેેટ કરેલ છે.\nઆ પ્રોગ્રામ જોવા માટે, ડિફૉલ્ટ લાઇવ TV ઍપ્લિકેશનનો ઉપયોગ કરો."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"પ્રોગ્રામ અવરોધિત કરેલ છે"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"આ પ્રોગ્રામ અનરેટેડ છે"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"આ પ્રોગ્રામ <xliff:g id="RATING">%1$s</xliff:g> રેટ કરેલ છે"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ફક્ત ઑડિઓ"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"નબળા સંકેત"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"કોઈ ઇન્ટરનેટ કનેક્શન નથી"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="one">આ ચૅનલ <xliff:g id="END_TIME_1">%1$s</xliff:g> સુધી ચલાવી શકાશે નહીં કારણ કે અન્ય ચૅનલો રેકોર્ડ થઈ રહી છે. \n\nરેકોર્ડિંગ શેડ્યૂલ ગોઠવવા માટે જમણે દબાવો.</item>
+ <item quantity="other">આ ચૅનલ <xliff:g id="END_TIME_1">%1$s</xliff:g> સુધી ચલાવી શકાશે નહીં કારણ કે અન્ય ચૅનલો રેકોર્ડ થઈ રહી છે. \n\nરેકોર્ડિંગ શેડ્યૂલ ગોઠવવા માટે જમણે દબાવો.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"કોઈ શીર્ષક નથી"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ચૅનલ અવરોધિત કરી"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"નવું"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"સ્રોતો"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d ચૅનલ</item>
+ <item quantity="other">%1$d ચૅનલ</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"કોઈ ચૅનલો ઉપલબ્ધ નથી"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"નવું"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"સેટ કરેલ નથી"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"વધુ સ્રોત મેળવો"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"લાઇવ ચૅનલો ઑફર કરતી ઍપ્લિકેશનો બ્રાઉઝ કરો"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"નવી ચૅનલનાં સ્રોત ઉપલબ્ધ છે"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"નવા ચૅનલ સ્રોત પાસે ઑફર કરવા માટે ચૅનલો છે.\nતેમને હમણાં જ સેટ કરો અથવા ચૅનલ સ્રોત સેટિંગમાં પછીથી આ કરી શકો છો."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"હવે સેટ કરો"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"બરાબર, સમજાઇ ગયું"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"TV મેનૂને ઍક્સેસ કરવા માટે "<b>"પસંદ કરો દબાવો"</b>"."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"કોઈ TV ઇનપુટ મળ્યું નથી"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"TV ઇનપુટ શોધી શકાતું નથી"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ટ્યૂનર પ્રકાર યોગ્ય નથી. કૃપા કરીને ટ્યૂનર પ્રકાર TV ઇનપુટ માટે લાઇવ ચૅનલો લોંચ કરો."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ટ્યૂન કરવાનું નિષ્ફળ થયું"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"આ ક્રિયાને હેન્ડલ કરવા માટે કોઈ ઍપ્લિકેશન મળી નહીં."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"તમામ સ્રોત ચૅનલો છુપાયેલા છે.\nજોવા માટે ઓછામાં ઓછી એક ચૅનલ પસંદ કરો."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"વિડિઓ અનપેક્ષિત રીતે અનુપલબ્ધ છે"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"પાછળ કી કનેક્ટ કરેલ ઉપકરણ માટે છે. બહાર નીકળવા માટે હોમ બટન દબાવો."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"TVની સૂચિ વાંચવા માટે લાઇવ ચૅનલોને પરવાનગીની જરૂર છે."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"તમારા સ્રોત સેટઅપ કરો"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"લાઇવ ચૅનલો પરંપરાગત TV ચૅનલોનાં અનુભવને ઍપ્લિકેશનો દ્વારા પ્રદાન કરેક સ્ટ્રીમિંગ ચૅનલો સાથે ભેગો કરે છે. \n\nપહેલેથી ઇન્સ્ટૉલ કરેલ હોય તે ચૅનલ સ્રોતોને સેટ કરીને પ્રારંભ કરો. અથવા Google Play સ્ટોર બ્રાઉઝ કરો."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"રેકોર્ડિંગ અને શેડ્યૂલ"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 મિનિટ"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 મિનિટ"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 કલાક"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 કલાક"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"તાજેતરના"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"શેડ્યૂલ કરેલ"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"શ્રૃંખલા"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"અન્ય"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ચૅનલ રેકોર્ડ કરી શકાતી નથી."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"પ્રોગ્રામ રેકોર્ડ કરી શકાતો નથી."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> રેકોર્ડ થવા માટે શેડ્યૂલ કરવામાં આવ્યો છે"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"હવેથી <xliff:g id="ENDTIME">%2$s</xliff:g> સુધી <xliff:g id="PROGRAMNAME">%1$s</xliff:g> રેકોર્ડ કરાશે"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"સંપૂર્ણ શેડ્યૂલ"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="one">આગલાં %1$d દિવસ</item>
+ <item quantity="other">આગલાં %1$d દિવસ</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="one">%1$d મિનિટ</item>
+ <item quantity="other">%1$d મિનિટ</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="one">%1$d નવા રેકોર્ડિંગ</item>
+ <item quantity="other">%1$d નવા રેકોર્ડિંગ</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="one">%1$d રેકોર્ડિંગ</item>
+ <item quantity="other">%1$d રેકોર્ડિંગ</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="one">%1$d રેકોર્ડિંગ શેડ્યૂલ કર્યા</item>
+ <item quantity="other">%1$d રેકોર્ડિંગ શેડ્યૂલ કર્યા</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"રેકોર્ડિંગ રદ કરો"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"રેકોર્ડિંગ રોકો"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"ઘડિયાળ"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"શરૂઆતથી ચલાવો"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"ચલાવવાનું ફરી શરૂ કરો"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"કાઢી નાખો"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"રેકોર્ડિંગ કાઢી નાખો"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"ફરી શરૂ કરો"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"સિઝન <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"શેડ્યૂલ જુઓ"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"વધુ વાંચો"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"રેકોર્ડિંગ કાઢી નાખો"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"તમે કાઢી નાખવા માગતા હોય તે એપિસોડ પસંદ કરો. એક વાર કાઢી નાખ્યા પછી તે પુનઃપ્રાપ્ત કરી શકાશે નહીં."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"કાઢી શકાય તેવું કોઈ રેકોર્ડિંગ નથી."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"જોયેલા એપિસોડ પસંદ કરો"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"તમામ એપિસોડ પસંદ કરો"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"તમામા એપિસોડની પસંદગી દૂર કરો"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> માંથી <xliff:g id="WATCHED">%1$d</xliff:g> મિનિટની રેકોર્ડિંગ જોઈ"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> માંથી <xliff:g id="WATCHED">%1$d</xliff:g> સેકન્ડની રેકોર્ડિંગ જોઈ"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"ક્યારેય જોઈ નથી"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="one">%2$dમાંથી %1$d એપિસોડ કાઢી નાખ્યાં</item>
+ <item quantity="other">%2$dમાંથી %1$d એપિસોડ કાઢી નાખ્યાં</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"પ્રાધાન્યતા"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"સૌથી ઉચ્ચ"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ન્યૂનતમ"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"નં. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ચૅનલો"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"કોઈપણ"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"પ્રાધાન્યતા પસંદ કરો"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"જ્યારે એક જ સમયે રેકોર્ડ કરવા માટે ઘણાં બધા પ્રોગ્રામ હોય છે, ત્યારે વધુ પ્રાધાન્યતાવાળા પ્રોગ્રામ જ રેકોર્ડ કરાશે."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"સાચવો"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"એક-વારની રેકોર્ડિંગની સૌથી વધુ પ્રાધાન્યતા હોય છે"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"રોકો"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"રેકોર્ડિંગ શેડ્યૂલ જુઓ"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"આ એકલ પ્રોગ્રામ"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"હવેથી - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"સમગ્ર શ્રૃંખલા…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"કોઈપણ રીતે શેડ્યૂલ કરો"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"તેને બદલે આ રેકોર્ડ કરો"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"આ રેકોર્ડિંગ રદ કરો"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"હમણાં જુઓ"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"રેકોર્ડિંગ કાઢી નાખો…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"રેકોર્ડ કરવા યોગ્ય"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"રેકોર્ડિંગ શેડ્યૂલ કર્યું"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"રેકોર્ડિંગ વિરોધ"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"રેકોર્ડ કરી રહ્યું છે"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"રેકોર્ડ કરવાનું નિષ્ફળ થયું"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"પ્રોગ્રામની માહિતી વાંચી રહી છે"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"તાજેતરનું રેકોર્ડિંગ જુઓ"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>નું રેકોર્ડિંગ અધૂરું છે."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> અને <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>નું રેકોર્ડિંગ અધૂરું છે."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> અને <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>નું રેકોર્ડિંગ અધૂરું છે."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"અપર્યાપ્ત સ્ટોરેજને કારણે <xliff:g id="PROGRAMNAME">%1$s</xliff:g>નું રેકોર્ડિંગ પૂર્ણ થયું નથી."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"અપર્યાપ્ત સ્ટોરેજને કારણે <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> અને <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>નું રેકોર્ડિંગ પૂર્ણ થયું નથી."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"અપર્યાપ્ત સ્ટોરેજને કારણે <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> અને <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>નું રેકોર્ડિંગ પૂર્ણ થયું નથી."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVRને વધુ સ્ટોરેજની જરૂર છે"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"તમે DVR વડે પ્રોગ્રામ રેકોર્ડ કરી શકશો. જોકે, હમણાં તમારા ઉપકરણ પર DVR કાર્ય કરી શકે તે માટે પર્યાપ્ત સ્ટોરેજ નથી. કૃપા કરીને <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB અથવા તેનાથી મોટી બાહ્યાં ડ્રાઇવ કનેક્ટ કરો અને તેને ઉપકરણ સ્ટોરેજ તરીકે ફૉર્મેટ કરવા માટે પગલાં અનુસરો."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"પર્યાપ્ત સ્ટોરેજ ઉપલબ્ધ નથી"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"પર્યાપ્ત સ્ટોરેજ ન હોવાને કારણે આ પ્રોગ્રામ રેકોર્ડ કરાશે નહીં. કેટલીક અસ્તિત્વમાંની રેકોર્ડિંગને કાઢી નાખીને ફરી પ્રયાસ કરો."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"સ્ટોરેજ ખૂટે છે"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"રેકોર્ડિંગ રોકીએ?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"રેકોર્ડ કરેલ સામગ્રી સાચવવામાં આવશે."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>નું રેકોર્ડિંગ બંધ થશે કારણ કે તે આ પ્રોગ્રામ સાથે વિરોધાભાસી છે. રેકોર્ડ કરેલ સામગ્રી સાચવવામાં આવશે."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"રેકોર્ડિંગ શેડ્યૂલ કરી પણ તે વિરોધાભાસી છે"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"રેકોર્ડિંગ શરૂ થઈ ગઈ છે પરંતુ તે વિરોધાભાસી છે"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> રેકોર્ડ કરવામાં આવશે."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> રેકોર્ડ થઈ રહી છે."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g>નાં કેટલાક ભાગો રેકોર્ડ કરવામાં આવશે નહીં."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> અને <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>નાં કેટલાક ભાગો રેકોર્ડ કરવામાં આવશે નહીં."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> અને વધુ એક શેડ્યૂલનાં કેટલાક ભાગો રેકોર્ડ કરવામાં આવશે નહીં."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> અને વધુ %3$d શેડ્યૂલનાં ભાગો રેકોર્ડ કરવામાં આવશે નહીં.</item>
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> અને વધુ %3$d શેડ્યૂલનાં ભાગો રેકોર્ડ કરવામાં આવશે નહીં.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"તમે શું રેકોર્ડ કરવા માગો છો?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"તમે કેટલી વાર સુધી રેકોર્ડ કરવા માગો છો?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"પહેલેથી શેડ્યૂલ કરેલ છે"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"આ જ પ્રોગ્રામ <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> વાગ્યે રેકોર્ડ કરવા માટે શેડ્યૂલ કરેલ છે."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"પહેલેથી રેકોર્ડ કરેલ છે"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"આ પ્રોગ્રામ પહેલેથી રેકોર્ડ કરેલો છે. તે DVR લાઇબ્રેરીમાં ઉપલબ્ધ છે."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"શ્રૃંખલા રેકોર્ડિંગ શેડ્યૂલ કરેલ છે"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> રેકોર્ડિંગ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> માટે શેડ્યૂલ કરવામાં આવ્યાં છે.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> રેકોર્ડિંગ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> માટે શેડ્યૂલ કરવામાં આવ્યાં છે.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> રેકોર્ડિંગ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> માટે શેડ્યૂલ કરવામાં આવ્યાં છે. વિરોધને કારણે તેમાંથી <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>ને રેકોર્ડ કરવામાં આવશે નહીં.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> રેકોર્ડિંગ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> માટે શેડ્યૂલ કરવામાં આવ્યાં છે. વિરોધને કારણે તેમાંથી <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>ને રેકોર્ડ કરવામાં આવશે નહીં.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> રેકોર્ડિંગ <xliff:g id="SERIESNAME_4">%2$s</xliff:g> માટે શેડ્યૂલ કરવામાં આવ્યાં છે. વિરોધને કારણે આ શ્રૃંખલા અને અન્ય શ્રૃંખલાનાં <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> એપિસોડ રેકોર્ડ કરવામાં આવશે નહીં.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> રેકોર્ડિંગ <xliff:g id="SERIESNAME_4">%2$s</xliff:g> માટે શેડ્યૂલ કરવામાં આવ્યાં છે. વિરોધને કારણે આ શ્રૃંખલા અને અન્ય શ્રૃંખલાનાં <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> એપિસોડ રેકોર્ડ કરવામાં આવશે નહીં.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> રેકોર્ડિંગ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> માટે શેડ્યૂલ કરવામાં આવ્યાં છે. વિરોધને કારણે અન્ય શ્રૃંખલાનો 1 એપિસોડ રેકોર્ડ કરાશે નહીં.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> રેકોર્ડિંગ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> માટે શેડ્યૂલ કરવામાં આવ્યાં છે. વિરોધને કારણે અન્ય શ્રૃંખલાનો 1 એપિસોડ રેકોર્ડ કરાશે નહીં.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> રેકોર્ડિંગ <xliff:g id="SERIESNAME_4">%2$s</xliff:g> માટે શેડ્યૂલ કરવામાં આવ્યાં છે. વિરોધને કારણે અન્ય શ્રૃંખલાનાં <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> એપિસોડ રેકોર્ડ કરાશે નહીં.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> રેકોર્ડિંગ <xliff:g id="SERIESNAME_4">%2$s</xliff:g> માટે શેડ્યૂલ કરવામાં આવ્યાં છે. વિરોધને કારણે અન્ય શ્રૃંખલાનાં <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> એપિસોડ રેકોર્ડ કરાશે નહીં.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"રેકોર્ડ કરેલ પ્રોગ્રામ મળ્યોં નથી."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"સંબંધિત રેકોર્ડિંગ"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="one">%1$d રેકોર્ડિંગ</item>
+ <item quantity="other">%1$d રેકોર્ડિંગ</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>ને રેકોર્ડિંગ શેડ્યૂલથી દૂર કરાયો"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ટ્યૂનર વિરોધને કારણે તે આંશિક રીતે રોકોર્ડ કરાશે."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ટ્યૂનર વિરોધને કારણે તે રોકોર્ડ કરાશે નહીં."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"હજી સુધી શેડ્યૂલ કરેલ કોઈ રેકોર્ડિંગ નથી.\nતમે પ્રોગ્રામ માર્ગદર્શિકાથી રેકોર્ડિંગને શેડ્યૂલ કરી શકો છો."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="one">%1$d રેકોર્ડિંગ વિરોધ</item>
+ <item quantity="other">%1$d રેકોર્ડિંગ વિરોધ</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"શ્રૃંખલા સેટિંગ્સ"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"શ્રૃંખલા રેકોર્ડ કરવાનું શરૂ કરો"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"શ્રૃંખલા રેકોર્ડ કરવાનું રોકો"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"શ્રૃંખલા રેકોર્ડ કરવાનું રોકીએ?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"રેકોર્ડ કરેલા એપિસોડ DVR લાઇબ્રેરીમાં ઉપલબ્ધ રહેશે."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"રોકો"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"હમણાં કોઈ એપિસોડ પ્રસારિત થઈ રહ્યાં નથી."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"કોઈ એપિસોડ ઉપલબ્ધ નથી.\nતે ઉપલબ્ધ હશે ત્યારે રેકોર્ડ કરવામાં આવશે."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="one">(%1$d મિનિટ)</item>
+ <item quantity="other">(%1$d મિનિટ)</item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"આજે"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"આવતીકાલે"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"ગઈકાલે"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> આજે"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> આવતી કાલે"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"સ્કોર"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"રેકોર્ડ કરેલ પ્રોગ્રામ"</string>
+</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index d6db8677..146bfa06 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"मोनो"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"स्टीरियो"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"चलाने के नियंत्रण"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"हाल ही के चैनल"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"चैनल"</string>
<string name="menu_title_options" msgid="7184594626814914022">"टीवी विकल्प"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP विकल्‍प"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"इस चैनल के लिए चलाने के नियंत्रण अनुपलब्‍ध हैं"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"चलाएं या रोकें"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"फ़ास्ट फ़ॉरवर्ड करें"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"उपशीर्षक"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"प्रदर्शन मोड"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"चालू"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"बंद"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"एकाधिक-ऑडियो"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"अधिक चैनल पाएं"</string>
<string name="options_item_settings" msgid="7623205838542400074">"सेटिंग"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"स्रोत"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"स्वैप करें"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"चालू"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"बंद"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"ध्वनि"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"मुख्‍य"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP विंडो"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"लेआउट"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"नीचे दाएं"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"ऊपर दाएं"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"ऊपर बाएं"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"नीचे बाएं"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"साथ-साथ"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"आकार"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"बड़ा"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"छोटा"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"इनपुट स्रोत"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"टीवी (एंटिना/केबल)"</string>
<string name="no_program_information" msgid="1049844207745145132">"कोई कार्यक्रम जानकारी नहीं"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"कोई सूचना नहीं"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"अवरोधित चैनल"</string>
- <string name="default_language" msgid="4122326459624337928">"अज्ञात भाषा"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"अज्ञात भाषा"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"बंद कैप्शन %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"उपशीर्षक"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"बंद"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"प्रारूपण कस्टमाइज़ करें"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"इसके द्वारा समूहीकृत"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"यह कार्यक्रम अवरोधित है"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"इस कार्यक्रम को रेट नहीं किया गया है"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"इस कार्यक्रम को <xliff:g id="RATING">%1$s</xliff:g> रेट किया गया है"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"इनपुट ऑटो-स्कैन का समर्थन नहीं करता है"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' के लिए स्वतः स्कैन प्रारंभ करने में असमर्थ"</string>
@@ -92,7 +74,6 @@
<item quantity="other">%1$d चैनल जोड़े गए</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"कोई चैनल नहीं जोड़ा गया"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ट्यूनर"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"अभिभावकीय नियंत्रण"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"चालू"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"बंद"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"अन्य देश"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"कोई नहीं"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"कोई नहीं"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"रेट नहीं किया गया"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"रेट नहीं किए गए कार्यक्रम ब्लॉक करें"</string>
<string name="option_rating_none" msgid="5204552587760414879">"कोई नहीं"</string>
<string name="option_rating_high" msgid="8898400296730158893">"उच्च प्रतिबंध"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"मध्यम प्रतिबंध"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"इस चैनल को देखने के लिए अपना पिन डालें"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"इस कार्यक्रम को देखने के लिए अपना पिन डालें"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"इस कार्यक्रम को <xliff:g id="RATING">%1$s</xliff:g> रेट किया गया है. यह कार्यक्रम देखने के लिए अपना पिन डालें"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"इस कार्यक्रम को रेट नहीं किया गया है. इसे देखने के लिए अपना पिन डालें"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"अपना पिन डालें"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"अभिभावकीय नियंत्रण सेट करने के लिए, पिन बनाएं"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"नया पिन डालें"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"वह पिन गलत था. पुन: प्रयास करें."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"फिर से प्रयास करें, पिन का मिलान नहीं हुआ"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"अपना ज़िप कोड डालें."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"लाइव चैनल ऐप्लिकेशन ज़िप कोड का उपयोग करके टीवी चैनल के लिए पूरी कार्यक्रम मार्गदर्शिका देगा."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"अपना ज़िप कोड डालें"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"अमान्य ज़िप कोड"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"सेटिंग"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"चैनल सूची कस्टमाइज़ करें"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"कार्यक्रम मार्गदर्शिका के लिए चैनल चुनें"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"चैनल के स्रोत"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"नए चैनल उपलब्‍ध हैं"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"अभिभावकीय नियंत्रण"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"टाइमशिफ़्ट"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"देखते समय रिकॉर्ड करें ताकि आप लाइव कार्यक्रमों को रोक सकें या उन्हें रिवाइंड कर पाएं.\nचेतावनी: यह जगह का बहुत ज़्यादा उपयोग करके आंतरिक जगह का जीवनकाल घटा सकता है."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"ओपन सोर्स लाइसेंस"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"ओपन सोर्स लाइसेंस"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"फ़ीडबैक भेजें"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"वर्शन"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"इस चैनल को देखने के लिए, दाईं ओर दबाएं और अपना पिन डालें"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"इस कार्यक्रम को देखने के लिए, दाईं ओर दबाएं और अपना पिन डालें"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"इस कार्यक्रम को रेट नहीं किया गया है.\nइसे देखने के लिए, कृपया दायां दबाएं और अपना पिन डालें"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"इस कार्यक्रम को <xliff:g id="RATING">%1$s</xliff:g> रेट किया गया है.\nइस कार्यक्रम को देखने के लिए, Right दबाएं और अपना पिन डालें."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"इस चैनल को देखने के लिए, डिफ़ॉल्ट लाइव टीवी ऐप का उपयोग करें."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"इस कार्यक्रम को देखने के लिए, डिफ़ॉल्ट लाइव टीवी ऐप का उपयोग करें."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"इस कार्यक्रम को रेट नहीं किया गया है.\nइसे देखने के लिए, डिफ़ॉल्ट Live TV ऐप्लिकेशन का उपयोग करें."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"इस कार्यक्रम को <xliff:g id="RATING">%1$s</xliff:g> रेट किया गया है.\nइस कार्यक्रम को देखने के लिए, डिफ़ॉल्ट लाइव टीवी ऐप का उपयोग करें."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"यह कार्यक्रम बंद कर दिया गया है"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"इस कार्यक्रम को रेट नहीं किया गया है"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"इस कार्यक्रम को <xliff:g id="RATING">%1$s</xliff:g> रेट किया गया है"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"केवल ऑडियो"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"कमज़ोर सिग्नल"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307">"टीवी मेनू ऐक्‍सेस करने के लिए "<b>"चुनें"</b>" दबाएं."</string>
<string name="msg_no_input" msgid="3897674146985427865">"कोई टीवी इनपुट नहीं मिला"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"टीवी इनपुट नहीं मिल पा रहा है"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP समर्थित नहीं है"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"कोई उपलब्ध इनपुट नहीं है जिसे PIP के साथ दिखाया जा सके"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"ट्यूनर प्रकार उपयुक्‍त नहीं है. कृपया ट्यूनर प्रकार टीवी इनपुट के लिए Live TV ऐप लॉन्‍च करें."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"ट्यून विफल रहा"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"यह कार्रवाई प्रबंधित करने के लिए कोई ऐप नहीं मिला."</string>
@@ -226,6 +217,8 @@
<item quantity="one">%1$d रिकॉर्डिंग शेड्यूल की गईं</item>
<item quantity="other">%1$d रिकॉर्डिंग शेड्यूल की गईं</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"रिकॉर्डिंग रद्द करें"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"रिकॉर्डिंग बंद करें"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"देखें"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"शुरू से चलाएं"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"चलाना फिर शुरू करें"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"जब एक ही समय पर कई सारे कार्यक्रम रिकॉर्ड करने हों, तो केवल उच्च प्राथमिकता वाले कार्यक्रम रिकॉर्ड किए जाएंगे."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"सहेजें"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"एक बार की रिकॉर्डिंग को उच्च प्राथमिकता दी जाती है"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"रद्द करें"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"रद्द करें"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"भूल जाएं"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"रोकें"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"रिकॉर्डिंग शेड्यूल देखें"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"यह एक ही कार्यक्रम"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"उसके बजाय इसे रिकॉर्ड करें"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"यह रिकॉर्डिंग रद्द करें"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"अभी देखें"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"रिकॉर्डिंग हटाएं…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"रिकॉर्ड करने योग्य"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"रिकॉर्डिंग शेड्यूल की गई"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"रिकॉर्डिंग संबंधी विरोध"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"रिकॉर्ड हो रहा है"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"रिकॉर्डिंग विफल रही"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"रिकॉर्डिंग शेड्यूल बनाने के लिए कार्यक्रम पढ़े जा रहे हैं"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"प्रोग्राम पढ़े जा रहे हैं"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"कार्यक्रम पढ़े जा रहे हैं"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"हाल ही की रिकॉर्डिंग देखें"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> की रिकॉर्डिंग अधूरी है."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> और <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> की रिकॉर्डिंग अधूरी है."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> और <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> की रिकॉर्डिंग अधूरी है."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"पर्याप्त जगह नहीं होने के कारण <xliff:g id="PROGRAMNAME">%1$s</xliff:g> की रिकॉर्डिंग पूरी नहीं हुई."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"पर्याप्त जगह नहीं होने के कारण <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> और <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> की रिकॉर्डिंग पूरी नहीं हुई."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"पर्याप्त जगह नहीं होने के कारण <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> और <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> की रिकॉर्डिंग पूरी नहीं हुई."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR को अधिक जगह की आवश्यकता है"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"आप DVR से प्रोग्राम रिकॉर्ड कर पाएंगे. हालांकि इस समय आपके डिवाइस पर DVR के काम करने के लिए पर्याप्त जगह नहीं है. कृपया एक बाहरी डिवाइस कनेक्ट करें जिसमें <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB या उससे अधिक जगह हो और उसे डिवाइस जगह के रूप में फ़ॉर्मेट करने के चरणों का अनुसरण करें."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"आप DVR से प्रोग्राम रिकॉर्ड कर पाएंगे. हालांकि इस समय आपके डिवाइस पर DVR के काम करने के लिए पर्याप्त जगह नहीं है. कृपया एक बाहरी डिवाइस कनेक्ट करें जिसमें <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB या उससे अधिक जगह हो और उसे डिवाइस जगह के रूप में फ़ॉर्मेट करने के चरणों का अनुसरण करें."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"पर्याप्‍त जगह नहीं है"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"इस कार्यक्रम को रिकॉर्ड नहीं किया जाएगा क्योंकि पर्याप्त जगह उपलब्ध नहीं है. कुछ मौजूदा रिकॉर्डिंग हटाकर देखें."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"जगह मिल नहीं रही है"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR द्वारा उपयोग की गई कुछ जगह मिल नहीं रही है. कृपया DVR को दोबारा सक्षम करने से पहले अपनी उपयोग की हुई बाहरी डिस्क कनेक्ट करें. वैकल्पिक रूप से, यदि जगह अब उपलब्ध नहीं है तो आप उसे भूल जाना चुन सकते हैं."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"जगह को भूल जाएं?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"आपकी रिकॉर्ड की हुई सभी सामग्री और शेड्यूल खो जाएंगे."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"रिकॉर्डिंग बंद करें?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"रिकॉर्ड की गई सामग्री सहेज ली जाएगी."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> की रिकॉर्डिंग रोक दी जाएगी क्योंकि यह इस प्रोग्राम का विरोध करता है. रिकॉर्ड की गई सामग्री सहेज ली जाएगी."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"रिकॉर्डिंग शेड्यूल की गई लेकिन विरोध मौजूद हैं"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"रिकॉर्डिंग शुरू हो गई है लेकिन उसमें विरोध मौजूद हैं"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> रिकॉर्ड किया जाएगा."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"इसी कार्यक्रम को <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> बजे रिकॉर्ड करने के लिए पहले ही शेड्यूल किया जा चुका है."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"पहले ही रिकॉर्ड हो चुका है"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"यह कार्यक्रम पहले ही रिकॉर्ड हो चुका है. वह DVR लाइब्रेरी में उपलब्ध है."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"सीरीज़ रिकॉर्डिंग शेड्यूल की गई"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> के लिए <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रिकॉर्डिंग शेड्यूल कर दी गई हैं.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> के लिए <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रिकॉर्डिंग शेड्यूल कर दी गई हैं.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> के लिए <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रिकॉर्डिंग शेड्यूल कर दी गई हैं. अन्य शेड्यूल से विरोधों के कारण उनमें से <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> को रिकॉर्ड नहीं किया जाएगा.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> के लिए <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रिकॉर्डिंग शेड्यूल कर दी गई हैं. अन्य शेड्यूल से विरोधों के कारण उनमें से <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> को रिकॉर्ड नहीं किया जाएगा.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> के लिए <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> रिकॉर्डिंग शेड्यूल कर दी गई हैं. अन्य शेड्यूल और दूसरे सीरीज़ के एपिसोड से विरोधों के कारण इस सीरीज़ और अन्य सीरीज़ के <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> एपिसोड रिकॉर्ड नहीं किए जाएंगे.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> के लिए <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> रिकॉर्डिंग शेड्यूल कर दी गई हैं. अन्य शेड्यूल और दूसरे सीरीज़ के एपिसोड से विरोधों के कारण इस सीरीज़ और अन्य सीरीज़ के <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> एपिसोड रिकॉर्ड नहीं किए जाएंगे.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> के लिए <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रिकॉर्डिंग शेड्यूल कर दी गई हैं. इस सीरीज़ से विरोधों के कारण अन्य सीरीज़ का 1 एपिसोड रिकॉर्ड नहीं किया जाएगा.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> के लिए <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रिकॉर्डिंग शेड्यूल कर दी गई हैं. इस सीरीज़ से विरोधों के कारण अन्य सीरीज़ का 1 एपिसोड रिकॉर्ड नहीं किया जाएगा.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> के लिए <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> रिकॉर्डिंग शेड्यूल कर दी गई हैं. इस सीरीज़ से विरोधों के कारण अन्य सीरीज़ के <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> एपिसोड रिकॉर्ड नहीं किए जाएंगे.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> के लिए <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> रिकॉर्डिंग शेड्यूल कर दी गई हैं. इस सीरीज़ से विरोधों के कारण अन्य सीरीज़ के <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> एपिसोड रिकॉर्ड नहीं किए जाएंगे.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"रिकॉर्ड किया गया प्रोग्राम नहीं मिला."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"संबंधित रिकॉर्डिंग"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(कोई कार्यक्रम वर्णन नहीं)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d रिकॉर्डिंग</item>
<item quantity="other">%1$d रिकॉर्डिंग</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"श्रृंखला की रिकॉर्डिंग रोकें?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"रिकॉर्ड किए गए एपिसोड DVR लाइब्रेरी में उपलब्ध रहेंगे."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"रोकें"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"इस समय कोई भी एपिसोड प्रसारित नहीं हो रहा है."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"कोई भी एपिसोड उपलब्ध नहीं है.\nएपिसोड उपलब्ध होने पर उन्हें रिकॉर्ड कर लिया जाएगा."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d मिनट)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> आज"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> कल"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"स्कोर"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"रिकॉर्ड किए गए कार्यक्रम"</string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 596a3f96..a4f000eb 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Kontrole reprodukcije"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Nedavni kanali"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanali"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV opcije"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opcije PIP-a"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Kontrole reprodukcije nisu dostupne za ovaj kanal"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Reprodukcija ili pauziranje"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Brzo unaprijed"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Titlovi"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Način prikaza"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Uključeno"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Isključeno"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multiaudio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Više kanala"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Postavke"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Izvor"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Zamijeni"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Uključeno"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Isključeno"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Zvuk"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Glavni"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Prozor PIP-a"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Raspored"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Pri dnu desno"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Pri vrhu desno"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Pri vrhu lijevo"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Pri dnu lijevo"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Jedno uz drugo"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Veličina"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Velik"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Malen"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Izvor ulaza"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/kabel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Nema podataka o programu"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Nema informacija"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blokirani kanal"</string>
- <string name="default_language" msgid="4122326459624337928">"Nepoznati jezik"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Nepoznati jezik"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Titlovi %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Titlovi"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Isključeno"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Prilagodi format"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Grupiraj po"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Program je blokiran"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ovaj je program neocijenjen"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Program ima ocjenu <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Ulaz ne podržava automatsko pretraživanje"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Nije moguće pokretanje automatskog pretraživanja za \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
@@ -93,7 +75,6 @@
<item quantity="other">Dodano je %1$d kanala</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Kanali nisu dodani"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tražilo"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Roditeljski nadzor"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Uključeno"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Isključeno"</string>
@@ -109,6 +90,8 @@
<string name="other_countries" msgid="8342216398676184749">"Ostale zemlje"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Ništa"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ništa"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Neocijenjeno"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blokiraj neocijenjene programe"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Ništa"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Visoka ograničenja"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Srednja ograničenja"</string>
@@ -125,6 +108,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Unesite PIN da biste gledali ovaj kanal"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Unesite PIN da biste gledali ovaj program"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Ovaj program ima ocjenu <xliff:g id="RATING">%1$s</xliff:g>. Da biste ga gledali, unesite PIN"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Ovaj je program neocijenjen. Da biste ga gledali, unesite PIN"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Unesite PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Da biste postavili roditeljski nadzor, stvorite PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Unesite novi PIN"</string>
@@ -137,22 +121,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"PIN je pogrešan. Pokušajte ponovno."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Pokušaj ponovo, PIN se ne podudara"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Unesite svoj poštanski broj."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Na temelju poštanskog broja aplikacija TV kanali uživo pružit će vam potpun programski vodič za TV kanale."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Unesite svoj poštanski broj"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Poštanski broj nije važeći"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Postavke"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Prilagodite popis kanala"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Odaberite kanale za programski vodič"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Izvori kanala"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Dostupni su novi kanali"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Roditeljski nadzor"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Vremenski pomak"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Snimajte tijekom gledanja da biste mogli pauzirati ili premotavati emisije uživo.\nUpozorenje: time se može skratiti trajanje interne pohrane zbog njezine intenzivne upotrebe."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licence otvorenog izvornog koda"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licence otvorenog izvornog koda"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Pošaljite povratne informacije"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Verzija"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Da biste gledali ovaj kanal, pritisnite desno pa unesite PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Da biste gledali ovaj program, pritisnite desno pa unesite PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Ovaj je program neocijenjen.\nDa biste ga gledali, pritisnite desno i unesite PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Ovaj program ima ocjenu <xliff:g id="RATING">%1$s</xliff:g>.\nDa biste ga gledali, pritisnite desni gumb pa unesite PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Da biste gledali ovaj kanal, upotrijebite zadanu aplikaciju za TV uživo."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Da biste gledali ovaj program, upotrijebite zadanu aplikaciju za TV uživo."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Ovaj je program neocijenjen.\nDa biste ga gledali, upotrijebite zadanu aplikaciju za TV uživo."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Ovaj program ima ocjenu <xliff:g id="RATING">%1$s</xliff:g>.\nDa biste ga gledali, upotrijebite zadanu aplikaciju za TV uživo."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Program je blokiran"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ovaj je program neocijenjen"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Program ima ocjenu <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Samo zvuk"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Slab signal"</string>
@@ -185,8 +178,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Pritisnite ODABERITE"</b>" da biste pristupili izborniku TV-a."</string>
<string name="msg_no_input" msgid="3897674146985427865">"TV ulaz nije pronađen"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"TV ulaz nije pronađen"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP nije podržan"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Nema dostupnog ulaza koji se može prikazati putem PIP-a"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Vrsta prijemnika nije prikladna. Pokrenite aplikaciju Kanali uživo ako želite koristiti prijemnik kao TV ulaz."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Traženje kanala nije uspjelo"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Nije pronađena nijedna aplikacija koja može provesti tu radnju."</string>
@@ -235,6 +226,8 @@
<item quantity="few">%1$d snimanja zakazana</item>
<item quantity="other">%1$d snimanja zakazano</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Otkaži snimanje"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Zaustavi snimanje"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Gledaj"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Reproduciraj od početka"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Nastavi reprodukciju"</string>
@@ -268,9 +261,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Kada će se se istovremeno trebati snimati previše emisija, snimit će se samo one s najvišim prioritetom."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Spremi"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Jednokratna snimanja imaju najviši prioritet"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Odustani"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Odustani"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Zaboravi"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Zaustavi"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Prikaz rasporeda snimanja"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Samo jedna epizoda"</string>
@@ -280,25 +270,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Snimi ovo"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Otkaži snimanje"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Pogledajte odmah"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Brisanje snimki…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Snimanje moguće"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Snimanje programirano"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Sukob rasporeda snimanja"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Snimanje"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Snimanje nije uspjelo"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Čitanje emisija za izradu rasporeda snimanja"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Čitanje emisija"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Čitanje emisija"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Prikaži nedavne snimke"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Snimka sadržaja <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nije dovršena."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Snimke sadržaja <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> i <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> nisu dovršene."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Snimke sadržaja <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> i <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> nisu dovršene."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Snimanje sadržaja <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nije dovršeno jer nema dovoljno mjesta u pohrani."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Snimanje sadržaja <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> i <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> nije dovršeno jer nema dovoljno mjesta u pohrani."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Snimanje sadržaja <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> i <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> nije dovršeno jer nema dovoljno mjesta u pohrani."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR treba više prostora za pohranu"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Moći ćete snimati programe DVR-om. No na vašem uređaju trenutačno nema dovoljno prostora za pohranu da bi DVR funkcionirao. Priključite vanjski disk od najmanje <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB i formatirajte ga kao pohranu uređaja prema uputama."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Moći ćete snimati programe DVR-om. No na vašem uređaju trenutačno nema dovoljno prostora za pohranu da bi DVR funkcionirao. Priključite vanjski disk od najmanje <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB i formatirajte ga kao pohranu uređaja prema uputama."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Nema dovoljno prostora za pohranu"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Emisija se neće snimiti jer nema dovoljno prostora za pohranu. Izbrišite neke snimljene emisije."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Pohrana nedostaje"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Nedostaje dio pohrane kojom se koristi DVR. Da biste ponovo omogućili DVR, povežite ga s vanjskim diskom koji ste upotrebljavali prethodno. Ako ta pohrana više nije dostupna, možete odabrati da je uređaj zaboravi."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Zaboraviti pohranu?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Izgubit ćete sve snimljene sadržaje i programirana snimanja."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Želite li zaustaviti snimanje?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Snimljeni će se sadržaj spremiti."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Snimanje sadržaja <xliff:g id="PROGRAMNAME">%1$s</xliff:g> zaustavit će se zbog sukoba s ovim programom. Snimljeni sadržaj ostat će spremljen."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Snimanje je programirano, ali ima sukoba"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Snimanje je započelo, ali ima sukoba"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Snimit će se <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
@@ -317,17 +310,34 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Snimanje tog programa već je programirano za <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Već snimljeno"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Taj je program već snimljen. Dostupan je u zbirci DVR-a."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Snimanje serije je zakazano"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> snimanje zakazano je za seriju <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> snimanja zakazana su za seriju <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> snimanja zakazano je za seriju <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> snimanje zakazano je za seriju <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> od njih neće se snimiti zbog sukoba.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> snimanja zakazana su za seriju <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> od njih neće se snimiti zbog sukoba.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> snimanja zakazano je za seriju <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> od njih neće se snimiti zbog sukoba.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> snimanje zakazano je za seriju <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> epizoda/e te serije i druge serije neće se snimiti zbog sukoba.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> snimanja zakazana su za seriju <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> epizoda/e te serije i druge serije neće se snimiti zbog sukoba.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> snimanja zakazano je za seriju <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> epizoda/e te serije i druge serije neće se snimiti zbog sukoba.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> snimanje zakazano je za seriju <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 epizoda neke druge serije neće se snimiti zbog sukoba.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> snimanja zakazana su za seriju <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 epizoda neke druge serije neće se snimiti zbog sukoba.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> snimanja zakazano je za seriju <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 epizoda neke druge serije neće se snimiti zbog sukoba.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> snimanje zakazano je za seriju <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> epizoda/e neke druge serije neće se snimiti zbog sukoba.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> snimanja zakazana su za seriju <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> epizoda/e neke druge serije neće se snimiti zbog sukoba.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> snimanja zakazano je za seriju <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> epizoda/e neke druge serije neće se snimiti zbog sukoba.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Snimljeni program nije pronađen."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Povezane snimke"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Nema opisa programa)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d snimka</item>
<item quantity="few">%1$d snimke</item>
@@ -349,6 +359,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Želite li zaustaviti snimanje serije?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Snimljene epizode ostat će dostupne u zbirci DVR-a."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Zaustavi"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Trenutačno se ne emitira nijedna epizoda."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Nije dostupna nijedna epizoda.\nEpizode će se snimiti kada budu dostupne."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d minuta)</item>
@@ -361,4 +372,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> danas"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> sutra"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Rezultat"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Snimljene emisije"</string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index d007a135..f28b3140 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"monó"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"sztereó"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Lejátszásvezérlők"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Legutóbbiak"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Csatornák"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Tv beállításai"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP-beállítások"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"A lejátszási vezérlők nem érhetők el ennél a csatornánál"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Lejátszás vagy szüneteltetés"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Előretekerés"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Feliratok"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Megjelenítés"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Bekapcsolva"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Kikapcsolva"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Több hangsáv"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"További csatornák"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Beállítások"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Forrás"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Csere"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Bekapcsolva"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Kikapcsolva"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Hang"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Elsődleges"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP-ablak"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Elrendezés"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Lent jobbra"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Fent jobbra"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Fent balra"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Lent balra"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Egymás mellett"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Méret"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Nagy"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Kicsi"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Bemeneti forrás"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenna/kábel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Nincsenek műsorinformációk"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Nincs információ."</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Letiltott csatorna"</string>
- <string name="default_language" msgid="4122326459624337928">"Ismeretlen nyelv"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Ismeretlen nyelv"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Feliratok (%1$d)"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Feliratok"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Kikapcsolva"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Személyre szabás"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Csoportosítás"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"A műsor le van tiltva."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ez a műsor nem rendelkezik besorolással"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"A műsor besorolása: <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"A bemenet nem támogatja az automatikus keresést"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Nem lehet elindítani a(z) „<xliff:g id="TV_INPUT">%s</xliff:g>” automatikus keresését"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d csatorna hozzáadva</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Nincs csatorna hozzáadva"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Szülői felügyelet"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Bekapcsolva"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Kikapcsolva"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Más országok"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Nincs"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Nincs"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Nincs besorolás"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Nem besorolt műsorok letiltása"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Nincs"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Magas korlátozások"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Közepes korlátozások"</string>
@@ -124,33 +107,43 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"A csatorna megtekintéséhez PIN-kód szükséges"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"A műsor megtekintéséhez PIN-kód szükséges"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"A műsor besorolása: <xliff:g id="RATING">%1$s</xliff:g>. A megtekintéséhez adja meg PIN-kódját."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Ez a műsor nem rendelkezik besorolással. Adja meg PIN-kódját a műsor megtekintéséhez"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"PIN-kód megadása"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Szülői felügyelet beállításához hozzon létre egy PIN kódot."</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Szülői felügyelet beállításához hozzon létre egy PIN-kódot."</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Új PIN-kód megadása"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"PIN-kód megerősítése"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Adja meg a jelenlegi PIN kódot"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Adja meg a jelenlegi PIN-kódot"</string>
<plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
<item quantity="other">Helytelen PIN-kódot adott meg ötször egymás után.\nPróbálja újra <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> másodperc múlva.</item>
<item quantity="one">Helytelen PIN-kódot adott meg ötször egymás után.\nPróbálja újra <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> másodperc múlva.</item>
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"A PIN-kód helytelen, próbálja újra."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"A PIN-kód nem egyezik, próbálja újra"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Irányítószám megadása"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Az Élő Csatornák alkalmazás az irányítószám használatával megjeleníti a csatornák teljes tévéműsorát."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Adja meg irányítószámát"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Érvénytelen irányítószám"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Beállítások"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Csatornalista testreszabása"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Válasszon csatornákat a műsorfüzetbe"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Csatornaforrások"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Új csatornák állnak rendelkezésre"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Szülői felügyelet"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Időeltolás"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"A nézésük közben felveheti a műsorokat, így szüneteltetheti vagy visszatekerheti őket.\nFigyelmeztetés: A belső tárhely intenzív használata miatt ez a funkció csökkentheti a tárhely élettartamát."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Nyílt forráskódú licencek"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Nyílt forráskódú licencek"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Visszajelzés küldése"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Verzió"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"A csatorna megtekintéséhez nyomja meg a jobbra gombot, majd adja meg a PIN kódot"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"A műsor megtekintéséhez nyomja meg a jobbra gombot, majd adja meg a PIN kódot"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"A műsor besorolása: <xliff:g id="RATING">%1$s</xliff:g>.\nA megtekintéséhez nyomja meg a jobbra gombot, majd adja meg a PIN kódot."</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"A csatorna megtekintéséhez nyomja meg a jobbra gombot, majd adja meg a PIN-kódot"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"A műsor megtekintéséhez nyomja meg a jobbra gombot, majd adja meg a PIN-kódot"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Ez a műsor nem rendelkezik besorolással.\nA műsor megtekintéséhez nyomja meg a Jobb gombot, majd adja meg a PIN-kódot"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"A műsor besorolása: <xliff:g id="RATING">%1$s</xliff:g>.\nA megtekintéséhez nyomja meg a jobbra gombot, majd adja meg a PIN-kódot."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"A csatorna megtekintéséhez használja az alapértelmezett „Live TV” alkalmazást."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"A program megtekintéséhez használja az alapértelmezett „Live TV” alkalmazást."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Ez a műsor nem rendelkezik besorolással.\nA műsor megtekintéséhez használja az alapértelmezett „Live TV” alkalmazást."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"A program besorolása: <xliff:g id="RATING">%1$s</xliff:g>.\nA megtekintéséhez használja az alapértelmezett „Live TV” alkalmazást."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"A műsor le van tiltva"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ez a műsor nem rendelkezik besorolással"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"A műsor besorolása: <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Csak hang"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Gyenge jel"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Nyomja meg a KIVÁLASZTÁS"</b>" gombot a tévé menüjének eléréséhez."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Nem található tévébemenet."</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"A tévébemenet nem található."</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"A kép a képben funkció nem támogatott."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Nincs elérhető bemeneti adás, amely megjeleníthető lenne a kép a képben (picture in picture, PIP) funkcióval."</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"A tuner típusa nem megfelelő. Indítsa el a tévé bemeneti tunertípusának megfelelő Élő csatornák alkalmazást."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Tunerhiba"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Nincs megfelelő alkalmazás a művelet végrehajtásához."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d rögzítés beütemezve</item>
<item quantity="one">%1$d rögzítés beütemezve</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Felvétel megszakítása"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Felvétel leállítása"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Megtekintés"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Lejátszás az elejétől"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Lejátszás folytatása"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Ha túl sok rögzítendő műsort állít be ugyanarra az időtartamra, kizárólag a magasabb prioritással rendelkezőket rögzíti a rendszer."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Mentés"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Az egyszeri rögzítések rendelkeznek a legmagasabb prioritással"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Mégse"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Mégse"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Elfelejt"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Leállítás"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Rögzítési ütemterv megtekintése"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Ezt az egy műsort"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Inkább ez legyen rögzítve"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"A rögzítés törlése"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Nézze meg most"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Felvételek törlése…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Felvehető"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"A felvétel beállítva"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Ütközés más felvétellel"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Rögzítés"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"A felvétel nem sikerült"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Műsorok beolvasása a rögzítési ütemterv kialakításához"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Műsorok beolvasása"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Műsorok beolvasása"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"A legutóbbi felvételek megtekintése"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"A(z) <xliff:g id="PROGRAMNAME">%1$s</xliff:g> felvétele megszakadt."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"A következők felvétele megszakadt: <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> és <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"A következők felvétele megszakadt: <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> és <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"A(z) <xliff:g id="PROGRAMNAME">%1$s</xliff:g> felvétele nem sikerült, mert nincs elég tárhely."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"A következők felvétele a kevés tárhely miatt nem sikerült: <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> és <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"A következők felvétele a kevés tárhely miatt nem sikerült: <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> és <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"A DVR számára több tárhely szükséges"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"A DVR segítségével műsorokat vehet fel. Azonban eszközén nincs elég szabad tárhely a DVR működéséhez. Csatlakoztasson egy legalább <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB tárhellyel rendelkező külső meghajtót, majd kövesse az utasításokat, hogy az eszköz tárhelyévé formázhassa."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"A DVR segítségével műsorokat vehet fel. Azonban eszközén nincs elég szabad tárhely a DVR működéséhez. Csatlakoztasson egy legalább <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB tárhellyel rendelkező külső meghajtót, majd kövesse az utasításokat, hogy az eszköz tárhelyévé formázhassa."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Nincs elegendő tárhely"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Ez a műsor nem lesz felvéve, mivel nincs elegendő tárhely. Próbáljon meg törölni néhány meglévő felvételt."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Hiányzó tárhely"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"A DVR által használt tárhely bizonyos része hiányzik. Kérjük, csatlakoztassa a korábban használt külső meghajtót a DVR ismételt engedélyezéséhez. Másik megoldásként megadhatja a rendszernek, hogy ne emlékezzen többé erre a tárhelyre, ha már nem áll a rendelkezésére."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"A rendszer ne emlékezzen többé erre a tárhelyre?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Az összes rögzített tartalom és ütemterv elvész."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Leállítja a rögzítést?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"A rögzített tartalmat elmenti a rendszer."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"A(z) <xliff:g id="PROGRAMNAME">%1$s</xliff:g> felvétele le fog állni, mert ütközik ezzel a programmal. A felvett tartalmat az alkalmazás menteni fogja."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"A rögzítést beállította, de az ütközik más műsorokkal"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"A rögzítés elindult, de az ütközik más műsorokkal"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"A(z) <xliff:g id="PROGRAMNAME">%1$s</xliff:g> rögzítve lesz."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Ugyanennek a műsornak a rögzítése már be van ütemezve a következő időpontban: <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Már készült róla felvétel"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Erről a műsorról már készült felvétel, amely a DVR könyvtárban található."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Sorozatfelvétel ütemezve"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> felvétel van ütemezve a következőhöz: <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> felvétel van ütemezve a következőhöz: <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> felvétel van ütemezve a következőhöz: <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Ütközés miatt a rendszer nem rögzít <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> felvételt.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> felvétel van ütemezve a következőhöz: <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Ütközés miatt a rendszer nem rögzíti a felvételt.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> felvétel van ütemezve a következőhöz: <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Ütközés miatt a rendszer <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> epizódot nem rögzít ebből, valamint más sorozatokból.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> felvétel van ütemezve a következőhöz: <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Ütközés miatt a rendszer <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> epizódot nem rögzít ebből, valamint más sorozatokból.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> felvétel van ütemezve a következőhöz: <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Ütközés miatt a rendszer 1 epizódot nem rögzít más sorozatokból.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> felvétel van ütemezve a következőhöz: <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Ütközés miatt a rendszer 1 epizódot nem rögzít más sorozatokból.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> felvétel van ütemezve a következőhöz: <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Ütközés miatt a rendszer <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> epizódot nem rögzít más sorozatokból.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> felvétel van ütemezve a következőhöz: <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Ütközés miatt a rendszer <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> epizódot nem rögzít más sorozatokból.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"A rögzített program nem található."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Kapcsolódó felvételek"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Nincs programleírás)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d felvétel</item>
<item quantity="one">%1$d felvétel</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Leállítja a sorozat rögzítését?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"A rögzített részek továbbra is hozzáférhetők lesznek a DVR könyvtárban."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Leállítás"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Egyetlen epizódot sem közvetítenek jelenleg."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Nincs rendelkezésre álló epizód.\nAz epizódok a megjelenésüket követően lesznek rögzítve."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d perc)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Ma: <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Holnap: <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Pontszám"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Felvett műsorok"</string>
</resources>
diff --git a/res/values-hy-v23/strings.xml b/res/values-hy-rAM-v23/strings.xml
index 774fbd3d..774fbd3d 100644
--- a/res/values-hy-v23/strings.xml
+++ b/res/values-hy-rAM-v23/strings.xml
diff --git a/res/values-hy/arrays.xml b/res/values-hy-rAM/arrays.xml
index 5c6f0bfd..5c6f0bfd 100644
--- a/res/values-hy/arrays.xml
+++ b/res/values-hy-rAM/arrays.xml
diff --git a/res/values-hy/rating_system_strings.xml b/res/values-hy-rAM/rating_system_strings.xml
index 8c69ca7e..8c69ca7e 100644
--- a/res/values-hy/rating_system_strings.xml
+++ b/res/values-hy-rAM/rating_system_strings.xml
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
new file mode 100644
index 00000000..a723a2ae
--- /dev/null
+++ b/res/values-hy-rAM/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"մոնո"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"ստերեո"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Նվագարկման կառավար"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Հեռուստաալիքներ"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"Հեռ. ընտրանքներ"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Նվագարկման կառավարներն այս ալիքում անհասանելի են"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Նվագարկել կամ դադարեցնել"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Արագ առաջանցում"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Հետանցում"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Հաջորդը"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Նախորդը"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Ծրագրի ուղեցույց"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Նոր ալիքներ"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Բացել <xliff:g id="APP_NAME">%1$s</xliff:g>-ը"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Փակ խորագրեր"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Ցուցադրման ռեժիմ"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Բազմաուդիո"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Ավելացնել ալիքներ"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Կարգավորումներ"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"Հեռուստացույց (ալեհավաք/մալուխ)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Ծրագրի մասին տեղեկություններ չկան"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Տեղեկություն չկա"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Ալիքն արգելափակված է:"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Անհայտ լեզու"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"%1$d ենթագրեր"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Փակ ենթագրեր"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Անջատված է"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Հարմարացնել ձևաչափը"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Սահմանել համակարգի խորագրերի պարամետրեր"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Ցուցադրման ռեժիմ"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Բազմաուդիո"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"Մոնո"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"Ստերեո"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 ծավալային ձայն"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 ծավալային ձայն"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d հեռուստաալիք"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Հարմարեցնել ցանկը"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Ընտրել խումբը"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Ապընտրել խումբը"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Խմբավորել"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Ալիք աղբյուրը"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Խմբավորել"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Այս ծրագիրը արգելափակված է"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ծրագիրը գնահատված չէ"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Այս ծրագրի վարկանիշը <xliff:g id="RATING">%1$s</xliff:g> է"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Մուտքը ինքնասկանավարում չի աջակցում"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Չի հաջողվում սկսել «<xliff:g id="TV_INPUT">%s</xliff:g>»-ի ավտոմատ սկանավորումը"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Չհաջողվեց բացել խորագրերի համակարգի կարգավորումները:"</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">Ավելացվեց %1$d ալիք</item>
+ <item quantity="other">Ավելացվեց %1$d ալիք</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Ալիքներ չեն ավելացվել"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Ծնողական հսկում"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Միացված է"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Անջատված է"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Արգելափակված են"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Արգելափակել բոլորը"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Ապաարգելափակել բոլորը"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Թաքնված ալիքներ"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Ծր. սահմանափակումներ"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"Փոխել PIN-ը"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Գն. համակարգեր"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Վարկանիշ"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Բոլոր գն. համակարգերը"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Այլ երկրներ"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Չկա"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Չկա"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Չգնահատված"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Արգելափակել չգնահատված ծրագրերը"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Չկա"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Խիստ սահմանափակում"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Միջ. սահմանափակումներ"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Թույլ սահմանափակում"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Հատուկ"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Բովանդակությունը հարմար է երեխաների համար"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Բարձր տարիքային խմբի երեխաների համար"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Բովանդակությունը հարմար է անչափահասների համար"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Ձեռքով կարգավորման սահմանափակումներ"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s և ենթավարկանիշեր"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Ենթավարկանիշեր"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Այս ալիքը դիտելու համար մուտքագրեք PIN-ը"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Այս ծրագիրը դիտելու համա մուտքագրեք PIN-ը"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Այս ծրագիրն ունի տարիքային սահմանափակում՝ <xliff:g id="RATING">%1$s</xliff:g>: Այն դիտելու համար մուտքագրեք PIN կոդը"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Ծրագիրը գնահատված չէ։ Մուտքագրեք PIN-ը՝ այն դիտելու համար"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"Մուտքագրեք ձեր PIN-ը"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Ծնողական վերահսկումը կարգավորելու համար PIN կոդ նախադրեք"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Մուտքագրեք նոր PIN"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"Հաստատեք ձեր PIN-ը"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Մուտքագրեք ձեր ներկայիս PIN-ը"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Դուք 5 անգամ մուտքագրել եք սխալ PIN կոդ:\nՓորձեք նորից <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> վայրկյանից:</item>
+ <item quantity="other">Դուք 5 անգամ մուտքագրել եք սխալ PIN կոդ:\nՓորձեք նորից <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> վայրկյանից:</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN-ը սխալ էր: Կրկին փորձեք:"</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Փորձեք կրկին, PIN-ը չի համապատասխանում"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Մուտքագրեք փոստային դասիչը:"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Ուղիղ եթեր հավելվածը փոստային դասիչը կօգտագործի հեռուստաալիքների ամբողջական ցանկը տրամադրելու համար։"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Մուտքագրեք փոստային դասիչը"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Փոստային դասիչը սխալ է"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Կարգավորումներ"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Հարմարեցնել ալիքների ցանկը"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Ընտրեք ալիքներ հեռուստահաղորդումների ծրագրի համար"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Ալիքների աղբյուրներ"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Առկա են նոր ալիքներ"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Ծնողական վերահսկողություն"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Ժամանակի կառավար"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Ձայնագրեք դիտելիս և կկարողանաք կանգնեցնել կամ հետարկել ուղիղ եթերով հեռարձակվող հաղորդումները:\nԶգուշացում. սա կարող է նվազեցնել ներքին հիշողության օգտագործման ժամկետը, եթե ինտենսիվորեն օգտագործեք հիշողությունը:"</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Բաց կոդով ծրագրակազմի արտոնագրեր"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Կարծիք հայտնել"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Տարբերակ"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Այս կապուղին դիտելու համար սեղմեք Աջ և մուտքագրեք ձեր PIN-ը"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Այս ծրագիրը դիտելու համար սեղմեք Աջ և մուտքագրեք ձեր PIN-ը"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Ծրագիրը գնահատված չէ։\nԱյն դիտելու համար սեղմեք «Աջ» կոճակը և մուտքագրեք ձեր PIN-ը"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Այս ծրագրի վարկանիշը <xliff:g id="RATING">%1$s</xliff:g> է:\nԱյն դիտելու համար սեղմեք Աջ և մուտքագրեք PIN կոդը:"</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Այս ալիքը դիտելու համար օգտագործեք Live TV կանխադրված հավելվածը:"</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Այս հաղորդումը դիտելու համար օգտագործեք Live TV կանխադրված հավելվածը:"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Ծրագիրը գնահատված չէ։\nԱյն դիտելու համար օգտագործեք կանխադրված «Ուղիղ եթեր» հավելվածը"</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Այս հաղորդումը գնահատվել է որպես <xliff:g id="RATING">%1$s</xliff:g>:\nԱյս հաղորդումը դիտելու համար օգտագործեք Live TV կենդանի կանխադրված հավելվածը:"</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Ծրագիրն արգելափակված է"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ծրագիրը գնահատված չէ"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Այս ծրագրի վարկանիշը <xliff:g id="RATING">%1$s</xliff:g> է"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Միայն աուդիո"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Թույլ ազդանշան"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Համացանցի կապակցում չկա"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="one">This channel can\'t be played until <xliff:g id="END_TIME_1">%1$s</xliff:g> because other channels are being recorded. \n\nPress Right to adjust recording schedule.</item>
+ <item quantity="other">Այս ալիքը հնարավոր չէ ցուցադրել մինչև <xliff:g id="END_TIME_1">%1$s</xliff:g>-ը, քանի որ ներկայումս տեսագրվում են այլ ալիքներ: \n\nՏեսագրման ժամանակացույցը կարգավորելու համար սեղմեք Աջ կոճակը:</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Անվերնագիր"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Ալիքն արգելափակված է"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Նոր"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Աղբյուրներ"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d ալիք</item>
+ <item quantity="other">%1$d ալիք</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Ալիքներ չկան"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Նոր"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Կարգավորված չէ"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Ավելացնել այլ աղբյուրներ"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Որոնեք ուղիղ եթեր առաջարկող հավելվածներ"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Հասանելի են ալիքների նոր աղբյուրներ"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Ալիքների նոր աղբյուրները պարունակում են նոր ալիքներ:\nԿարգավորեք դրանք հիմա կամ ավելի ուշ՝ ալիքների աղբյուրների կարգավորումների միջոցով:"</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Կարգավորել հիմա"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Լավ, հասկացա"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"Հեռուստացույցի ընտրացանկից օգտվելու համար "<b>"սեղմեք ԸՆՏՐԵԼ"</b>":"</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"Հեռուստացույցի մուտք չի գտնվել"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"Հեռուստացույցի մուտքը տեղադրված չէ"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Կարգավորիչի մուտքը համապատասխան չէ: Գործարկեք «Ուղիղ եթեր» հավելվածը, եթե օգտագործում եք հեռուստացույցի մուտք:"</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Կարգավորումը չհաջողվեց"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Այս գործողությունը կատարելու համար ոչ մի հավելված չի գտնվել"</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Բոլոր ալիքները թաքնված են:\nԸնտրեք առնվազն մեկ ալիք:"</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Անսպասելի սխալ առաջացավ տեսանյութի ցուցադրման ժամանակ"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"«Հետ» կոճակը միացված սարքի համար է: Դուս գալու համար սեղմեք «Գլխավոր» կոճակը:"</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Հեռուստատեսային ծրագրերը կարդալու համար ուղիղ եթերին թույլտվություն է անհրաժեշտ:"</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Կարգավորեք աղբյուրները"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Ուղիղ եթերը համատեղում է ավանդական հեռուստաալիքները և հավելվածների կողմից հոսքային եղանակով հեռարձակվող ալիքները: \n\nՍկսեք արդեն իսկ տեղադրված ալիքների աղբյուրները կարգավորելուց կամ Google Play Խանութում որոնեք ուղիղ եթեր առաջարկող այլ հավելվածներ:"</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Տեսագրում և ժամանակացույցեր"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 րոպե"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 րոպե"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ժամ"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ժամ"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Վերջինները"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Ծրագրավորված"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Սերիալներ"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Այլ"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Հնարավոր չէ տեսագրել այս հեռուստաալիքը:"</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Հնարավոր չէ տեսագրել այս ծրագիրը:"</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագրի տեսագրումը ծրագրավորվեց"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագրի տեսագրում այս պահից մինչև <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Ամբողջական ժամանակացույց"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="one">Next %1$d days</item>
+ <item quantity="other">%1$d օր</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="one">%1$d minutes</item>
+ <item quantity="other">%1$d րոպե</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="one">%1$d new recordings</item>
+ <item quantity="other">%1$d նոր տեսագրություն</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="one">%1$d recordings</item>
+ <item quantity="other">%1$d տեսագրություն</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="one">%1$d recordings scheduled</item>
+ <item quantity="other">Ծրագրավորվել է %1$d տեսագրություն</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Չեղարկել տեսագրումը"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Դադարեցնել տեսագրումը"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Դիտել"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Նվագարկել սկզբից"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Վերսկսել նվագարկումը"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Ջնջել"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Ջնջել տեսագրությունները"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Շարունակել"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Եթերաշրջան <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Ժամանակացույց"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Կարդալ ավելին"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Ջնջել տեսագրումները"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Ընտրեք դրվագները, որոնք ցանկանում եք ջնջել: Ջնջելուց հետո դրանք այլևս հնարավոր չի լինի տեսագրել:"</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Ջնջելու համար տեսագրումներ չկան"</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Նշել դիտված դրվագները"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Նշել բոլոր դրվագները"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Ապանշել բոլոր դրվագները"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> րոպեից դիտվել է <xliff:g id="WATCHED">%1$d</xliff:g>-ը"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> վայրկյանից դիտվել է <xliff:g id="WATCHED">%1$d</xliff:g>-ը"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Երբեք չդիտված"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="one">%1$d of %2$d episodes are deleted</item>
+ <item quantity="other">%2$d դրվագներից %1$d-ը ջնջվել է</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Առաջնահերթություն"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Ամենաբարձր"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Ամենացածր"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Ոչ: <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Հեռուստաալիքներ"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Ցանկացած"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Ընտրեք առաջնահերթությունը"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Եթե միաժամանակ ծրագրավորված է չափազանց շատ ծրագրերի տեսագրում, ապա կտեսագրվեն միայն բարձր առաջնահերթություն ունեցող ծրագրերը:"</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Պահել"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Միանգամյա տեսագրումն ունի ամենաբարձր առաջնահերթությունը"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Դադար"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Դիտել տեսագրման ժամանակացույցը"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Միայն այս ծրագիրը"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"այժմ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Ամբողջ սերիալը…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Ծրագրավորել"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Փոխարենը տեսագրել այս ծրագիրը"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Չեղարկել այս տեսագրումը"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Դիտել հիմա"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Ջնջել տեսագրությունները…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Հնարավոր է տեսագրել"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Տեսագրումը ծրագրավորված է"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Տեսագրման հակասություն"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Տեսագրում"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Չհաջողվեց տեսագրել"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Ծրագրերի ընթերցում"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Դիտել վերջին տեսագրությունները"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագրի տեսագրումը չի ավարտվել:"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> և <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ծրագրերի տեսագրումը չի ավարտվել:"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> և <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ծրագրերի տեսագրումը չի ավարտվել:"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագրի տեսագրումը չի ավարտվել, քանի որ հիշողությունը բավարար չէ:"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> և <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ծրագրերի տեսագրումը չի ավարտվել, քանի որ հիշողությունը բավարար չէ:"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> և <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ծրագրերի տեսագրումը չի ավարտվել, քանի որ հիշողությունը բավարար չէ:"</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR-ին ավելի շատ հիշողություն է անհրաժեշտ"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Դուք կկարողանաք տեսագրել ծրագրեր DVR-ի օգնությամբ: Սակայն այս պահին ձեր սարքում DVR-ի աշխատանքի համար անհրաժեշտ բավականաչափ հիշողություն չկա: Միացեք առնվազն <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>ԳԲ հիշողություն ունեցող արտաքին սարք և հետևեք ցուցումներին՝ այն որպես սարքի հիշողություն ձևաչափելու համար:"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Բավականաչափ հիշողություն չկա"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Այս ծրագիրը չի տեսագրվի բավականաչափ հիշողություն բացակայության պատճառով: Փորձեք ջնջել առկա տեսագրություններից մի քանիսը:"</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Հիշողությունն անհասանելի է"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Դադարեցնե՞լ տեսագրումը:"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Տեսագրված բովանդակությունը կպահվի:"</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագրի տեսագրումը կդադարեցվի, քանի որ այն ունի հակասություններ այս ծրագրի հետ: Արդեն իսկ տեսագրված բովանդակությունը կպահվի:"</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Տեսագրումը ծրագրավորվեց, սակայն այն հակասություններ ունի"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Տեսագրումը սկսվել է, սակայն որոշ հակասություններ ունի"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագիրը կտեսագրվի:"</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ալիքը տեսագրվում է:"</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ծրագրի որոշ հատվածներ չեն տեսագրվի:"</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> և <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ծրագրերի որոշ հատվածներ չեն տեսագրվի:"</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ու ևս մեկ ծրագրի որոշ հատվածներ չեն տեսագրվի:"</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="one">Some parts of <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> and %3$d more schedules will not be recorded.</item>
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ու ևս %3$d ծրագրի որոշ հատվածներ չեն տեսագրվի:</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Ի՞նչ եք ցանկանում տեսագրել:"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Նշեք տեսագրելու տևողությունը"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Արդեն ծրագրավորվել է"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Միևնույն ծրագրի տեսագրումն արդեն ծրագրավորվել է <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>-ին:"</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Արդեն տեսագրվել է"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Այս ծրագիրն արդեն տեսագրվել է: Այն հասանելի է DVR դարանում:"</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Սերիալի տեսագրումը ծրագրավորված է"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g>-ի համար ծրագրավորված է <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> տեսագրում:</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> of them will not be recorded due to conflicts.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g>-ի համար ծրագրավորված է <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> տեսագրում: Այդ տեսագրումներից <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>-ը հակասությունների պատճառով չեն կատարվի:</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodes of this series and other series will not be recorded due to conflicts.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g>-ի համար ծրագրավորված է <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> տեսագրում: Այս սերիալի <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> դրվագներ և մյուս սերիալը հակասությունների պատճառով չեն տեսագրվի:</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 episode of other series will not be recorded due to conflicts.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g>-ի համար ծրագրավորված է <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> տեսագրում: Մյուս սերիալի 1 դրվագ հակասությունների պատճառով չի տեսագրվի:</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episodes of other series will not be recorded due to conflicts.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g>-ի համար ծրագրավորված է <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> տեսագրում: Մյուս սերիալի <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> դրվագներ հակասությունների պատճառով չեն տեսագրվի:</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Տեսագրված ծրագիրը չի գտնվել:"</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Առնչվող տեսագրություններ"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="one">%1$d recordings</item>
+ <item quantity="other">%1$d տեսագրություն</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագիրը հեռացվել է տեսագրման ժամանակացույցից"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Ընդունիչների հակասությունների պատճառով կտեսագրվի մասամբ:"</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Ընդունիչների հակասությունների պատճառով չի տեսագրվի:"</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Ծրագրավորված տեսագրումներ դեռ չկան:\nՏեսագրումը կարող եք ծրագրավորել հեռուստահաղորդումների ցանկից:"</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="one">%1$d recording conflicts</item>
+ <item quantity="other">Տեսագրման %1$d հակասություն</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Սերիալների կարգավորումներ"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Սկսել սերիալի տեսագրումը"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Դադարեցնել սերիալի տեսագրումը"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Դադարեցնե՞լ սերիալի տեսագրումը:"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Տեսագրված դրվագները հասանելի կմնան միայն DVR դարանում:"</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Դադար"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Այս պահին եթեր հեռարձակվող դրվագներ չկան:"</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Հասանելի դրվագներ չկան:\nԴրանք կտեսագրվեն հասանելի դառնալուց հետո:"</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="one">(%1$d minutes)</item>
+ <item quantity="other">(%1$d րոպե)</item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Այսօր"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Վաղը"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Երեկ"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"Այսօր, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Վաղը, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Գնահատական"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Տեսագրած ծրագրեր"</string>
+</resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
deleted file mode 100644
index d10652e1..00000000
--- a/res/values-hy/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"մոնո"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"ստերեո"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Նվագարկման կառավար"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Վերջինները"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"Հեռ. ընտրանքներ"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP ընտրանքներ"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Նվագարկման կառավարներն այս ալիքում անհասանելի են"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Նվագարկել կամ դադարեցնել"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Արագ առաջանցում"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Հետանցում"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Հաջորդը"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Նախորդը"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Ծրագրի ուղեցույց"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Նոր ալիքներ"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Բացել <xliff:g id="APP_NAME">%1$s</xliff:g>-ը"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Փակ խորագրեր"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Ցուցադրման ռեժիմ"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Միացված է"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Անջատված է"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Բազմաուդիո"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Ավելացնել ալիքներ"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Կարգավորումներ"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Աղբյուր"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Փոխել"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Միացված է"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Անջատված է"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Ձայն"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Հիմնական"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP պատուհան"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Դասավորություն"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Ստորին աջ"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Վերին աջ"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Վերին ձախ"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Ստորին ձախ"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Կողք կողքի"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Չափը"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Մեծ"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Փոքր"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Աղբյուր"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"Հեռուստացույց (ալեհավաք/մալուխ)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Ծրագրի մասին տեղեկություններ չկան"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Տեղեկություն չկա"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Ալիքն արգելափակված է:"</string>
- <string name="default_language" msgid="4122326459624337928">"Անհայտ լեզու"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Փակ ենթագրեր"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Անջատված է"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Հարմարացնել ձևաչափը"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Սահմանել համակարգի խորագրերի պարամետրեր"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Ցուցադրման ռեժիմ"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Բազմաուդիո"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"Մոնո"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"Ստերեո"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 ծավալային ձայն"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 ծավալային ձայն"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d հեռուստաալիք"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Հարմարեցնել ցանկը"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Ընտրել խումբը"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Ապընտրել խումբը"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Խմբավորել"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Ալիք աղբյուրը"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Խմբավորել"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Այս ծրագիրը արգելափակված է"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Այս ծրագրի վարկանիշը <xliff:g id="RATING">%1$s</xliff:g> է"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Մուտքը ինքնասկանավարում չի աջակցում"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Չի հաջողվում սկսել «<xliff:g id="TV_INPUT">%s</xliff:g>»-ի ավտոմատ սկանավորումը"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Չհաջողվեց բացել խորագրերի համակարգի կարգավորումները:"</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="one">Ավելացվեց %1$d ալիք</item>
- <item quantity="other">Ավելացվեց %1$d ալիք</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Ալիքներ չեն ավելացվել"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Ծնողական հսկում"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Միացված է"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Անջատված է"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Արգելափակված են"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Արգելափակել բոլորը"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Ապաարգելափակել բոլորը"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Թաքնված ալիքներ"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Ծր. սահմանափակումներ"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"Փոխել PIN-ը"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Գն. համակարգեր"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Վարկանիշ"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Բոլոր գն. համակարգերը"</string>
- <string name="other_countries" msgid="8342216398676184749">"Այլ երկրներ"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Չկա"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Չկա"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Չկա"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Խիստ սահմանափակում"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Միջ. սահմանափակումներ"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Թույլ սահմանափակում"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Հատուկ"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Բովանդակությունը հարմար է երեխաների համար"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Բարձր տարիքային խմբի երեխաների համար"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Բովանդակությունը հարմար է անչափահասների համար"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Ձեռքով կարգավորման սահմանափակումներ"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s և ենթավարկանիշեր"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Ենթավարկանիշեր"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Այս ալիքը դիտելու համար մուտքագրեք PIN-ը"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Այս ծրագիրը դիտելու համա մուտքագրեք PIN-ը"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Այս ծրագիրն ունի տարիքային սահմանափակում՝ <xliff:g id="RATING">%1$s</xliff:g>: Այն դիտելու համար մուտքագրեք PIN կոդը"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"Մուտքագրեք ձեր PIN-ը"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Ծնողական վերահսկումը կարգավորելու համար PIN կոդ նախադրեք"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Մուտքագրեք նոր PIN"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"Հաստատեք ձեր PIN-ը"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Մուտքագրեք ձեր ներկայիս PIN-ը"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="one">Դուք 5 անգամ մուտքագրել եք սխալ PIN կոդ:\nՓորձեք նորից <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> վայրկյանից:</item>
- <item quantity="other">Դուք 5 անգամ մուտքագրել եք սխալ PIN կոդ:\nՓորձեք նորից <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> վայրկյանից:</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN-ը սխալ էր: Կրկին փորձեք:"</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Փորձեք կրկին, PIN-ը չի համապատասխանում"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Կարգավորումներ"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Հարմարեցնել ալիքների ցանկը"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Ընտրեք ալիքներ հեռուստահաղորդումների ծրագրի համար"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Ալիքների աղբյուրներ"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Առկա են նոր ալիքներ"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Ծնողական վերահսկողություն"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Բաց կոդով ծրագրակազմի արտոնագրեր"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Բաց կոդով ծրագրաշարի լիցենզիաներ"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Տարբերակ"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Այս կապուղին դիտելու համար սեղմեք Աջ և մուտքագրեք ձեր PIN-ը"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Այս ծրագիրը դիտելու համար սեղմեք Աջ և մուտքագրեք ձեր PIN-ը"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Այս ծրագրի վարկանիշը <xliff:g id="RATING">%1$s</xliff:g> է:\nԱյն դիտելու համար սեղմեք Աջ և մուտքագրեք PIN կոդը:"</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Այս ալիքը դիտելու համար օգտագործեք Live TV կանխադրված հավելվածը:"</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Այս հաղորդումը դիտելու համար օգտագործեք Live TV կանխադրված հավելվածը:"</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Այս հաղորդումը գնահատվել է որպես <xliff:g id="RATING">%1$s</xliff:g>:\nԱյս հաղորդումը դիտելու համար օգտագործեք Live TV կենդանի կանխադրված հավելվածը:"</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Ծրագիրն արգելափակված է"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Այս ծրագրի վարկանիշը <xliff:g id="RATING">%1$s</xliff:g> է"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Միայն ձայն"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Թույլ ազդանշան"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Համացանցի կապակցում չկա"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="one">This channel can\'t be played until <xliff:g id="END_TIME_1">%1$s</xliff:g> because other channels are being recorded. \n\nPress Right to adjust recording schedule.</item>
- <item quantity="other">Այս ալիքը հնարավոր չէ ցուցադրել մինչև <xliff:g id="END_TIME_1">%1$s</xliff:g>-ը, քանի որ ներկայումս տեսագրվում են այլ ալիքներ: \n\nՏեսագրման ժամանակացույցը կարգավորելու համար սեղմեք Աջ կոճակը:</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Անվերնագիր"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Ալիքն արգելափակված է"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Նոր"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Աղբյուրներ"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="one">%1$d ալիք</item>
- <item quantity="other">%1$d ալիք</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Ալիքներ չկան"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Նոր"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Կարգավորված չէ"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Ավելացնել այլ աղբյուրներ"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Որոնեք ուղիղ եթեր առաջարկող հավելվածներ"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Հասանելի են ալիքների նոր աղբյուրներ"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Ալիքների նոր աղբյուրները պարունակում են նոր ալիքներ:\nԿարգավորեք դրանք հիմա կամ ավելի ուշ՝ ալիքների աղբյուրների կարգավորումների միջոցով:"</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Կարգավորել հիմա"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"Լավ, հասկացա"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"Հեռուստացույցի ընտրացանկից օգտվելու համար "<b>"սեղմեք ԸՆՏՐԵԼ"</b>":"</string>
- <string name="msg_no_input" msgid="3897674146985427865">"Հեռուստացույցի մուտք չի գտնվել"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"Հեռուստացույցի մուտքը տեղադրված չէ"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP-ը չի աջակցվում"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP-ը ցուցադրելու համար աղբյուր չկա"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Կարգավորիչի մուտքը համապատասխան չէ: Գործարկեք «Ուղիղ եթեր» հավելվածը, եթե օգտագործում եք հեռուստացույցի մուտք:"</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Կարգավորումը չհաջողվեց"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Այս գործողությունը կատարելու համար ոչ մի հավելված չի գտնվել"</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Բոլոր ալիքները թաքնված են:\nԸնտրեք առնվազն մեկ ալիք:"</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Անսպասելի սխալ առաջացավ տեսանյութի ցուցադրման ժամանակ"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"«Հետ» կոճակը միացված սարքի համար է: Դուս գալու համար սեղմեք «Գլխավոր» կոճակը:"</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Հեռուստատեսային ծրագրերը կարդալու համար ուղիղ եթերին թույլտվություն է անհրաժեշտ:"</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Կարգավորեք աղբյուրները"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Ուղիղ եթերը համատեղում է ավանդական հեռուստաալիքները և հավելվածների կողմից հոսքային եղանակով հեռարձակվող ալիքները: \n\nՍկսեք արդեն իսկ տեղադրված ալիքների աղբյուրները կարգավորելուց կամ Google Play Խանութում որոնեք ուղիղ եթեր առաջարկող այլ հավելվածներ:"</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Տեսագրում և ժամանակացույցեր"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 րոպե"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 րոպե"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ժամ"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ժամ"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Վերջինները"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Ծրագրավորված"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Սերիալներ"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Այլ"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Հնարավոր չէ տեսագրել այս հեռուստաալիքը:"</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Հնարավոր չէ տեսագրել այս ծրագիրը:"</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագրի տեսագրումը ծրագրավորվեց"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագրի տեսագրում այս պահից մինչև <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Ամբողջական ժամանակացույց"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="one">Next %1$d days</item>
- <item quantity="other">%1$d օր</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="one">%1$d minutes</item>
- <item quantity="other">%1$d րոպե</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="one">%1$d new recordings</item>
- <item quantity="other">%1$d նոր տեսագրություն</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="one">%1$d recordings</item>
- <item quantity="other">%1$d տեսագրություն</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="one">%1$d recordings scheduled</item>
- <item quantity="other">Ծրագրավորվել է %1$d տեսագրություն</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Դիտել"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Նվագարկել սկզբից"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Վերսկսել նվագարկումը"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Ջնջել"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Ջնջել տեսագրությունները"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Շարունակել"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Եթերաշրջան <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Ժամանակացույց"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Կարդալ ավելին"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Ջնջել տեսագրումները"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Ընտրեք դրվագները, որոնք ցանկանում եք ջնջել: Ջնջելուց հետո դրանք այլևս հնարավոր չի լինի տեսագրել:"</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Ջնջելու համար տեսագրումներ չկան"</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Նշել դիտված դրվագները"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Նշել բոլոր դրվագները"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Ապանշել բոլոր դրվագները"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> րոպեից դիտվել է <xliff:g id="WATCHED">%1$d</xliff:g>-ը"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> վայրկյանից դիտվել է <xliff:g id="WATCHED">%1$d</xliff:g>-ը"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Երբեք չդիտված"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="one">%1$d of %2$d episodes are deleted</item>
- <item quantity="other">%2$d դրվագներից %1$d-ը ջնջվել է</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Առաջնահերթություն"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Ամենաբարձր"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Ամենացածր"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Ոչ: <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Հեռուստաալիքներ"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Ցանկացած"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Ընտրեք առաջնահերթությունը"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Եթե միաժամանակ ծրագրավորված է չափազանց շատ ծրագրերի տեսագրում, ապա կտեսագրվեն միայն բարձր առաջնահերթություն ունեցող ծրագրերը:"</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Պահել"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Միանգամյա տեսագրումն ունի ամենաբարձր առաջնահերթությունը"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Չեղարկել"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Չեղարկել"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Մոռանալ"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Դադար"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Դիտել տեսագրման ժամանակացույցը"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Միայն այս ծրագիրը"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"այժմ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Ամբողջ սերիալը…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Ծրագրավորել"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Փոխարենը տեսագրել այս ծրագիրը"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Չեղարկել այս տեսագրումը"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Դիտել հիմա"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Հնարավոր է տեսագրել"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Տեսագրումը ծրագրավորված է"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Տեսագրման հակասություն"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Տեսագրում"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Չհաջողվեց տեսագրել"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Ծրագրերի ընթերցում՝ տեսագրության ժամանակացույցեր ստեղծելու համար"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Ծրագրերի ընթերցում"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR-ին ավելի շատ հիշողություն է անհրաժեշտ"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Դուք կկարողանաք տեսագրել ծրագրեր DVR-ի օգնությամբ: Սակայն այս պահին ձեր սարքում DVR-ի աշխատանքի համար անհրաժեշտ բավականաչափ հիշողություն չկա: Միացեք առնվազն <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>ԳԲ հիշողություն ունեցող արտաքին սարք և հետևեք ցուցումներին՝ այն որպես սարքի հիշողություն ձևաչափելու համար:"</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Հիշողությունն անհասանելի է"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR-ի կողմից օգտագործվող հիշողության մի մասն անհասանելի է: DVR-ը կրկին ակտիվացնելու համար միացրեք նախկինում օգտագործված արտաքին սարքը: Կարող եք նաև մոռանալ հիշողությունը, եթե այն այևս հասանելի չէ:"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Մոռանա՞լ հիշողությունը:"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Ձեր տեսագրած ամբողջ բովանդակությունը և ժամանակացույցները չեն պահվի:"</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Դադարեցնե՞լ տեսագրումը:"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Տեսագրված բովանդակությունը կպահվի:"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Տեսագրումը ծրագրավորվեց, սակայն այն հակասություններ ունի"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Տեսագրումը սկսվել է, սակայն որոշ հակասություններ ունի"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագիրը կտեսագրվի:"</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ալիքը տեսագրվում է:"</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ծրագրի որոշ հատվածներ չեն տեսագրվի:"</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> և <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ծրագրերի որոշ հատվածներ չեն տեսագրվի:"</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ու ևս մեկ ծրագրի որոշ հատվածներ չեն տեսագրվի:"</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="one">Some parts of <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> and %3$d more schedules will not be recorded.</item>
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ու ևս %3$d ծրագրի որոշ հատվածներ չեն տեսագրվի:</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Ի՞նչ եք ցանկանում տեսագրել:"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Նշեք տեսագրելու տևողությունը"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Արդեն ծրագրավորվել է"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Միևնույն ծրագրի տեսագրումն արդեն ծրագրավորվել է <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>-ին:"</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Արդեն տեսագրվել է"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Այս ծրագիրն արդեն տեսագրվել է: Այն հասանելի է DVR դարանում:"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Տեսագրված ծրագիրը չի գտնվել:"</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Առնչվող տեսագրություններ"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Ծրագիրը նկարագրություն չունի)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="one">%1$d recordings</item>
- <item quantity="other">%1$d տեսագրություն</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ծրագիրը հեռացվել է տեսագրման ժամանակացույցից"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Ընդունիչների հակասությունների պատճառով կտեսագրվի մասամբ:"</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Ընդունիչների հակասությունների պատճառով չի տեսագրվի:"</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Ծրագրավորված տեսագրումներ դեռ չկան:\nՏեսագրումը կարող եք ծրագրավորել հեռուստահաղորդումների ցանկից:"</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="one">%1$d recording conflicts</item>
- <item quantity="other">Տեսագրման %1$d հակասություն</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Սերիալների կարգավորումներ"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Սկսել սերիալի տեսագրումը"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Դադարեցնել սերիալի տեսագրումը"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Դադարեցնե՞լ սերիալի տեսագրումը:"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Տեսագրված դրվագները հասանելի կմնան միայն DVR դարանում:"</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Դադար"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Հասանելի դրվագներ չկան:\nԴրանք կտեսագրվեն հասանելի դառնալուց հետո:"</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="one">(%1$d minutes)</item>
- <item quantity="other">(%1$d րոպե)</item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Այսօր"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Վաղը"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Երեկ"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"Այսօր, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Վաղը, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Գնահատական"</string>
-</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 662cfc89..33cca968 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Kontrol pemutar"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Saluran terkini"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Saluran"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Opsi TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opsi PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Kontrol Play tidak tersedia untuk saluran ini"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Putar atau jeda"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Maju cepat"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Teks"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Mode tayang"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Aktif"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Nonaktif"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Dapatkan saluran lain"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Setelan"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Sumber"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Tukar"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Aktif"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Nonaktif"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Suara"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Utama"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Jendela PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Tata letak"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Kanan bawah"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Kanan atas"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Kiri atas"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Kiri bawah"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Berdampingan"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Ukuran"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Besar"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Kecil"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Sumber masukan"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/kabel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Tidak ada informasi program"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Tidak ada informasi"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Saluran yang diblokir"</string>
- <string name="default_language" msgid="4122326459624337928">"Bahasa tidak dikenal"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Bahasa tidak dikenal"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Subtitel, CC %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Teks"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Nonaktif"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Sesuaikan format"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Kelompokkan menurut"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Program ini diblokir"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Program ini tidak memiliki nilai"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Program ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Masukan tidak mendukung pemindaian otomatis"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Tidak dapat memulai pemindaian otomatis untuk \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d saluran ditambahkan</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Tidak ditambahkan saluran"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Kontrol induk"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Aktif"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Nonaktif"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Negara lain"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Tidak ada"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Tidak ada"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Tanpa nilai"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blokir program tanpa nilai"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Tidak ada"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Pembatasan tinggi"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Pembatasan menengah"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Masukkan PIN untuk menonton saluran ini"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Masukkan PIN untuk menonton program ini"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Program ini memiliki rating <xliff:g id="RATING">%1$s</xliff:g>. Masukkan PIN untuk menonton program ini"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Program ini tidak memiliki nilai. Masukkan PIN untuk menonton program ini"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Masukkan PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Untuk menyetel kontrol induk, buat PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Masukkan PIN baru"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"PIN salah. Coba lagi."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Pin tidak cocok, coba lagi"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Memasukkan Kode Pos"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Aplikasi Live TV akan menggunakan Kode Pos untuk memberikan panduan program lengkap bagi saluran TV."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Masukkan Kode Pos"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Kode ZIP Tidak Valid"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Setelan"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Sesuaikan daftar saluran"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Pilih saluran untuk panduan program"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Sumber saluran"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Tersedia saluran baru"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Kontrol induk"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Lisensi sumber terbuka"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Lisensi sumber terbuka"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Pergantian waktu"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Rekam sambil menonton sehingga Anda dapat menjeda atau memutar ulang program live.\nPeringatan: Tindakan ini menggunakan penyimpanan secara intensif sehingga dapat mengurangi masa pakai penyimpanan internal."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Lisensi open source"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Kirim masukan"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versi"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Untuk menonton saluran ini, tekan Kanan dan masukkan PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Untuk menonton program ini, tekan Kanan dan masukkan PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Program ini tidak memiliki nilai.\nUntuk menonton program ini, tekan Kanan lalu masukkan PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Program ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>.\nUntuk menonton program ini, tekan Panah Kanan dan masukkan PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Untuk menonton saluran ini, gunakan aplikasi TV Siaran Langsung default."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Untuk menonton program ini, gunakan aplikasi TV Siaran Langsung default."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Program ini tidak memiliki nilai.\nUntuk menonton program ini, gunakan aplikasi TV Siaran Langsung default."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Program ini memiliki rating <xliff:g id="RATING">%1$s</xliff:g>.\nUntuk menonton program ini, gunakan aplikasi TV Siaran Langsung default."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Program diblokir"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Program ini tidak memiliki nilai"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Program ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audio saja"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Sinyal lemah"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Tekan PILIH"</b>" untuk mengakses menu TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Tidak ditemukan masukan TV"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Tidak dapat menemukan masukan TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP tidak didukung"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Tidak tersedia masukan yang dapat ditampilkan dengan PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Jenis tuner tidak cocok. Luncurkan aplikasi Saluran Siaran Langsung untuk masukan TV yang sesuai dengan jenis tuner"</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Penalaan gagal"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Tidak ditemukan aplikasi untuk menangani tindakan ini."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d jadwal rekaman</item>
<item quantity="one">%1$d jadwal rekaman</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Batalkan rekaman"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Berhenti merekam"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Tonton"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Putar dari awal"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Lanjutkan pemutaran"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Jika terlalu banyak program yang akan direkam secara bersamaan, hanya program dengan prioritas lebih tinggi yang akan direkam."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Simpan"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Perekaman satu kali memiliki prioritas tertinggi"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Batal"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Batal"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Lupakan"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Berhenti"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Lihat jadwal rekaman"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Program tunggal ini"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Rekam yang ini saja"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Batalkan rekaman ini"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Tonton sekarang"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Hapus rekaman…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Dapat direkam"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Perekaman dijadwalkan"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Perekaman bentrok"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Merekam"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Rekaman gagal"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Membaca program untuk membuat jadwal rekaman"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Membaca program"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Membaca program"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Lihat rekaman baru-baru ini"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Rekaman <xliff:g id="PROGRAMNAME">%1$s</xliff:g> tidak selesai."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Rekaman <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> dan <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> tidak selesai."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Rekaman <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, dan <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> tidak selesai."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Rekaman <xliff:g id="PROGRAMNAME">%1$s</xliff:g> tidak selesai karena penyimpanan tidak mencukupi."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Rekaman <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> dan <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> tidak selesai karena penyimpanan tidak mencukupi."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Rekaman <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, dan <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> tidak selesai karena penyimpanan tidak mencukupi."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR memerlukan penyimpanan ekstra"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Anda akan dapat merekam program dengan DVR. Namun, saat ini penyimpanan pada perangkat tidak cukup untuk menjalankan DVR. Hubungkan drive eksternal berukuran <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB atau lebih besar dan ikuti langkah untuk memformat drive tersebut sebagai perangkat penyimpanan."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Anda akan dapat merekam program dengan DVR. Namun, saat ini penyimpanan pada perangkat tidak cukup untuk menjalankan DVR. Hubungkan drive eksternal berukuran <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB atau lebih besar dan ikuti langkah untuk memformat drive tersebut sebagai perangkat penyimpanan."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Penyimpanan tidak cukup"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Program ini tidak akan direkam karena penyimpanan tidak cukup. Coba menghapus beberapa rekaman yang ada."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Penyimpanan tidak ada"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Beberapa penyimpanan yang digunakan oleh DVR tidak ada. Hubungkan drive eksternal yang sebelumnya digunakan untuk kembali mengaktifkan DVR. Atau, Anda dapat memilih untuk melupakan penyimpanan jika sudah tidak tersedia."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Lupakan penyimpanan?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Semua konten dan jadwal yang direkam akan hilang."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Berhenti merekam?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Konten yang direkam akan disimpan."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Perekaman <xliff:g id="PROGRAMNAME">%1$s</xliff:g> akan dihentikan karena bentrok dengan program ini. Konten yang direkam akan disimpan."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Rekaman telah dijadwalkan, tapi jadwalnya bentrok"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Rekaman telah dimulai, namun jadwalnya bentrok"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> akan direkam."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Program yang sama telah dijadwalkan untuk direkam pukul <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Sudah direkam"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Program ini telah direkam. Rekaman ada di pustaka DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Perekaman serial dijadwalkan"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> rekaman telah dijadwalkan untuk <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> rekaman telah dijadwalkan untuk <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> rekaman telah dijadwalkan untuk <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> rekaman tersebut tidak akan direkam karena jadwalnya bentrok.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> rekaman telah dijadwalkan untuk <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Rekaman tersebut tidak akan direkam karena jadwalnya bentrok.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> rekaman telah dijadwalkan untuk <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episode seri ini dan seri lainnya tidak akan direkam karena jadwalnya bentrok.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> rekaman telah dijadwalkan untuk <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episode seri ini dan seri lainnya tidak akan direkam karena jadwalnya bentrok.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> rekaman telah dijadwalkan untuk <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 episode seri lainnya tidak akan direkam karena jadwalnya bentrok.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> rekaman telah dijadwalkan untuk <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 episode seri lainnya tidak akan direkam karena jadwalnya bentrok.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> rekaman telah dijadwalkan untuk <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episode seri lainnya tidak akan direkam karena jadwalnya bentrok.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> rekaman telah dijadwalkan untuk <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episode seri lainnya tidak akan direkam karena jadwalnya bentrok.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Tidak ditemukan program yang direkam."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Rekaman terkait"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Tidak ada deskripsi program)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d rekaman</item>
<item quantity="one">%1$d rekaman</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Hentikan rekaman seri?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Episode yang direkam akan tetap tersedia di pustaka DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Hentikan"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Tidak ada episode tayang sekarang."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Tidak ada episode yang tersedia.\nEpisode akan direkam setelah tersedia."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d menit)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> hari ini"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> besok"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Skor"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Program yang Direkam"</string>
</resources>
diff --git a/res/values-is-v23/strings.xml b/res/values-is-rIS-v23/strings.xml
index 2954d77b..2954d77b 100644
--- a/res/values-is-v23/strings.xml
+++ b/res/values-is-rIS-v23/strings.xml
diff --git a/res/values-is/arrays.xml b/res/values-is-rIS/arrays.xml
index 27cb8655..27cb8655 100644
--- a/res/values-is/arrays.xml
+++ b/res/values-is-rIS/arrays.xml
diff --git a/res/values-is/rating_system_strings.xml b/res/values-is-rIS/rating_system_strings.xml
index 1725d040..1725d040 100644
--- a/res/values-is/rating_system_strings.xml
+++ b/res/values-is-rIS/rating_system_strings.xml
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
new file mode 100644
index 00000000..99e84596
--- /dev/null
+++ b/res/values-is-rIS/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"einóma"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"víðóma"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Spilunarstýringar"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Rásir"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"Sjónvarpskostir"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Spilunarstýringar eru ekki í boði fyrir þessa rás"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Spila eða gera hlé"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Spóla áfram"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Spóla til baka"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Áfram"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Til baka"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Dagskrárvísir"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Nýjar rásir í boði"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Opna <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Skjátextar"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Birtingarstill."</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"Innfelld mynd"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-Audio"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Fá fleiri rásir"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Stillingar"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"Sjónvarp (loftnet/kapall)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Engar dagskrárupplýsingar"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Engar upplýsingar"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Læst rás"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Óþekkt tungumál"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Skjátexti %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Skjátextar"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Slökkt"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Sérstilla snið"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Stilla skjátextaval fyrir allt kerfið"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Birtingarstilling"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multi-Audio"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"einóma"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"víðóma"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 surround"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 surround"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d rásir"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Sérsníða rásalista"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Velja hóp"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Taka val af hóp"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Flokka eftir"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Inntak rása"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"Háskerpa/staðalgæði"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Háskerpa"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Staðalgæði"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Flokka eftir"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Þessi dagskrárliður er læstur"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Þessi þáttur er óflokkaður"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Þessi dagskrárliður er flokkaður sem <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Inntakið styður ekki sjálfvirka skönnun"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Ekki tókst að hefja sjálfvirka skönnun fyrir „<xliff:g id="TV_INPUT">%s</xliff:g>“"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Ekki er hægt að opna skjátextastillingar fyrir kerfið allt."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d rás bætt við</item>
+ <item quantity="other">%1$d rásum bætt við</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Engum rásum bætt við"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Foreldraeftirlit"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Kveikt"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Slökkt"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Útilokaðar rásir"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Útiloka allar"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Opna allar"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Faldar rásir"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Aldurstakmark"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"Breyta PIN-númeri"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Flokkunarkerfi"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Flokkun"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Sjá flokkunarkerfi"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Önnur lönd"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Engin"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ekkert"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Óflokkað"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Útiloka þætti án flokkunar"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Ekkert"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Miklar takmarkanir"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Miðlungs takmarkanir"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Litlar takmarkanir"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Sérsniðið"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Efni sem hentar fyrir börn"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Efni sem hentar eldri börnum"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Efni sem hentar fyrir unglinga"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Handstillt aldurstakmark"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s og undirflokkar"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Undirflokkar"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Sláðu inn PIN-númerið til að horfa á þessa rás"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Sláðu inn PIN-númerið til að horfa á þennan þátt"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Þessi þáttur er flokkaður sem <xliff:g id="RATING">%1$s</xliff:g>. Sláðu inn PIN-númerið til að horfa á þáttinn"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Þessi þáttur er óflokkaður. Sláðu inn PIN-númerið til að horfa á þáttinn"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"Sláðu inn PIN-númerið"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Til að stilla foreldraeftirlit skaltu búa til PIN-númer"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Sláðu inn nýtt PIN-númer"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"Staðfestu PIN-númerið"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Sláðu inn núverandi PIN-númerið þitt"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Þú slóst fimm sinnum inn rangt PIN-númer.\nReyndur aftur eftir <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekúndu.</item>
+ <item quantity="other">Þú slóst fimm sinnum inn rangt PIN-númer.\nReyndur aftur eftir <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekúndur.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"Rangt PIN-númer. Reyndu aftur."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Reyndu aftur; PIN-númerin stemma ekki"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Sláðu inn póstnúmerið þitt."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Forritið Beinar útsendingar notar póstnúmerið þitt til að veita þér nákvæma sjónvarpsdagskrá."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Sláðu inn póstnúmerið þitt"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Ógilt póstnúmer"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Stillingar"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Sérsníða rásalista"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Veldu rásir fyrir dagskrárvísinn þinn"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Inntak rása"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nýjar rásir í boði"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Foreldraeftirlit"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Tímabreyting"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Taktu upp á meðan þú horfir svo þú getir gert hlé eða spólað til baka á útsendingu í beinni.\nViðvörun: Þetta getur dregið úr líftíma innbyggðrar geymslu vegna mikillar notkunar."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Leyfi opins kóða"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Senda ábendingu"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Útgáfa"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Til að horfa á þessa rás skaltu ýta til hægri og slá inn PIN-númerið þitt"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Til að horfa á þennan þátt skaltu ýta til hægri og slá inn PIN-númerið þitt"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Þessi þáttur er óflokkaður.\nTil að horfa á þennan þátt skaltu ýta til hægri og slá inn PIN-númerið"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Þessi þáttur er flokkaður sem <xliff:g id="RATING">%1$s</xliff:g>.\nTil að horfa á þáttinn skaltu ýta til hægri og slá inn PIN-númerið þitt."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Til að horfa á þessa rás skaltu nota sjálfgefna forritið fyrir sjónvarp í beinni útsendingu."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Til að horfa á þennan þátt skaltu nota sjálfgefna forritið fyrir sjónvarp í beinni útsendingu."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Þessi þáttur er óflokkaður.\nTil að horfa á þennan þátt skaltu nota sjálfgefna forritið fyrir sjónvarp í beinni útsendingu."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Þessi þáttur er flokkaður sem <xliff:g id="RATING">%1$s</xliff:g>.\nTil að horfa á þennan þátt skaltu nota sjálfgefna forritið fyrir sjónvarp í beinni útsendingu."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Þátturinn er læstur"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Þessi þáttur er óflokkaður"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Þessi dagskrárliður er flokkaður sem <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Aðeins hljóð"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Lítill sendistyrkur"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Engin nettenging"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="one">Ekki er hægt að spila þessa rás fyrr en <xliff:g id="END_TIME_1">%1$s</xliff:g> þar sem verið er að taka upp aðrar rásir. \n\nÝttu á hægri takkann til að breyta upptökuáætluninni.</item>
+ <item quantity="other">Ekki er hægt að spila þessa rás fyrr en <xliff:g id="END_TIME_1">%1$s</xliff:g> þar sem verið er að taka upp aðrar rásir. \n\nÝttu á hægri takkann til að breyta upptökuáætluninni.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Ekkert heiti"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Rás læst"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Ný"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Veitur"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d rás</item>
+ <item quantity="other">%1$d rásir</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Engar rásir í boði"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Nýtt"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Ekki uppsett"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Sækja fleiri veitur"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Skoða forrit sem bjóða upp á beinar útsendingar"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Nýjar sjónvarpsveitur í boði"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Nýjum sjónvarpsveitum fylgja nýjar sjónvarpsrásir.\nSettu þær upp núna eða gerðu það síðar í stillingunum fyrir inntak rása."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Setja upp núna"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Ég skil"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>"Ýttu á VELJA"</b>" til að fá aðgang að sjónvarpsvalmyndinni."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"Ekkert sjónvarpsinntak fannst"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"Sjónvarpsinntak finnst ekki"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Gerð móttakara passar ekki. Ræstu forritið Rásir í beinni til að fá sjónvarpsinntak með móttakaragerð."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Stilling mistókst"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Ekkert forrit fannst sem getur framkvæmt þessa aðgerð."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Allar inntaksrásir eru faldar.\nVeldu minnst eina rás til að horfa á."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Myndskeiðið er óvænt ekki tiltækt"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"Til baka-lykillinn er fyrir tengd tæki. Ýttu á heimahnappinn til að hætta."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Rásir í beinni þurfa heimild til að lesa sjónvarpsdagskrána."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Setja upp inntök rása"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Beinar útsendingar sameina þá upplifun að horfa á venjulegar sjónvarpsstöðvar og straumspila rásir í gegnum forrit. \n\nByrjaðu á því að setja upp þau inntök rása sem þegar hafa verið sótt eða farðu í Google Play Store til að skoða fleiri forrit sem bjóða upp á beinar útsendingar."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Upptökur og áætlanir"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 mínútur"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 mínútur"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 klukkustund"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 klukkustundir"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Nýlegt"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Áætlað"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Þáttaröð"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Annað"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Ekki er hægt að taka upp rásina."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Ekki er hægt að taka upp dagskrárliðinn."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> var sett á upptökuáætlun"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Tekur upp <xliff:g id="PROGRAMNAME">%1$s</xliff:g> núna og þangað til <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Heildaráætlun"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="one">Næsti %1$d dagur</item>
+ <item quantity="other">Næstu %1$d dagar</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="one">%1$d mínúta</item>
+ <item quantity="other">%1$d mínútur</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="one">%1$d ný upptaka</item>
+ <item quantity="other">%1$d nýjar upptökur</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="one">%1$d upptaka</item>
+ <item quantity="other">%1$d upptökur</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="one">%1$d upptaka á áætlun</item>
+ <item quantity="other">%1$d upptökur á áætlun</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Hætta við upptöku"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Stöðva upptöku"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Horfa"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Spila frá upphafi"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Halda spilun áfram"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Eyða"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Eyða upptökum"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Halda áfram"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Þáttaröð <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Skoða dagskrá"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Lesa meira"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Eyða upptökum"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Veldu þætti sem þú vilt eyða. Ekki er hægt að endurheimta þætti eftir að þeim hefur verið eytt."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Engar upptökur til að eyða"</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Velja þætti sem horft var á"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Velja alla þætti"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Hætta við val á öllum þáttum"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"Horft á <xliff:g id="WATCHED">%1$d</xliff:g> af <xliff:g id="DURATION">%2$d</xliff:g> mínútum"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"Horft á <xliff:g id="WATCHED">%1$d</xliff:g> af <xliff:g id="DURATION">%2$d</xliff:g> sekúndum"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Aldrei horft á"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="one">%1$d af %2$d þætti er eytt</item>
+ <item quantity="other">%1$d af %2$d þáttum er eytt</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Forgangur"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Mestur"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Mjög lítill"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Nei. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Stöðvar"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Hvað sem er"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Veldu forgang"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Þegar taka á upp of marga þætti á sama tíma eru aðeins þættir sem eru í forgangi teknir upp."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Vista"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Stakar upptökur hafa forgang"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Stöðva"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Skoða upptökuáætlun"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Bara þennan þátt"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"núna – <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Alla þáttaröðina…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Setja samt á áætlun"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Taka þetta upp í staðinn"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Hætta við þessa upptöku"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Horfa núna"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Eyða upptökum…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Hægt að taka upp"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Upptaka sett á áætlun"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Skarast á við aðra upptöku"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Upptaka í gangi"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Upptaka mistókst"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Skoðar þætti"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Skoða nýlegar upptökur"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Upptöku á <xliff:g id="PROGRAMNAME">%1$s</xliff:g> er ekki lokið."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Upptöku á <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> og <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> er ekki lokið."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Upptöku á <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> og <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> er ekki lokið."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Skortur á geymslurými kom í veg fyrir að upptöku á <xliff:g id="PROGRAMNAME">%1$s</xliff:g> væri lokið."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Skortur á geymslurými kom í veg fyrir að upptöku á <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> og <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> væri lokið."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Skortur á geymslurými kom í veg fyrir að upptöku á <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> og <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> væri lokið."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR þarf meira geymslupláss"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Þú getur tekið upp þætti með stafræna upptökubúnaðinum (DVR). Hins vegar er ekki nóg geymslupláss til staðar á tækinu þínu sem stendur til að DVR virki. Tengdu utanáliggjandi disk við tækið sem er <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB eða stærri og fylgdu skrefunum til að setja það upp sem geymslupláss tækisins."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Of lítið geymslurými"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Þátturinn verður ekki tekinn upp þar sem of lítið geymslurými er til staðar. Prófaðu að eyða einhverjum af þeim upptökum sem eru þegar til staðar."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Geymslu vantar"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Stöðva upptöku?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Upptökur á efni verða vistaðar."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Upptöku á <xliff:g id="PROGRAMNAME">%1$s</xliff:g> verður hætt þar sem það skarast á við þennan þátt. Upptekið efni verður vistað."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Upptaka á áætlun en skarast við aðra"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Upptaka er hafin en hún skarast við aðra"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> verður tekið upp."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"Upptaka í gangi á <xliff:g id="CHANNELNAME">%1$s</xliff:g>."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Einhverjir hlutar af <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> verða ekki teknir upp."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Einhverjir hlutar af <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> og <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> verða ekki teknir upp."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Einhverjir hlutar af <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> og einu dagskráratriði í viðbót verða ekki teknir upp."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="one">Einhverjir hlutar af <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> og %3$d í viðbót verða ekki teknir upp.</item>
+ <item quantity="other">Einhverjir hlutar af <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> og %3$d í viðbót verða ekki teknir upp.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Hvað viltu taka upp?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Hversu lengi viltu taka upp?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Þegar áætlað"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Sami þáttur er þegar á upptökuáætlun kl. <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Þegar tekið upp"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Þessi þáttur hefur þegar verið tekinn upp. Hann er tiltækur í DVR-safninu."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Upptaka þáttaseríu sett á áætlun"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> upptaka var sett á áætlun fyrir <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> upptökur voru settar á áætlun fyrir <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> upptökur voru settar á áætlun fyrir <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> verður ekki tekið upp því að það skarast á við annað.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> upptökur voru settar á áætlun fyrir <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> verður ekki tekið upp því að það skarast á við annað.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> upptaka var sett á áætlun fyrir <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> þættir úr þessari þáttaröð og í öðrum þáttaröðum verða ekki teknir upp því það skarast á við annað.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> upptökur voru settar á áætlun fyrir <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> þættir úr þessari þáttaröð og í öðrum þáttaröðum verða ekki teknir upp því það skarast á við annað.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> upptaka var sett á áætlun fyrir <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Einn þáttur í annarri þáttaröð verður ekki tekinn upp því að hann skarast á við annað.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> upptökur voru settar á áætlun fyrir <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Einn þáttur í annarri þáttaröð verður ekki tekinn upp því að hann skarast á við annað.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> upptaka var sett á áætlun fyrir <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> þættir úr annarri þáttaröð verða ekki teknir upp því þeir skarast á við annað.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> upptökur voru settar á áætlun fyrir <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> þættir úr annarri þáttaröð verða ekki teknir upp því þeir skarast á við annað.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Upptekinn þáttur fannst ekki."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Tengdar upptökur"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="one">%1$d upptaka</item>
+ <item quantity="other">%1$d upptökur</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> fjarlægt úr upptökuáætlun"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Verður tekið upp að hluta til vegna árekstra við stilli."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Verður ekki tekið upp vegna árekstra við stilli."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Engar upptökur eru á áætlun enn sem komið er.\nÞú getur bætt upptöku við áætlun í dagskrárvísinum."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="one">%1$d árekstur í upptöku</item>
+ <item quantity="other">%1$d árekstrar í upptöku</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Þáttaraðastillingar"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Hefja upptöku á þáttaröð"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Hætta upptöku á þáttaröð"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Hætta upptöku á þáttaröð?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Upptökur af þáttum verða áfram tiltækar í DVR-safninu."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Stöðva"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Ekki er verið að sýna þætti að svo stöddu."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Engir þættir eru tiltækir.\nÞeir verða teknir upp þegar þeir eru tiltækir."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="one">(%1$d mínúta)</item>
+ <item quantity="other">(%1$d mínútur)</item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Í dag"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Á morgun"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Í gær"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> í dag"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> á morgun"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Einkunn"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Upptökur af þáttum"</string>
+</resources>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
deleted file mode 100644
index 6111b578..00000000
--- a/res/values-is/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"einóma"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"víðóma"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Spilunarstýringar"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Nýlegar rásir"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"Sjónvarpskostir"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Innfelld mynd"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Spilunarstýringar eru ekki í boði fyrir þessa rás"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Spila eða gera hlé"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Spóla áfram"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Spóla til baka"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Áfram"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Til baka"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Dagskrárvísir"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Nýjar rásir í boði"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Opna <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Skjátextar"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Birtingarstill."</string>
- <string name="options_item_pip" msgid="3951350386626879645">"Innfelld mynd"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Kveikt"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Slökkt"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-Audio"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Fá fleiri rásir"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Stillingar"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Inntak"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Víxla"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Kveikt"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Slökkt"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Hljóð"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Aðalgluggi"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Innfelling"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Útlit"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Neðst til hægri"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Efst til hægri"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Efst til vinstri"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Neðst til vinstri"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Hlið við hlið"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Stærð"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Stór"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Lítil"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Inntak"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"Sjónvarp (loftnet/kapall)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Engar dagskrárupplýsingar"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Engar upplýsingar"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Læst rás"</string>
- <string name="default_language" msgid="4122326459624337928">"Óþekkt tungumál"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Skjátextar"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Slökkt"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Sérstilla snið"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Stilla skjátextaval fyrir allt kerfið"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Birtingarstilling"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multi-Audio"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"einóma"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"víðóma"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 surround"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 surround"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d rásir"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Sérsníða rásalista"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Velja hóp"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Taka val af hóp"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Flokka eftir"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Inntak rása"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"Háskerpa/staðalgæði"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"Háskerpa"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Staðalgæði"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Flokka eftir"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Þessi dagskrárliður er læstur"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Þessi dagskrárliður er flokkaður sem <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Inntakið styður ekki sjálfvirka skönnun"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Ekki tókst að hefja sjálfvirka skönnun fyrir „<xliff:g id="TV_INPUT">%s</xliff:g>“"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Ekki er hægt að opna skjátextastillingar fyrir kerfið allt."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="one">%1$d rás bætt við</item>
- <item quantity="other">%1$d rásum bætt við</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Engum rásum bætt við"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Stillir"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Foreldraeftirlit"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Kveikt"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Slökkt"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Útilokaðar rásir"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Útiloka allar"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Opna allar"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Faldar rásir"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Aldurstakmark"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"Breyta PIN-númeri"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Flokkunarkerfi"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Flokkun"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Sjá flokkunarkerfi"</string>
- <string name="other_countries" msgid="8342216398676184749">"Önnur lönd"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Engin"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ekkert"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Ekkert"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Miklar takmarkanir"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Miðlungs takmarkanir"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Litlar takmarkanir"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Sérsniðið"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Efni sem hentar fyrir börn"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Efni sem hentar eldri börnum"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Efni sem hentar fyrir unglinga"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Handstillt aldurstakmark"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s og undirflokkar"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Undirflokkar"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Sláðu inn PIN-númerið til að horfa á þessa rás"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Sláðu inn PIN-númerið til að horfa á þennan þátt"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Þessi þáttur er flokkaður sem <xliff:g id="RATING">%1$s</xliff:g>. Sláðu inn PIN-númerið til að horfa á þáttinn"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"Sláðu inn PIN-númerið"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Til að stilla foreldraeftirlit skaltu búa til PIN-númer"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Sláðu inn nýtt PIN-númer"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"Staðfestu PIN-númerið"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Sláðu inn núverandi PIN-númerið þitt"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="one">Þú slóst fimm sinnum inn rangt PIN-númer.\nReyndur aftur eftir <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekúndu.</item>
- <item quantity="other">Þú slóst fimm sinnum inn rangt PIN-númer.\nReyndur aftur eftir <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekúndur.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"Rangt PIN-númer. Reyndu aftur."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Reyndu aftur; PIN-númerin stemma ekki"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Stillingar"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Sérsníða rásalista"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Veldu rásir fyrir dagskrárvísinn þinn"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Inntak rása"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nýjar rásir í boði"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Foreldraeftirlit"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Leyfi opins kóða"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Leyfi opins kóða"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Útgáfa"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Til að horfa á þessa rás skaltu ýta til hægri og slá inn PIN-númerið þitt"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Til að horfa á þennan þátt skaltu ýta til hægri og slá inn PIN-númerið þitt"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Þessi þáttur er flokkaður sem <xliff:g id="RATING">%1$s</xliff:g>.\nTil að horfa á þáttinn skaltu ýta til hægri og slá inn PIN-númerið þitt."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Til að horfa á þessa rás skaltu nota sjálfgefna forritið fyrir sjónvarp í beinni útsendingu."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Til að horfa á þennan þátt skaltu nota sjálfgefna forritið fyrir sjónvarp í beinni útsendingu."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Þessi þáttur er flokkaður sem <xliff:g id="RATING">%1$s</xliff:g>.\nTil að horfa á þennan þátt skaltu nota sjálfgefna forritið fyrir sjónvarp í beinni útsendingu."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Þátturinn er læstur"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Þessi dagskrárliður er flokkaður sem <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Aðeins hljóð"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Lítill sendistyrkur"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Engin nettenging"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="one">Ekki er hægt að spila þessa rás fyrr en <xliff:g id="END_TIME_1">%1$s</xliff:g> þar sem verið er að taka upp aðrar rásir. \n\nÝttu á hægri takkann til að breyta upptökuáætluninni.</item>
- <item quantity="other">Ekki er hægt að spila þessa rás fyrr en <xliff:g id="END_TIME_1">%1$s</xliff:g> þar sem verið er að taka upp aðrar rásir. \n\nÝttu á hægri takkann til að breyta upptökuáætluninni.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Ekkert heiti"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Rás læst"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Ný"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Veitur"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="one">%1$d rás</item>
- <item quantity="other">%1$d rásir</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Engar rásir í boði"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Nýtt"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Ekki uppsett"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Sækja fleiri veitur"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Skoða forrit sem bjóða upp á beinar útsendingar"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Nýjar sjónvarpsveitur í boði"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Nýjum sjónvarpsveitum fylgja nýjar sjónvarpsrásir.\nSettu þær upp núna eða gerðu það síðar í stillingunum fyrir inntak rása."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Setja upp núna"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"Ég skil"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307"><b>"Ýttu á VELJA"</b>" til að fá aðgang að sjónvarpsvalmyndinni."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"Ekkert sjónvarpsinntak fannst"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"Sjónvarpsinntak finnst ekki"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Ekki er stuðningur við innfellda mynd"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Ekkert inntak er fyrir hendi til að nota í innfelldri mynd"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Gerð móttakara passar ekki. Ræstu forritið Rásir í beinni til að fá sjónvarpsinntak með móttakaragerð."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Stilling mistókst"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Ekkert forrit fannst sem getur framkvæmt þessa aðgerð."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Allar inntaksrásir eru faldar.\nVeldu minnst eina rás til að horfa á."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Myndskeiðið er óvænt ekki tiltækt"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"Til baka-lykillinn er fyrir tengd tæki. Ýttu á heimahnappinn til að hætta."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Rásir í beinni þurfa heimild til að lesa sjónvarpsdagskrána."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Setja upp inntök rása"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Beinar útsendingar sameina þá upplifun að horfa á venjulegar sjónvarpsstöðvar og straumspila rásir í gegnum forrit. \n\nByrjaðu á því að setja upp þau inntök rása sem þegar hafa verið sótt eða farðu í Google Play Store til að skoða fleiri forrit sem bjóða upp á beinar útsendingar."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Upptökur og áætlanir"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 mínútur"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 mínútur"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 klukkustund"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 klukkustundir"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Nýlegt"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Áætlað"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Þáttaröð"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Annað"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Ekki er hægt að taka upp rásina."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Ekki er hægt að taka upp dagskrárliðinn."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> var sett á upptökuáætlun"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Tekur upp <xliff:g id="PROGRAMNAME">%1$s</xliff:g> núna og þangað til <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Heildaráætlun"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="one">Næsti %1$d dagur</item>
- <item quantity="other">Næstu %1$d dagar</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="one">%1$d mínúta</item>
- <item quantity="other">%1$d mínútur</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="one">%1$d ný upptaka</item>
- <item quantity="other">%1$d nýjar upptökur</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="one">%1$d upptaka</item>
- <item quantity="other">%1$d upptökur</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="one">%1$d upptaka á áætlun</item>
- <item quantity="other">%1$d upptökur á áætlun</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Horfa"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Spila frá upphafi"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Halda spilun áfram"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Eyða"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Eyða upptökum"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Halda áfram"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Þáttaröð <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Skoða dagskrá"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Lesa meira"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Eyða upptökum"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Veldu þætti sem þú vilt eyða. Ekki er hægt að endurheimta þætti eftir að þeim hefur verið eytt."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Engar upptökur til að eyða"</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Velja þætti sem horft var á"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Velja alla þætti"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Hætta við val á öllum þáttum"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"Horft á <xliff:g id="WATCHED">%1$d</xliff:g> af <xliff:g id="DURATION">%2$d</xliff:g> mínútum"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"Horft á <xliff:g id="WATCHED">%1$d</xliff:g> af <xliff:g id="DURATION">%2$d</xliff:g> sekúndum"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Aldrei horft á"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="one">%1$d af %2$d þætti er eytt</item>
- <item quantity="other">%1$d af %2$d þáttum er eytt</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Forgangur"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Mestur"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Mjög lítill"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Nei. <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Stöðvar"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Hvað sem er"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Veldu forgang"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Þegar taka á upp of marga þætti á sama tíma eru aðeins þættir sem eru í forgangi teknir upp."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Vista"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Stakar upptökur hafa forgang"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Hætta við"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Hætta við"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Gleyma"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Stöðva"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Skoða upptökuáætlun"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Bara þennan þátt"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"núna – <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Alla þáttaröðina…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Setja samt á áætlun"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Taka þetta upp í staðinn"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Hætta við þessa upptöku"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Horfa núna"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Hægt að taka upp"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Upptaka sett á áætlun"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Skarast á við aðra upptöku"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Upptaka í gangi"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Upptaka mistókst"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Les dagskrár til að búa til upptökuáætlanir"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Les dagskrár"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR þarf meira geymslupláss"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Þú getur tekið upp þætti með stafræna upptökubúnaðinum (DVR). Hins vegar er ekki nóg geymslupláss til staðar á tækinu þínu sem stendur til að DVR virki. Tengdu utanáliggjandi disk við tækið sem er <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB eða stærri og fylgdu skrefunum til að setja það upp sem geymslupláss tækisins."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Geymslu vantar"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Hluta af geymslurýminu sem stafræni upptökubúnaðurinn notar vantar. Tengdu utanáliggjandi drif sem þú notaðir áður til að gera stafræna upptökubúnaðinn virkan á ný. Einnig geturðu valið að gleyma geymslunni ef hún er ekki lengur tiltæk."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Viltu gleyma geymslunni?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Allt efni sem þú hefur tekið upp og allar dagskrár glatast."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Stöðva upptöku?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Upptökur á efni verða vistaðar."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Upptaka á áætlun en skarast við aðra"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Upptaka er hafin en hún skarast við aðra"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> verður tekið upp."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"Upptaka í gangi á <xliff:g id="CHANNELNAME">%1$s</xliff:g>."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Einhverjir hlutar af <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> verða ekki teknir upp."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Einhverjir hlutar af <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> og <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> verða ekki teknir upp."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Einhverjir hlutar af <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> og einu dagskráratriði í viðbót verða ekki teknir upp."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="one">Einhverjir hlutar af <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> og %3$d í viðbót verða ekki teknir upp.</item>
- <item quantity="other">Einhverjir hlutar af <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> og %3$d í viðbót verða ekki teknir upp.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Hvað viltu taka upp?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Hversu lengi viltu taka upp?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Þegar áætlað"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Sami þáttur er þegar á upptökuáætlun kl. <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Þegar tekið upp"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Þessi þáttur hefur þegar verið tekinn upp. Hann er tiltækur í DVR-safninu."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Upptekinn þáttur fannst ekki."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Tengdar upptökur"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Engin þáttalýsing)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="one">%1$d upptaka</item>
- <item quantity="other">%1$d upptökur</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> fjarlægt úr upptökuáætlun"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Verður tekið upp að hluta til vegna árekstra við stilli."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Verður ekki tekið upp vegna árekstra við stilli."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Engar upptökur eru á áætlun enn sem komið er.\nÞú getur bætt upptöku við áætlun í dagskrárvísinum."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="one">%1$d árekstur í upptöku</item>
- <item quantity="other">%1$d árekstrar í upptöku</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Þáttaraðastillingar"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Hefja upptöku á þáttaröð"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Hætta upptöku á þáttaröð"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Hætta upptöku á þáttaröð?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Upptökur af þáttum verða áfram tiltækar í DVR-safninu."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Stöðva"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Engir þættir eru tiltækir.\nÞeir verða teknir upp þegar þeir eru tiltækir."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="one">(%1$d mínúta)</item>
- <item quantity="other">(%1$d mínútur)</item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Í dag"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Á morgun"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Í gær"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> í dag"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> á morgun"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Einkunn"</string>
-</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index da0b48a6..3f00e561 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Controlli riproduzione"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Canali recenti"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Canali"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Opzioni TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opzioni PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Controlli di riproduzione non disponibili per questo canale"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Riproduci o metti in pausa"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Avanza velocemente"</string>
@@ -35,39 +34,21 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Sottotitoli"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Visualizzazione"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Attiva"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Non attiva"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Audio multilingua"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Trova altri canali"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Impostazioni"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Fonte"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Scambia"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Attiva"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Non attiva"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Suono"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Principale"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Finestra PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Layout"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"In basso a des."</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"In alto a des."</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"In alto a sin."</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"In basso a sin."</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Affiancata"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Dimensioni"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Grande"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Piccola"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Origine ingresso"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenna/cavo)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Nessuna informazione sul programma"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Nessuna informazione"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Canale bloccato"</string>
- <string name="default_language" msgid="4122326459624337928">"Lingua sconosciuta"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Lingua sconosciuta"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Sottotitoli in %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Sottotitoli"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Off"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Personalizza"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Imposta pref. di sistema per sottotitoli"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Imposta preferenze di sistema per i sottotitoli"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"Visualizzazione"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multi-audio"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Audio multilingua"</string>
<string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
<string name="multi_audio_channel_stereo" msgid="3758995659214256587">"stereo"</string>
<string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"Surround 5.1"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Bassa definizione"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Raggruppa per"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Questo programma è bloccato"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Questo programma non è classificato"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Questo programma è classificato come <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"L\'ingresso non supporta la ricerca automatica"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Impossibile avviare la ricerca automatica per \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d canale aggiunto</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Nessun canale aggiunto"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Sintonizzatore"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Controllo genitori"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Attivo"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Non attivo"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Altri Paesi"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Nessuno"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Nessuna"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Senza classificazione"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blocca i non classificati"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Nessuna"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Limitazioni alte"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Limitazioni medie"</string>
@@ -126,6 +109,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Inserisci il codice PIN per guardare questo canale"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Inserisci il codice PIN per guardare questo programma"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"La valutazione di questo programma è <xliff:g id="RATING">%1$s</xliff:g>. Inserisci il tuo PIN per guardare il programma"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Questo programma non è classificato. Per guardarlo, inserisci il codice PIN."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Inserisci il codice PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Per impostare il filtro famiglia, crea un codice PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Inserisci il nuovo PIN"</string>
@@ -137,22 +121,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Il PIN è errato. Riprova."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Riprova, il PIN non corrisponde"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Inserisci il codice postale."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"L\'app Dirette TV userà il codice postale per fornire una guida ai programmi completa per i canali TV."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Inserisci il codice postale"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Codice postale non valido"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Impostazioni"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personalizza canali"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Scegli canali per guida ai programmi"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Fonti canali"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nuovi canali disponibili"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Controllo genitori"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Registra i programmi in diretta mentre li guardi per poterli mettere in pausa o mandarli indietro.\nAvviso: l\'uso intensivo della memoria interna potrebbe ridurne la durata."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licenze open source"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licenze open source"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Invia feedback"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versione"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Per guardare questo canale, premi il pulsante destro e inserisci il PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Per guardare questo programma, premi il pulsante destro e inserisci il PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Questo programma non è classificato.\nPer guardarlo, premi il pulsante destro e inserisci il codice PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Questo programma è classificato come <xliff:g id="RATING">%1$s</xliff:g>.\nPer guardarlo, premi il tasto destro e inserisci il PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Per guardare questo canale, utilizza l\'app predefinita per la trasmissione di contenuti TV in tempo reale."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Per guardare questo programma utilizza l\'app predefinita per la trasmissione di contenuti TV in tempo reale."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Questo programma non è classificato.\nPer guardarlo, utilizza l\'app predefinita per la trasmissione di contenuti TV in tempo reale."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"La valutazione di questo programma è <xliff:g id="RATING">%1$s</xliff:g>.\nPer guardare questo programma utilizza l\'app predefinita per la trasmissione di contenuti TV in tempo reale."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Il programma è bloccato"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Questo programma non è classificato"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Questo programma è classificato come <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Solo audio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Segnale debole"</string>
@@ -170,7 +163,7 @@
<item quantity="one">%1$d canale</item>
</plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Nessun canale disponibile"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Elementi nuovi"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Nuovo"</string>
<string name="setup_input_setup_now" msgid="1772000402336958967">"Non configurato"</string>
<string name="setup_store_action_title" msgid="4083402039720973414">"Trova altre fonti"</string>
<string name="setup_store_action_description" msgid="6820482635042445297">"Trova app che offrono dirette TV"</string>
@@ -183,17 +176,15 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Premi SELEZIONA"</b>" per accedere al menu della TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Nessun ingresso TV trovato"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Impossibile trovare l\'ingresso TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Funzione PIP non supportata"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Nessun ingresso disponibile per visualizzazione PIP"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tipo di sintonizzatore non adatto. Avvia l\'app Live TV per l\'ingresso TV di tipo sintonizzatore."</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tipo di sintonizzatore non adatto. Avvia l\'app Dirette TV per l\'ingresso TV di tipo sintonizzatore."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Sintonizzazione non riuscita"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Nessuna app trovata per gestire questa azione."</string>
<string name="msg_all_channels_hidden" msgid="777397634062471936">"Tutti i canali di origine sono nascosti.\nSeleziona almeno un canale da guardare."</string>
<string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Il video è improvvisamente non disponibile"</string>
<string name="msg_back_key_guide" msgid="7404682718828721924">"Il tasto INDIETRO è per il dispositivo connesso. Per uscire premi il pulsante HOME."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Live TV richiede l\'autorizzazione per leggere gli elenchi TV."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Dirette TV richiede l\'autorizzazione per leggere gli elenchi TV."</string>
<string name="setup_sources_text" msgid="4988039637873759839">"Configura le tue fonti"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"L\'app Dirette TV combina i canali TV tradizionali ai canali in streaming forniti dalle app. \n\nInnanzitutto, configura le fonti di canali già installate. In alternativa, cerca altre app di dirette TV sul Google Play Store."</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"L\'app Dirette TV combina i canali TV tradizionali con i canali in streaming forniti dalle app. \n\nInnanzitutto, configura le fonti di canali già installate. In alternativa, cerca altre app di dirette TV sul Google Play Store."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Registrazioni e programmazioni"</string>
<string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minuti"</string>
<string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minuti"</string>
@@ -228,6 +219,8 @@
<item quantity="other">%1$d registrazioni programmate</item>
<item quantity="one">%1$d registrazione programmata</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Annulla registrazione"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Interrompi registrazione"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Guarda"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Riproduci dall\'inizio"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Riprendi riproduz."</string>
@@ -260,9 +253,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Quando ci sono troppi programmi da registrare nello stesso momento, vengono registrati solo quelli con le priorità maggiori."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Salva"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Le registrazioni uniche hanno la massima priorità"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Annulla"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Annulla"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Elimina"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Interrompi"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Pianificazione registrazione"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Solo questo programma"</string>
@@ -272,25 +262,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Registra questo"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Annulla la registrazione"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Guarda adesso"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Elimina registrazioni…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Registrabile"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Registrazione programmata"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Conflitto di registrazione"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Registrazione in corso"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Registrazione non riuscita"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Lettura dei programmi per la creazione delle pianificazioni di registrazione"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Lettura dei programmi…"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Lettura dei programmi…"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Visualizza registrazioni recenti"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"La registrazione di <xliff:g id="PROGRAMNAME">%1$s</xliff:g> è incompleta."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Le registrazioni di <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> e <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> sono incomplete."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Le registrazioni di <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> e <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> sono incomplete."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"La registrazione di <xliff:g id="PROGRAMNAME">%1$s</xliff:g> non è stata completata poiché lo spazio di archiviazione non era sufficiente."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Le registrazioni di <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> e <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> non sono state completate poiché lo spazio di archiviazione non era sufficiente."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Le registrazioni di <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> e <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> non sono state completate poiché lo spazio di archiviazione non era sufficiente."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Il dispositivo DVR ha bisogno di più spazio di archiviazione"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Potrai registrare programmi con un dispositivo DVR. Tuttavia, al momento lo spazio di archiviazione non è sufficiente per consentire il funzionamento del DVR. Collega un\'unità esterna di almeno <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB e segui la procedura per formattarla come memoria dispositivo."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Potrai registrare programmi con un dispositivo DVR. Tuttavia, al momento lo spazio di archiviazione non è sufficiente per consentire il funzionamento del DVR. Collega un\'unità esterna di almeno <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB e segui la procedura per formattarla come memoria dispositivo."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Spazio di archiviazione insufficiente"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Il programma non sarà registrato perché lo spazio di archiviazione non è sufficiente. Prova a eliminare alcune registrazioni esistenti."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Memoria mancante"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Manca parte della memoria utilizzata dal DVR. Collega l\'unità esterna utilizzata prima di riattivare il DVR. In alternativa, puoi scegliere di eliminare la memoria se non è più disponibile."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Eliminare la memoria?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Tutti i contenuti registrati e le pianificazioni andranno persi."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Interrompere la registrazione?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"I contenuti registrati verranno salvati."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"La registrazione di <xliff:g id="PROGRAMNAME">%1$s</xliff:g> verrà interrotta perché è in conflitto con questo programma. I contenuti registrati verranno salvati."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Registrazione programmata, ma ci sono conflitti"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"La registrazione è iniziata, ma ci sono conflitti"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Verrà registrato il programma <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
@@ -308,17 +301,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"È già stata programmata la registrazione dello stesso programma alle <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Già registrato"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Questo programma è già stato registrato. È disponibile nella raccolta DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Registrazione della serie programmata"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> registrazioni sono state pianificate per la serie <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> registrazione è stata pianificata per la serie <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> registrazioni sono state pianificate per la serie <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> non saranno registrate a causa di conflitti.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> registrazione è stata pianificata per la serie <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Non sarà registrata a causa di conflitti.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> registrazioni sono state pianificate per la serie <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> puntate di questa e altre serie non saranno registrate a causa di conflitti.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> registrazione è stata pianificata per la serie <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> puntate di questa e altre serie non saranno registrate a causa di conflitti.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> registrazioni sono state pianificate per la serie <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Una puntata di un\'altra serie non sarà registrata a causa di conflitti.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> registrazione è stata pianificata per la serie <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Una puntata di un\'altra serie non sarà registrata a causa di conflitti.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> registrazioni sono state pianificate per la serie <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> puntate di altre serie non saranno registrate a causa di conflitti.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> registrazione è stata pianificata per la serie <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> puntate di altre serie non saranno registrate a causa di conflitti.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Programma registrato non trovato."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Registrazioni correlate"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Nessuna descrizione programma)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d registrazioni</item>
<item quantity="one">%1$d registrazione</item>
@@ -338,6 +343,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Interrompere la registrazione della serie?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Le puntate registrate resteranno disponibili nella raccolta DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Interrompi"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Nessuna puntata in onda al momento."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Non ci sono episodi a disposizione.\nVerranno registrati non appena saranno disponibili."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minuti)</item>
@@ -349,4 +355,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> di oggi"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> di domani"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Punteggio"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programmi registrati"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 743b31fd..6599d98c 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"מונו"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"סטריאו"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"פקדי הפעלה"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"ערוצים אחרונים"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"ערוצים"</string>
<string name="menu_title_options" msgid="7184594626814914022">"‏אפשרויות TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"‏אפשרויות PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"פקדי הפעלה אינם זמינים בשביל הערוץ הזה"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"הפעל או השהה"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"הרץ קדימה"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"כתוביות"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"מצב תצוגה"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"מופעל"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"כבוי"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"מולטי-אודיו"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"קבל ערוצים נוספים"</string>
<string name="options_item_settings" msgid="7623205838542400074">"הגדרות"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"מקור"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"החלף"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"מופעל"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"כבוי"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"צליל"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"ראשי"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"‏חלון PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"פריסה"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"שמאל למטה"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"שמאל למעלה"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"ימין למעלה"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"ימין למטה"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"זה לצד זה"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"גודל"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"גדול"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"קטן"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"מקור קלט"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"טלוויזיה (אנטנה/כבלים)"</string>
<string name="no_program_information" msgid="1049844207745145132">"אין פרטי תכנית"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"אין מידע"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"ערוץ חסום"</string>
- <string name="default_language" msgid="4122326459624337928">"שפה לא ידועה"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"שפה לא ידועה"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"‏כתוביות ב%1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"כתוביות"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"כבוי"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"התאם אישית את הפורמט"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"איכות רגילה"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"קבץ לפי"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"התכנית הזו חסומה"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"לתוכנית הזו אין סיווג תוכן"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"סיווג התכנית הזו הוא <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"הקלט אינו תומך בסריקה אוטומטית"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"לא ניתן להתחיל בסריקה אוטומטית עבור \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
@@ -94,7 +76,6 @@
<item quantity="one">נוסף ערוץ אחד</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"לא נוספו ערוצים"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"טיונר"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"בקרות הוריות"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"מופעל"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"כבוי"</string>
@@ -110,6 +91,8 @@
<string name="other_countries" msgid="8342216398676184749">"מדינות אחרות"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"ללא"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ללא"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"ללא סיווג תוכן"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"חסימת תוכניות ללא סיווג תוכן"</string>
<string name="option_rating_none" msgid="5204552587760414879">"ללא"</string>
<string name="option_rating_high" msgid="8898400296730158893">"הגבלות קפדניות"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"הגבלות בינוניות"</string>
@@ -126,6 +109,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"הזן את קוד האימות שלך כדי לצפות בערוץ זה"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"הזן את קוד האימות שלך כדי לצפות בתכנית זו"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"‏סיווג התוכנית הזו הוא <xliff:g id="RATING">%1$s</xliff:g>. הזן את ה-PIN שלך כדי לצפות בתוכנית זו"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"‏לתוכנית הזו אין סיווג תוכן. עליך להזין את ה-PIN כדי לצפות בה"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"הזן את קוד האימות שלך"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"‏להגדרת בקרות הוריות, צור מספר PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"‏הזן את מספר ה-PIN החדש"</string>
@@ -139,22 +123,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"‏מספר ה-PIN היה שגוי. נסה שוב."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"נסה שוב, קוד האימות אינו תואם"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"הזן את המיקוד שלך"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"‏אפליקציית Live TV תשתמש במיקוד כדי לספק לך את לוח השידורים המלא של ערוצי הטלוויזיה."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"הזן את המיקוד שלך"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"מיקוד לא חוקי"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"הגדרות"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"התאם אישית רשימת ערוצים"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"בחר ערוצים ללוח השידורים שלך"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"מקורות של ערוצים"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"ערוצים חדשים זמינים"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"בקרת הורים"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"פקדי וידאו"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"אפשר להקליט את השידור בזמן הצפייה כדי להשהות תוכניות או להריץ אותן אחורה בזמן אמת.\nאזהרה: הפעלה של האפשרות הזו עלולה לקצר את חיי האחסון הפנימי עקב שימוש אינטנסיבי."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"רישיונות קוד פתוח"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"רישיונות קוד פתוח"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"שלח משוב"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"גרסה"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"‏כדי לצפות בערוץ הזה, לחץ על \'ימין\' והזן את מספר ה-PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"‏כדי לצפות בתכנית הזו, לחץ על \'ימין\' והזן את מספר ה-PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"‏לתוכנית הזו אין סיווג תוכן.\nכדי לצפות בה, יש ללחוץ על החץ ימינה ולהזין את ה-PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"‏סיווג התכנית הזו הוא <xliff:g id="RATING">%1$s</xliff:g>.\nכדי לצפות בתכנית, לחץ ימינה והזן את ה-PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"כדי לצפות בערוץ הזה, השתמש באפליקציית ברירת המחדל לטלוויזיה בשידור חי."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"כדי לצפות בתכנית זו, השתמש באפליקציית ברירת המחדל לטלוויזיה בשידור חי."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"לתוכנית הזו אין סיווג תוכן.\nכדי לצפות בה, יש להשתמש באפליקציית הטלוויזיה המוגדרת כברירת מחדל."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"סיווג התכנית הזו הוא <xliff:g id="RATING">%1$s</xliff:g>.\nכדי לצפות בתכנית זו, השתמש באפליקציית ברירת המחדל לטלוויזיה בשידור חי."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"התכנית חסומה"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"לתוכנית הזו אין סיווג תוכן"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"סיווג התכנית הזו הוא <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"אודיו בלבד"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"אות חלש"</string>
@@ -189,8 +182,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"לחץ על \'בחר\'"</b>" כדי לפתוח את תפריט הטלוויזיה."</string>
<string name="msg_no_input" msgid="3897674146985427865">"לא נמצא קלט טלוויזיה"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"לא ניתן למצוא את קלט הטלוויזיה"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"‏PIP אינו נתמך"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"‏אין קלט זמין הניתן להצגה באמצעות PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"סוג הטיונר אינו מתאים. הפעל את האפליקציה \'ערוצים בשידור חי\' בשביל טיונר מסוג קלט טלוויזיה."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"הכוונון נכשל"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"לא נמצאה אפליקציה שיכולה לטפל בפעולה הזו."</string>
@@ -244,6 +235,8 @@
<item quantity="other">‏תוזמנו %1$d הקלטות</item>
<item quantity="one">הקלטה אחת תוזמנה</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"בטל את ההקלטה"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"הפסק את ההקלטה"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"צפה"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"הפעל מההתחלה"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"המשך את ההפעלה"</string>
@@ -278,9 +271,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"כשיש יותר מדי תוכניות להקליט בו-זמנית, רק תוכניות בעלות עדיפות גבוהה יותר יוקלטו."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"שמור"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"הקלטות חד-פעמיות הן בעלות העדיפות הגבוהה ביותר"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"בטל"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"בטל"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"שכח"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"עצור"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"הצג לוח זמנים להקלטה"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"את התוכנית הזו בלבד"</string>
@@ -290,25 +280,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"הקלטת תוכנית זו במקום זאת"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"ביטול הקלטה זאת"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"לצפייה עכשיו"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"מחיקת הקלטות…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"ניתנת להקלטה"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ההקלטה מתוזמנת"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"התנגשות בין הקלטות"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"מקליט"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ההקלטה נכשלה"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"קורא תוכניות כדי ליצור לוחות זמנים להקלטות"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"קורא תוכניות"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"קורא תוכניות"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"הצגת ההקלטות האחרונות"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"ההקלטה של <xliff:g id="PROGRAMNAME">%1$s</xliff:g> חלקית."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"ההקלטות של <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ו-<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> חלקיות."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"ההקלטות של <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ו-<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> חלקיות."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"ההקלטה של <xliff:g id="PROGRAMNAME">%1$s</xliff:g> לא הושלמה מפני ששטח האחסון אינו מספיק."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"ההקלטות של <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ו-<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> לא הושלמו מפני ששטח האחסון אינו מספיק."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"ההקלטות של <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ו-<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> לא הושלמו מפני ששטח האחסון אינו מספיק."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"‏DVR זקוק לשטח אחסון נוסף"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"‏תוכל להקליט תוכניות עם DVR. אולם, אין מספיק מקום אחסון במכשיר שלך כרגע כדי ש-DVR יעבוד. התחבר לכונן חיצוני בגודל GB<xliff:g id="STORAGE_SIZE">%1$s</xliff:g> או יותר, ובצע את השלבים לביצוע פורמט כאחסון מכשיר."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"‏תוכל להקליט תוכניות עם DVR. אולם, אין מספיק מקום אחסון במכשיר שלך כרגע כדי ש-DVR יעבוד. התחבר לכונן חיצוני בגודל GB<xliff:g id="STORAGE_SIZE">%1$d</xliff:g> או יותר, ובצע את השלבים לביצוע פורמט כאחסון מכשיר."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"אין מספיק שטח אחסון"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"התוכנית הזאת לא תוקלט מפני שאין מספיק שטח אחסון. נסה למחוק חלק מההקלטות הקיימות."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"אחסון חסר"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"‏חלק מהאחסון שנעשה בו שימוש ב-DVR חסר. חבר את הכונן החיצוני שבו השתמשת בעבר כדי להפעיל מחדש את ה-DVR. לחלופין, תוכל לבחור לשכוח את האחסון אם הוא אינו זמין עוד."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"לשכוח את האחסון?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"כל התוכן ולוחות הזמנים שתיעדת יאבדו."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"האם להפסיק את ההקלטה?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"התוכן המוקלט יישמר."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"ההקלטה של <xliff:g id="PROGRAMNAME">%1$s</xliff:g> תיפסק מפני שהיא מתנגשת עם התוכנית הזאת. התוכן שהוקלט יישמר."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ההקלטה מתוזמנת, אבל ישנן הקלטות מתנגשות."</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ההקלטה החלה, אבל ישנן הקלטות מתנגשות"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"התוכנית <xliff:g id="PROGRAMNAME">%1$s</xliff:g> תוקלט."</string>
@@ -328,17 +321,39 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"אותה תוכנית כבר תוזמנה להקלטה ב-<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"כבר הוקלט"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"‏תוכנית זו כבר הוקלטה. היא זמינה לצפייה בספריית ה-DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"הקלטת הסדרה תוזמנה"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="two"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="many"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one">הקלטה <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> תוזמנה לסדרה <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="two"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> הקלטות מתוכן לא יוקלטו עקב התנגשויות.</item>
+ <item quantity="many"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> הקלטות מתוכן לא יוקלטו עקב התנגשויות.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> הקלטות מתוכן לא יוקלטו עקב התנגשויות.</item>
+ <item quantity="one">הקלטה <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> תוזמנה לסדרה <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. היא לא תוקלט עקב התנגשויות.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="two"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> פרקים מסדרה זו וסדרה אחרת לא יוקלטו עקב התנגשויות.</item>
+ <item quantity="many"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> פרקים מסדרה זו וסדרה אחרת לא יוקלטו עקב התנגשויות.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> פרקים מסדרה זו וסדרה אחרת לא יוקלטו עקב התנגשויות.</item>
+ <item quantity="one">הקלטה <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> תוזמנה לסדרה <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> פרקים מסדרה זו וסדרה אחרת לא יוקלטו עקב התנגשויות.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="two"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. פרק אחד מסדרה אחרת לא יוקלט עקב התנגשויות.</item>
+ <item quantity="many"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. פרק אחד מסדרה אחרת לא יוקלט עקב התנגשויות.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. פרק אחד מסדרה אחרת לא יוקלט עקב התנגשויות.</item>
+ <item quantity="one">הקלטה <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> תזומנה לסדרה <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. פרק אחד מסדרה אחרת לא יוקלט עקב התנגשויות.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="two"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> פרקים מסדרה אחרת לא יוקלטו עקב התנגשויות.</item>
+ <item quantity="many"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> פרקים מסדרה אחרת לא יוקלטו עקב התנגשויות.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> הקלטות תוזמנו לסדרה <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> פרקים מסדרה אחרת לא יוקלטו עקב התנגשויות.</item>
+ <item quantity="one">הקלטה <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> תוזמנה לסדרה <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> פרקים מסדרה אחרת לא יוקלטו עקב התנגשות.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"התוכנית המוקלטת לא נמצאה."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"הקלטות קשורות"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(אין תיאור לתוכנית)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="two">‏%1$d הקלטות</item>
<item quantity="many">‏%1$d הקלטות</item>
@@ -362,6 +377,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"האם להפסיק את הקלטת הסדרה?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"‏פרקים מוקלטים יישארו זמינים בספריית DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"הפסק"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"אף פרק אינו משודר כעת."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"אין פרקים זמינים.\nהם יוקלטו כשיהיו זמינים."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="two">‏(%1$d דקות)</item>
@@ -375,4 +391,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> היום"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> מחר"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"ניקוד"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"תוכניות שהוקלטו"</string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 9c526c21..47c2bf47 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"モノラル"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"ステレオ"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"再生操作"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"最近のチャンネル"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"チャンネル"</string>
<string name="menu_title_options" msgid="7184594626814914022">"テレビオプション"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIPオプション"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"このチャンネルでは再生操作を使用できません"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"再生または一時停止"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"早送り"</string>
@@ -30,38 +29,20 @@
<string name="play_controls_description_skip_next" msgid="1603587562124694592">"次へ"</string>
<string name="play_controls_description_skip_previous" msgid="3858447678278021381">"前へ"</string>
<string name="channels_item_program_guide" msgid="2889807207930678418">"番組ガイド"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"利用できる新しいチャンネル"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"新しいチャンネル"</string>
<string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g>を開く"</string>
<string name="options_item_closed_caption" msgid="5945274655046367170">"字幕"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"表示モード"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"ON"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"OFF"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"マルチオーディオ"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"その他のチャンネル"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"他のチャンネル"</string>
<string name="options_item_settings" msgid="7623205838542400074">"設定"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"ソース"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"切り替え"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"ON"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"OFF"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"サウンド"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"メイン"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIPウィンドウ"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"レイアウト"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"右下"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"右上"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"左上"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"左下"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"横並び"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"サイズ"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"大"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"小"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"入力ソース"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"テレビ(アンテナ/ケーブル)"</string>
<string name="no_program_information" msgid="1049844207745145132">"プログラム情報がありません"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"情報はありません"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"ブロックされているチャンネル"</string>
- <string name="default_language" msgid="4122326459624337928">"不明な言語"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"不明な言語"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"クローズド キャプション %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"字幕"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"OFF"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"書式設定のカスタマイズ"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"グループ化"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"このプログラムはブロックされています"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"この番組にはレーティングがありません"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"このプログラムのレーティングは<xliff:g id="RATING">%1$s</xliff:g>です"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"入力が自動スキャンをサポートしていません"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"「<xliff:g id="TV_INPUT">%s</xliff:g>」の自動スキャンを開始できません"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d 件のチャンネルが追加されました</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"追加されたチャンネルなし"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"チューナー"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"保護者による使用制限"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ON"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"OFF"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"その他の国"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"なし"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"なし"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"レーティングなし"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"レーティングなしの番組をブロック"</string>
<string name="option_rating_none" msgid="5204552587760414879">"なし"</string>
<string name="option_rating_high" msgid="8898400296730158893">"制限: 高"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"制限: 中"</string>
@@ -124,9 +107,10 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"PINを入力してこのチャンネルを視聴"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"PINを入力してこのプログラムを視聴"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"この番組は「<xliff:g id="RATING">%1$s</xliff:g>」レーティングです。この番組を視聴するには PIN を入力してください"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"この番組にはレーティングがありません。この番組を視聴するには PIN を入力してください"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"PINの入力"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"保護者による使用制限を設定するには、暗証番号を作成してください"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"新しいPINを入力"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"新しい PIN を入力"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"PINの確認"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"現在のPINの入力"</string>
<plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"PINが正しくありません。もう一度お試しください。"</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"もう一度お試しください。PINが一致しません。"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"郵便番号の入力"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"ライブ チャンネル アプリは、テレビ チャンネルの完全な番組ガイドを提供するために郵便番号を使用します。"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"郵便番号を入力してください"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"郵便番号が無効です"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"設定"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"チャンネル リストをカスタマイズ"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"番組ガイド用のチャンネルを選択します"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"チャンネル ソース"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"新しいチャンネルを利用できます"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"保護者による使用制限"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"タイムシフト"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"放送中の番組を視聴しながら録画する機能です。一時停止や巻き戻しができます。\n警告: 内部ストレージの負荷が増えるため、ストレージの寿命が短くなる恐れがあります。"</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"オープンソース ライセンス"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"オープンソースライセンス"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"フィードバックを送信"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"バージョン"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"このチャンネルを視聴するには、右のボタンを押してPINを入力してください。"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"このプログラムを視聴するには、右のボタンを押してPINを入力してください。"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"この番組にはレーティングがありません。\nこの番組を視聴するには、右のボタンを押して PIN を入力してください"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"このプログラムのレーティングは<xliff:g id="RATING">%1$s</xliff:g>です。\nこのプログラムを視聴するには、右のボタンを押してPINを入力してください。"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"このチャンネルを視聴するには、デフォルトのライブテレビアプリを使用してください。"</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"この番組を視聴するには、デフォルトのライブテレビアプリを使用してください。"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"この番組にはレーティングがありません。\nこの番組を視聴するには、デフォルトのライブテレビ アプリを使用してください。"</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"この番組は「<xliff:g id="RATING">%1$s</xliff:g>」レーティングです。\nこの番組を視聴するには、デフォルトのライブテレビアプリを使用してください。"</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"プログラムはブロックされています"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"この番組にはレーティングがありません"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"このプログラムのレーティングは<xliff:g id="RATING">%1$s</xliff:g>です"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"音声のみ"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"信号強度が弱くなっています"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307">"テレビのメニューにアクセスするには"<b>"[SELECT]を押してください"</b>"。"</string>
<string name="msg_no_input" msgid="3897674146985427865">"テレビ入力が見つかりませんでした"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"テレビ入力が見つかりません"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIPがサポートされていません"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIPで表示できる有効な入力はありません"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"無効なチューナータイプ。チューナー入力のライブチャンネルアプリを起動してください。"</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"同調に失敗しました"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"この操作を行うアプリが見つかりませんでした。"</string>
@@ -193,10 +184,10 @@
<string name="setup_sources_text" msgid="4988039637873759839">"ソースをセットアップ"</string>
<string name="setup_sources_description" msgid="5695518946225445202">"ライブ チャンネルを利用すると、アプリで提供されるストリーミング チャンネルを従来のテレビのチャンネルと同様に視聴できます。\n\n使ってみるには、既にインストールされているチャンネル ソースをセットアップします。また、ライブ チャンネルを提供するアプリを Google Play ストアで探してさらに追加することもできます。"</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"録画予約"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10分"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30分"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1時間"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3時間"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 分"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 分"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 時間"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 時間"</string>
<string name="dvr_main_recent" msgid="2553805424822806495">"最近"</string>
<string name="dvr_main_scheduled" msgid="7837260963086408492">"予約済み"</string>
<string name="dvr_main_series" msgid="8278256687595691676">"シリーズ"</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d 件の録画予約</item>
<item quantity="one">%1$d 件の録画予約</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"録画をキャンセル"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"録音を停止"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"再生"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"最初から再生"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"再生を再開"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"同時に多数の番組を録画する場合は、優先度の高い番組だけが録画されます。"</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"保存"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"1 回のみの録画を最優先"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"キャンセル"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"キャンセル"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"削除"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"停止"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"録画予約を見る"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"この番組のみ"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"この番組を代わりに録画"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"この録画をキャンセル"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"今すぐ見る"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"録画の削除…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"録画できます"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"録画を予約しました"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"録画予約が重複しています"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"録画"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"録画に失敗しました"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"録画予約を作成する番組情報を読み取っています"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"番組情報を読み取っています"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"番組情報を読み取っています"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"最近の録画を表示"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"「<xliff:g id="PROGRAMNAME">%1$s</xliff:g>」の録画を完了できませんでした"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"「<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>」と「<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>」の録画を完了できませんでした"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"「<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>」、「<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>」、「<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>」の録画を完了できませんでした"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"ストレージの容量不足のため、「<xliff:g id="PROGRAMNAME">%1$s</xliff:g>」の録画を完了できませんでした。"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"ストレージの容量不足のため、「<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>」と「<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>」の録画を完了できませんでした。"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"ストレージの容量不足のため、「<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>」、「<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>」、「<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>」の録画を完了できませんでした。"</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR のストレージ不足"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR を使用して番組を録画することはできますが、お使いの端末のストレージが十分ではないため、現在 DVR を使用できません。<xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB 以上の外部ストレージを接続し、手順に沿って端末のストレージと同じようにフォーマットしてください。"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR を使用して番組を録画することはできますが、お使いの端末のストレージが十分ではないため、現在 DVR を使用できません。<xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB 以上の外部ストレージを接続し、手順に沿って端末のストレージと同じようにフォーマットしてください。"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"空き容量の不足"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"空き容量が不足しているため、この番組は録画されません。録画済みの番組をいくつか削除してみてください。"</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"ストレージにアクセスできません"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR で使用しているストレージの一部にアクセスできません。DVR を再度有効にする前に、使用している外部ドライブを接続してください。アクセスできないストレージは削除することもできます。"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"ストレージの削除"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"録画したコンテンツと録画予約がすべて失われます。"</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"録音の停止"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"録画したコンテンツは保存されます。"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"「<xliff:g id="PROGRAMNAME">%1$s</xliff:g>」の録画は、この番組と重なっているため停止されます。録画したコンテンツは保存されます。"</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"録画を予約しましたが、他の予約と重なっています"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"録画を開始しましたが、他の予約と重なっています"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"「<xliff:g id="PROGRAMNAME">%1$s</xliff:g>」が録画されます。"</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"同じ番組が既に録画予約されています(<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>)。"</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"録画済み"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"この番組は既に録画され、DVR ライブラリから利用できます。"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"シリーズの録画を予約しました"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">「<xliff:g id="SERIESNAME_3">%2$s</xliff:g>」の録画は <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 件予約されています。</item>
+ <item quantity="one">「<xliff:g id="SERIESNAME_1">%2$s</xliff:g>」の録画は <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 件予約されています。</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">「<xliff:g id="SERIESNAME_3">%2$s</xliff:g>」の録画は <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 件予約されていますが、予約が競合するため <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> 件は録画されません。</item>
+ <item quantity="one">「<xliff:g id="SERIESNAME_1">%2$s</xliff:g>」の録画は <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 件予約されていますが、予約が競合するため録画されません。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">「<xliff:g id="SERIESNAME_4">%2$s</xliff:g>」の録画は <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> 件予約されています。予約が競合するため、このシリーズと他のシリーズのエピソード(<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> 件)は録画されません。</item>
+ <item quantity="one">「<xliff:g id="SERIESNAME_1">%2$s</xliff:g>」の録画は <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 件予約されています。予約が競合するため、このシリーズと他のシリーズのエピソード(<xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> 件)は録画されません。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">「<xliff:g id="SERIESNAME_3">%2$s</xliff:g>」の録画は <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 件予約されています。予約が競合するため、他のシリーズのエピソード(1 件)は録画されません。</item>
+ <item quantity="one">「<xliff:g id="SERIESNAME_1">%2$s</xliff:g>」の録画は <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 件予約されています。予約が競合するため、他のシリーズのエピソード(1 件)は録画されません。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">「<xliff:g id="SERIESNAME_4">%2$s</xliff:g>」の録画は <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> 件予約されています。予約が競合するため、他のシリーズのエピソード(<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> 件)は録画されません。</item>
+ <item quantity="one">「<xliff:g id="SERIESNAME_1">%2$s</xliff:g>」の録画は <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 件予約されています。予約が競合するため、他のシリーズのエピソード(<xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> 件)は録画されません。</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"録画された番組は見つかりませんでした。"</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"関連の録画"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(番組の説明はありません)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d 件の録画</item>
<item quantity="one">%1$d 件の録画</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"シリーズの録画を中止しますか?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"録画したエピソードは DVR ライブラリから利用できます。"</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"停止"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"現在、放送中の番組はありません。"</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"利用可能なエピソードはありません。\n利用可能になると録画されます。"</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d分)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"今日(<xliff:g id="TIME_RANGE">%1$s</xliff:g>)"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"明日(<xliff:g id="TIME_RANGE">%1$s</xliff:g>)"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"スコア"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"録画した番組"</string>
</resources>
diff --git a/res/values-ka-v23/strings.xml b/res/values-ka-rGE-v23/strings.xml
index 20f03595..20f03595 100644
--- a/res/values-ka-v23/strings.xml
+++ b/res/values-ka-rGE-v23/strings.xml
diff --git a/res/values-ka/arrays.xml b/res/values-ka-rGE/arrays.xml
index 1d6659a6..1d6659a6 100644
--- a/res/values-ka/arrays.xml
+++ b/res/values-ka-rGE/arrays.xml
diff --git a/res/values-ka/rating_system_strings.xml b/res/values-ka-rGE/rating_system_strings.xml
index 498d1d82..498d1d82 100644
--- a/res/values-ka/rating_system_strings.xml
+++ b/res/values-ka-rGE/rating_system_strings.xml
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
new file mode 100644
index 00000000..28c8ce3c
--- /dev/null
+++ b/res/values-ka-rGE/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"მონო"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"სტერეო"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"ჩართვის კონტროლი"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"არხები"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"TV პარამეტრები"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"ამ არხისთვის არ არის ხელმისაწვდომი ჩართვის კონტროლი"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"დაკვრა ან პაუზა"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"წინ გადახვევა"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"უკან გადახვევა"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"შემდეგი"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"წინა"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"პროგ. სახელმძღვანელო"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"წვდომაა ახალ არხებზე"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის გახსნა"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"დახურ.წარწერები"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"ჩვენების რეჟიმი"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"მულტი-აუდიო"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"მეტი არხის მიღება"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"პარამეტრები"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ტელევიზია (ანტენა/კაბელი)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"პროგრამის ინფორმაცია არ არის"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"ინფორმაცია არ არის ხელმისაწვდომი"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"დაბლოკილი არხი"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"უცნობი ენა"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"დახურული სუბტიტრები %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"დახურული სუბტიტრები"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"გამორთულია"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"ფორმატირების მორგება"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"მთელ სისტ. პარ.დაყ. დახ. წარწერებისთვის"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ჩვენების რეჟიმი"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"მულტი-აუდიო"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"მონო"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"სტერეო"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 surround"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 surround"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d არხი"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"არხ.სიის მორგება"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ჯგუფის არჩევა"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"ჯგუფის მონიშვ.გაუქმ."</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"დაჯგუფება:"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"არხის წყარო"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"დაჯგუფება:"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"ეს პროგრამა დაბლოკილია"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"ეს პროგრამა შეუფასებელია"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"ამ პროგრამის რეიტინგია <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"ავტო-სკანირება არ არის მხარდაჭერილი შეყვანით."</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"ვერ ხერხდება ავტო-სკანირება „<xliff:g id="TV_INPUT">%s</xliff:g>“-ისთვის"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"დახურული წარწერებისთვის სისტემის მასშტაბით პარამეტრების გაშვება ვერ ხერხდება."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">დაემატა %1$d არხი</item>
+ <item quantity="one">დაემატა %1$d არხი</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"არხები არ დამატებულა"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"მშობელთა კონტროლი"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ჩართულია"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"გამორთულია"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"დაბლოკილი არხები"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"ყველას დაბლოკვა"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"ყველას განბლოკვა"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"დამალული არხები"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"პროგრ. შეზღუდვები"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN-ის შეცვლა"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"რეიტინგ. სისტემები"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"რეიტინგები"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"ყველ.რეიტ.სის. ნახვა"</string>
+ <string name="other_countries" msgid="8342216398676184749">"სხვა ქვეყნები"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"არცერთი"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"არცერთი"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"შეუფასებელი"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"შეუფასებელ პროგრამათა დაბლოკვა"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"არცერთი"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"მაღალი შეზღუდვები"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"საშუალო შეზღუდვები"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"დაბალი შეზღუდვები"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"მორგებული"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"კონტენტი მიზანშეწონილია ბავშვებისთვის"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"კონტენ. შეეფერება უფროსი ასაკის ბავშვებს"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"კონტენტი განკუთვნილია მოზარდებისთვის"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"ხელით დაყენების შეზღუდვები"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s და ქვე-რეიტინგ."</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"ქვე-რეიტინგები"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"შეიყვანეთ თქვენი PIN ამ არხის საყურებლად"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"შეიყვანეთ თქვენი PIN ამ პროგრამის საყურებლად"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ამ პროგრამის ასაკობრივი შეზღუდვაა: <xliff:g id="RATING">%1$s</xliff:g>. მის საყურებლად, შეიყვანეთ PIN-კოდი"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"ეს პროგრამა შეუფასებელია. ამ პროგრამის სანახავად, შეიყვანეთ თქვენი PIN-კოდი"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"შეიყვანეთ თქვენი PIN"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"მშობელთა კონტროლის დასაყენებლად შექმენით PIN"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"შეიყვანეთ ახალი PIN"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"კვლავ შეიყვანეთ თქვენი PIN"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"შეიყვანეთ თქვენი მიმდინარე PIN"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">თქვენ შეიყვანეთ არასწორი PIN 5-ჯერ.\nცადეთ ისევ <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> წამში.</item>
+ <item quantity="one">თქვენ შეიყვანეთ არასწორი PIN 5-ჯერ.\nცადეთ ისევ <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> წამში.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"ეს PIN არასწორი იყო. ისევ სცადეთ."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"სცადეთ ისევ, PIN არ შეესაბამება"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"შეიყვანეთ თქვენი ZIP კოდი."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"სატელევიზიო არხების სრული პროგრამის სახელმძღვანელოს მისაწოდებლად, Live TV აპი ZIP კოდს გამოიყენებს."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"შეიყვანეთ თქვენი ZIP კოდი"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"არასწორი ZIP კოდი"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"პარამეტრები"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"არხების სიის მორგება"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"აირჩიეთ არხები პროგრამის სახელმძღვანელოსთვის"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"არხების წყაროები"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"ხელმისაწვდომია ახალი არხები"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"მშობელთა კონტროლი"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"დროის შეცვლა"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"ჩაიწერეთ ყურებისას, რათა შეძლოთ პირდაპირ ეთერში გაშვებული პროგრამების დაპაუზება და უკან გადახვევა.\nგაფრთხილება: ამ ქმედებამ შეიძლება შეამციროს შიდა მეხსიერების ფუნქციონირების პერიოდი, მისი ინტენსიური გამოყენების გამო."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"ღია კოდის ლიცენზიები"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"გამოხმაურება"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ვერსია"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"ამ არხის საყურებლად დააჭირეთ „მარჯვენას“ და შეიყვანოთ თქვენი PIN"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"ამ პროგრამის საყურებლად დააჭირეთ „მარჯვენას“ და შეიყვანოთ თქვენი PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"ეს პროგრამა შეუფასებელია.\nამ პროგრამის სანახავად, დააჭირეთ „მარჯვენას“ და შეიყვანეთ თქვენი PIN-კოდი."</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"ამ პროგრამის რეიტინგია <xliff:g id="RATING">%1$s</xliff:g>.\nამ პროგრამის საყურებლად დააჭირეთ „მარჯვენას“ და შეიყვანოთ თქვენი PIN."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ამ არხის საყურებლად, გამოიყენეთ პირდაპირი ტელევიზიის ნაგულისხმევი აპი."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ამ პროგრამის საყურებლად, გამოიყენეთ პირდაპირი ტელევიზიის ნაგულისხმევი აპი."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"ეს პროგრამა შეუფასებელია.\nამ პროგრამის სანახავად, გამოიყენეთ პირდაპირი ტელევიზიის ნაგულისხმევი აპი."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ამ პროგრამის რეიტინგია: <xliff:g id="RATING">%1$s</xliff:g>.\nამ პროგრამის საყურებლად, გამოიყენეთ პირდაპირი ტელევიზიის ნაგულისხმევი აპი."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"პროგრამა დაბლოკილია"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"ეს პროგრამა შეუფასებელია"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ამ პროგრამის რეიტინგია <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"მხოლოდ აუდიო"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"სიგნალი სუსტია"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ინტერნეტთან კავშირი არ არის"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">ამ არხის დაკვრა <xliff:g id="END_TIME_1">%1$s</xliff:g>-მდე ვერ მოხერხდება, რადგან იწერება სხვა არხები. \n\nჩაწერის განრიგის კორექტირებისთვის, დააჭირეთ „მარჯვნივ“-ს.</item>
+ <item quantity="one">ამ არხის დაკვრა <xliff:g id="END_TIME_0">%1$s</xliff:g>-მდე ვერ მოხერხდება, რადგან იწერება სხვა არხი. \n\nჩაწერის განრიგის კორექტირებისთვის, დააჭირეთ „მარჯვნივ“-ს.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"უსათაურო"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"არხი დაბლოკილია"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"ახალი"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"წყაროები"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d არხი</item>
+ <item quantity="one">%1$d არხი</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"ხელმისაწვდომი არხები არ არის"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"ახალი"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"არ არის დაყენებული"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"მეტი წყაროს მიღება"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"დაათვალიერეთ აპები, რომლებიც პირდაპირ არხებს გთავაზობთ"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"ხელმისაწვდომია არხების ახალი წყაროები"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"არხების ახალი წყაროები დამატებით არხებს გთავაზობთ.\nდააყენეთ ისინი ახლავე ან მოგვიანებით, არხების წყაროების პარამეტრებიდან."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"ახლავე დაყენება"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"კარგი, გასაგებია"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>"დააჭირეთ არჩევას"</b>" სატელევიზიო მენიუზე წვდომისთვის."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"TV შეყვანა ვერ მოიძებნა."</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"TV შეყვანა ვერ იძებნება."</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ტიუნერის ტიპი არ არის შესაფერისი; გთხოვთ გაუშვით პირდაპირი არხების აპი, სატელევიზიო შეტანის ტიუნერის ტიპისათვის."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"არხების დაჭერა ვერ მოხერხდა."</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"ამ მოქმედების შესასრულებლად აპი ვერ მოიძებნა."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"წყაროს ყველა არხი დამალულია.\nსაყურებლად აირჩიეთ მინიმუმ ერთი არხი."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ვიდეო მიუწვდომელი გახდა მოულოდნელად."</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"ღილაკი „უკან“ დაკავშირებული მოწყობილობისთვისაა. გამოსასვლელად დააჭირეთ ღილაკს „მთავარი“."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"პირდაპირი არხები საჭიროებს ნებართვას ტელეპროგრამის წასაკითხად."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"დააყენეთ თქვენი წყაროები"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"პირდაპირი არხები ტრადიციულ სატელევიზიო არხებსა და აპების მიერ მოწოდებულ სტრიმინგის არხებს აერთიანებს. \n\nდასაწყებად, დააყენეთ არხების უკვე დაინსტალირებული წყაროები, ან დაათვალიერეთ Google Play Store და აღმოაჩინეთ მეტი აპი, რომლებიც პირდაპირ არხებს გთავაზობთ."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"ჩანაწერები და განრიგები"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 წუთი"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 წუთი"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 საათი"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 საათი"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"ბოლო"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"დაგეგმილი"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"სერიები"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"სხვა"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"არხის ჩაწერა ვერ მოხერხდება."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"პროგრამის ჩაწერა ვერ მოხერხდება."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> დაიგეგმა ჩასაწერად"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> იწერება ამ მომენტიდან <xliff:g id="ENDTIME">%2$s</xliff:g>-მდე"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"სრული განრიგი"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">შემდეგი %1$d დღე</item>
+ <item quantity="one">შემდეგი %1$d დღე</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d წუთი</item>
+ <item quantity="one">%1$d წუთი</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d ახალი ჩანაწერი</item>
+ <item quantity="one">%1$d ახალი ჩანაწერი</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d ჩანაწერი</item>
+ <item quantity="one">%1$d ჩანაწერი</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d ჩანაწერი დაიგეგმა</item>
+ <item quantity="one">%1$d ჩანაწერი დაიგეგმა</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"ჩაწერის გაუქმება"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"ჩაწერის შეწყვეტა"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"ყურება"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"თავიდან დაკვრა"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"დაკვრის განახლება"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"წაშლა"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ჩანაწერების წაშლა"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"განახლება"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"სეზონი <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"განრიგის ნახვა"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"მეტის წაკითხვა"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ჩანაწერების წაშლა"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"აირჩიეთ ეპიზოდები, რომელთა წაშლაც გსურთ. წაშლის შემდეგ, მათი აღდგენა ვეღარ მოხერხდება."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"წასაშლელი ჩანაწერები არ არის."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"ნაყურები ეპიზოდების არჩევა"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"ყველა ეპიზოდის არჩევა"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"ყველა მონიშვნის მოხსნა"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"ნაყურებია <xliff:g id="DURATION">%2$d</xliff:g>-დან <xliff:g id="WATCHED">%1$d</xliff:g> წუთი"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"ნაყურებია <xliff:g id="DURATION">%2$d</xliff:g>-დან <xliff:g id="WATCHED">%1$d</xliff:g> წამი"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"არასოდეს ნაყურები"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%2$d-დან %1$d ეპიზოდი წაიშალა</item>
+ <item quantity="one">%2$d-დან %1$d ეპიზოდი წაიშალა</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"პრიორიტეტი"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ყველაზე მაღალი"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ყველაზე დაბალი"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"№ <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"არხები"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ნებისმიერი"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"აირჩიეთ პრიორიტეტი"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"თუ ჩასაწერად მეტისმეტად ბევრი პროგრამა დაიგეგმება, ჩაიწერება მხოლოდ მაღალი პრიორიტეტის მქონე პროგრამები."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"შენახვა"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ერთჯერად ჩანაწერებს მიენიჭოს მეტი პრიორიტეტი"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"შეწყვეტა"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ჩაწერის განრიგის ნახვა"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"მხოლოდ ეს პროგრამა"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ახლა — <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"მთლიანი სერიალი…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"მაინც დაგეგმვა"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"სანაცვლოდ, ჩაიწეროს ეს"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ამ ჩანაწერის გაუქმება"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"ახლავე ყურება"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"ჩანაწერების წაშლა…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"შესაძლებელია ჩაწერა"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ჩაწერა დაგეგმილია"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ჩაწერის კონფლიქტი"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"მიმდინარეობს ჩაწერა"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ჩაწერა ვერ მოხერხდა"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"მიმდინარეობს პროგრამების წაკითხვა"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"ბოლო ჩანაწერების ნახვა"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> არასრულად ჩაიწერა."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> და <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> არასრულად ჩაიწერა."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> და <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> არასრულად ჩაიწერა."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"არასაკმარისი მეხსიერების გამო, <xliff:g id="PROGRAMNAME">%1$s</xliff:g> არასრულად ჩაიწერა."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"არასაკმარისი მეხსიერების გამო, <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> და <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> არასრულად ჩაიწერა."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"არასაკმარისი მეხსიერების გამო, <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> და <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> არასრულად ჩაიწერა."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR მეტ მეხსიერებას საჭიროებს"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR-ის მეშვეობით პროგრამების ჩაწერა შესაძლებელია, თუმცა თქვენს მოწყობილობაზე ამჟამად ხელმისაწვდომი მეხსიერება DVR-ის მუშაობისთვის არასაკმარისია. გთხოვთ, დააკავშიროთ <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> გბაიტი ან მეტი მოცულობის დისკწამყვანი და მიჰყვეთ ინსტრუქციას, რომელიც დაგეხმარებათ, დააფორმატოთ ის მოწყობილობის მეხსიერების სახით."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"მეხსიერება არასაკმარისია"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"ეს პროგრამა ვერ ჩაიწერება არასაკმარისი მეხსიერების გამო. ცადეთ არსებული ჩანაწერების წაშლა."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"აკლია მეხსიერება"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"გსურთ ჩაწერის შეწყვეტა?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ჩაწერილი კონტენტი შეინახება."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"„<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“-ის ჩაწერა შეწყდება ამ პროგრამასთან კონფლიქტის გამო. ჩაწერილი კონტენტი შეინახება."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ჩაწერა დაგეგმილია, თუმცა ის კონფლიქტშია"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ჩაწერა დაიწყო, თუმცა ის კონფლიქტშია"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ჩაიწერება."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> იწერება."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ნაწილობრივ არ ჩაიწერება."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> და <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ნაწილობრივ არ ჩაიწერება."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> და კიდევ ერთი განრიგი ნაწილობრივ არ ჩაიწერება."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> და კიდევ %3$d განრიგი ნაწილობრივ არ ჩაიწერება.</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> და კიდევ %3$d განრიგი ნაწილობრივ არ ჩაიწერება.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"გსურთ ჩაწერა?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"რამდენი ხანი გსურთ, გაგრძელდეს ჩაწერა?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"უკვე დაგეგმილია"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"იგივე პროგრამა უკვე დაიგეგმა ჩასაწერად <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>-ზე."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"უკვე ჩაწერილია"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ეს პროგრამა უკვე ჩაწერილია და DVR ბიბლიოთეკაშია ხელმისაწვდომი."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"სერიალის ჩაწერა დაგეგმილია"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">„<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“-სთვის დაიგეგმა <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ჩანაწერი.</item>
+ <item quantity="one">„<xliff:g id="SERIESNAME_1">%2$s</xliff:g>“-სთვის დაიგეგმა <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ჩანაწერი.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">„<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“-სთვის დაიგეგმა <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ჩანაწერი. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> მათგანი ვერ ჩაიწერება კონფლიქტების გამო.</item>
+ <item quantity="one">„<xliff:g id="SERIESNAME_1">%2$s</xliff:g>“-სთვის დაიგეგმა <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ჩანაწერი. ის ვერ ჩაიწერება კონფლიქტების გამო.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">„<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“-სთვის დაიგეგმა <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ჩანაწერი. ამ სერიალის <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ეპიზოდი და სხვა სერიალები ვერ ჩაიწერება კონფლიქტების გამო.</item>
+ <item quantity="one">„<xliff:g id="SERIESNAME_1">%2$s</xliff:g>“-სთვის დაიგეგმა <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ჩანაწერი. ამ სერიალის <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ეპიზოდი და სხვა სერიალები ვერ ჩაიწერება კონფლიქტების გამო.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">„<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“-სთვის დაიგეგმა <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ჩანაწერი. სხვა სერიალის 1 ეპიზოდი ვერ ჩაიწერება კონფლიქტების გამო.</item>
+ <item quantity="one">„<xliff:g id="SERIESNAME_1">%2$s</xliff:g>“-სთვის დაიგეგმა <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ჩანაწერი. სხვა სერიალის 1 ეპიზოდი ვერ ჩაიწერება კონფლიქტების გამო.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">„<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“-სთვის დაიგეგმა <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ჩანაწერი. სხვა სერიალების <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ეპიზოდი ვერ ჩაიწერება კონფლიქტების გამო.</item>
+ <item quantity="one">„<xliff:g id="SERIESNAME_1">%2$s</xliff:g>“-სთვის დაიგეგმა <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ჩანაწერი. სხვა სერიალების <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ეპიზოდი ვერ ჩაიწერება კონფლიქტების გამო.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"ჩაწერილი პროგრამა ვერ მოიძებნა."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"დაკავშირებული ჩანაწერები"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d ჩანაწერი</item>
+ <item quantity="one">%1$d ჩანაწერი</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ამოიშალა ჩაწერის განრიგიდან"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ჩაიწერება ნაწილობრივ ტუნერის კონფლიქტების გამო."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"არ ჩაიწერება ტუნერის კონფლიქტების გამო."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ჩაწერა ჯერ დაგეგმილი არ არის.\nჩაწერის დაგეგმვა პროგრამების მეგზურიდან შეგიძლიათ."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d ჩაწერის კონფლიქტი</item>
+ <item quantity="one">%1$d ჩაწერის კონფლიქტი</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"სერიალის პარამეტრები"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"სერიალის ჩაწერის დაწყება"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"სერიალის ჩაწერის შეწყვეტა"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"გსურთ სერიალის ჩაწერის შეწყვეტა?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ჩაწერილი ეპიზოდები DVR ბიბლიოთეკაში კვლავ იქნება ხელმისაწვდომი."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"შეწყვეტა"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ამჟამად ეთერში არცერთი ეპიზოდი არ გადის."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ეპიზოდები მიუწვდომელია.\nმათი ჩაწერა მოხდება მაშინ, როცა ისინი ხელმისაწვდომი გახდება."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d წუთი)</item>
+ <item quantity="one">(%1$d წუთი) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"დღეს"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"ხვალ"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"გუშინ"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"დღეს, <xliff:g id="TIME_RANGE">%1$s</xliff:g>-ზე"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"ხვალ, <xliff:g id="TIME_RANGE">%1$s</xliff:g>-ზე"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"შეფასება"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"ჩაწერილი პროგრამები"</string>
+</resources>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
deleted file mode 100644
index 72608bd4..00000000
--- a/res/values-ka/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"მონო"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"სტერეო"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"ჩართვის კონტროლი"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"უახლესი არხები"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"TV პარამეტრები"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP პარამეტრები"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"ამ არხისთვის არ არის ხელმისაწვდომი ჩართვის კონტროლი"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"დაკვრა ან პაუზა"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"წინ გადახვევა"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"უკან გადახვევა"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"შემდეგი"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"წინა"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"პროგ. სახელმძღვანელო"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"წვდომაა ახალ არხებზე"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის გახსნა"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"დახურ.წარწერები"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"ჩვენების რეჟიმი"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"ჩართული"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"გამორთული"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"მულტი-აუდიო"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"მეტი არხის მიღება"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"პარამეტრები"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"წყარო"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"შენაცვლება"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"ჩართული"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"გამორთული"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"ხმა"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"მთავარი"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP ფანჯარა"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"განლაგება"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"ქვედა მარჯვენა"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"ზედა მარჯვენა"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"ზედა მარცხენა"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"ქვედა მარცხენა"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"გვერდი-გვერდ"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"ზომა"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"დიდი"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"პატარა"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"შემავალი წყარო"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ტელევიზია (ანტენა/კაბელი)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"პროგრამის ინფორმაცია არ არის"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"ინფორმაცია არ არის ხელმისაწვდომი"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"დაბლოკილი არხი"</string>
- <string name="default_language" msgid="4122326459624337928">"უცნობი ენა"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"დახურული სუბტიტრები"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"გამორთულია"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"ფორმატირების მორგება"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"მთელ სისტ. პარ.დაყ. დახ. წარწერებისთვის"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ჩვენების რეჟიმი"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"მულტი-აუდიო"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"მონო"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"სტერეო"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 surround"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 surround"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d არხი"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"არხ.სიის მორგება"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ჯგუფის არჩევა"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"ჯგუფის მონიშვ.გაუქმ."</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"დაჯგუფება:"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"არხის წყარო"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"დაჯგუფება:"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"ეს პროგრამა დაბლოკილია"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"ამ პროგრამის რეიტინგია <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"ავტო-სკანირება არ არის მხარდაჭერილი შეყვანით."</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"ვერ ხერხდება ავტო-სკანირება „<xliff:g id="TV_INPUT">%s</xliff:g>“-ისთვის"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"დახურული წარწერებისთვის სისტემის მასშტაბით პარამეტრების გაშვება ვერ ხერხდება."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">დაემატა %1$d არხი</item>
- <item quantity="one">დაემატა %1$d არხი</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"არხები არ დამატებულა"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ტუნერი"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"მშობელთა კონტროლი"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ჩართულია"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"გამორთულია"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"დაბლოკილი არხები"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"ყველას დაბლოკვა"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"ყველას განბლოკვა"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"დამალული არხები"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"პროგრ. შეზღუდვები"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN-ის შეცვლა"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"რეიტინგ. სისტემები"</string>
- <string name="option_ratings" msgid="4009116954188688616">"რეიტინგები"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"ყველ.რეიტ.სის. ნახვა"</string>
- <string name="other_countries" msgid="8342216398676184749">"სხვა ქვეყნები"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"არცერთი"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"არცერთი"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"არცერთი"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"მაღალი შეზღუდვები"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"საშუალო შეზღუდვები"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"დაბალი შეზღუდვები"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"მორგებული"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"კონტენტი მიზანშეწონილია ბავშვებისთვის"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"კონტენ. შეეფერება უფროსი ასაკის ბავშვებს"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"კონტენტი განკუთვნილია მოზარდებისთვის"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"ხელით დაყენების შეზღუდვები"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s და ქვე-რეიტინგ."</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"ქვე-რეიტინგები"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"შეიყვანეთ თქვენი PIN ამ არხის საყურებლად"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"შეიყვანეთ თქვენი PIN ამ პროგრამის საყურებლად"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ამ პროგრამის ასაკობრივი შეზღუდვაა: <xliff:g id="RATING">%1$s</xliff:g>. მის საყურებლად, შეიყვანეთ PIN-კოდი"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"შეიყვანეთ თქვენი PIN"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"მშობელთა კონტროლის დასაყენებლად შექმენით PIN"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"შეიყვანეთ ახალი PIN"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"კვლავ შეიყვანეთ თქვენი PIN"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"შეიყვანეთ თქვენი მიმდინარე PIN"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">თქვენ შეიყვანეთ არასწორი PIN 5-ჯერ.\nცადეთ ისევ <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> წამში.</item>
- <item quantity="one">თქვენ შეიყვანეთ არასწორი PIN 5-ჯერ.\nცადეთ ისევ <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> წამში.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"ეს PIN არასწორი იყო. ისევ სცადეთ."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"სცადეთ ისევ, PIN არ შეესაბამება"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"პარამეტრები"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"არხების სიის მორგება"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"აირჩიეთ არხები პროგრამის სახელმძღვანელოსთვის"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"არხების წყაროები"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"ხელმისაწვდომია ახალი არხები"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"მშობელთა კონტროლი"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"ღია კოდის ლიცენზიები"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"ღია კოდის ლიცენზიები"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"ვერსია"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"ამ არხის საყურებლად დააჭირეთ „მარჯვენას“ და შეიყვანოთ თქვენი PIN"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"ამ პროგრამის საყურებლად დააჭირეთ „მარჯვენას“ და შეიყვანოთ თქვენი PIN"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"ამ პროგრამის რეიტინგია <xliff:g id="RATING">%1$s</xliff:g>.\nამ პროგრამის საყურებლად დააჭირეთ „მარჯვენას“ და შეიყვანოთ თქვენი PIN."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ამ არხის საყურებლად, გამოიყენეთ პირდაპირი ტელევიზიის ნაგულისხმევი აპი."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ამ პროგრამის საყურებლად, გამოიყენეთ პირდაპირი ტელევიზიის ნაგულისხმევი აპი."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ამ პროგრამის რეიტინგია: <xliff:g id="RATING">%1$s</xliff:g>.\nამ პროგრამის საყურებლად, გამოიყენეთ პირდაპირი ტელევიზიის ნაგულისხმევი აპი."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"პროგრამა დაბლოკილია"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ამ პროგრამის რეიტინგია <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"მხოლოდ აუდიო"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"სიგნალი სუსტია"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ინტერნეტთან კავშირი არ არის"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">ამ არხის დაკვრა <xliff:g id="END_TIME_1">%1$s</xliff:g>-მდე ვერ მოხერხდება, რადგან იწერება სხვა არხები. \n\nჩაწერის განრიგის კორექტირებისთვის, დააჭირეთ „მარჯვნივ“-ს.</item>
- <item quantity="one">ამ არხის დაკვრა <xliff:g id="END_TIME_0">%1$s</xliff:g>-მდე ვერ მოხერხდება, რადგან იწერება სხვა არხი. \n\nჩაწერის განრიგის კორექტირებისთვის, დააჭირეთ „მარჯვნივ“-ს.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"უსათაურო"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"არხი დაბლოკილია"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"ახალი"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"წყაროები"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d არხი</item>
- <item quantity="one">%1$d არხი</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"ხელმისაწვდომი არხები არ არის"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"ახალი"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"არ არის დაყენებული"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"მეტი წყაროს მიღება"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"დაათვალიერეთ აპები, რომლებიც პირდაპირ არხებს გთავაზობთ"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"ხელმისაწვდომია არხების ახალი წყაროები"</string>
- <string name="new_sources_description" msgid="749649005588426813">"არხების ახალი წყაროები დამატებით არხებს გთავაზობთ.\nდააყენეთ ისინი ახლავე ან მოგვიანებით, არხების წყაროების პარამეტრებიდან."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"ახლავე დაყენება"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"კარგი, გასაგებია"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307"><b>"დააჭირეთ არჩევას"</b>" სატელევიზიო მენიუზე წვდომისთვის."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"TV შეყვანა ვერ მოიძებნა."</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"TV შეყვანა ვერ იძებნება."</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"არ არის PIP-ის მხარდაჭერა."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP-ში გამოსაჩენი შემავალი სიგნალი მიუწვდომელია."</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ტიუნერის ტიპი არ არის შესაფერისი; გთხოვთ გაუშვით პირდაპირი არხების აპი, სატელევიზიო შეტანის ტიუნერის ტიპისათვის."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"არხების დაჭერა ვერ მოხერხდა."</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"ამ მოქმედების შესასრულებლად აპი ვერ მოიძებნა."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"წყაროს ყველა არხი დამალულია.\nსაყურებლად აირჩიეთ მინიმუმ ერთი არხი."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ვიდეო მიუწვდომელი გახდა მოულოდნელად."</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"ღილაკი „უკან“ დაკავშირებული მოწყობილობისთვისაა. გამოსასვლელად დააჭირეთ ღილაკს „მთავარი“."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"პირდაპირი არხები საჭიროებს ნებართვას ტელეპროგრამის წასაკითხად."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"დააყენეთ თქვენი წყაროები"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"პირდაპირი არხები ტრადიციულ სატელევიზიო არხებსა და აპების მიერ მოწოდებულ სტრიმინგის არხებს აერთიანებს. \n\nდასაწყებად, დააყენეთ არხების უკვე დაინსტალირებული წყაროები, ან დაათვალიერეთ Google Play Store და აღმოაჩინეთ მეტი აპი, რომლებიც პირდაპირ არხებს გთავაზობთ."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"ჩანაწერები და განრიგები"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 წუთი"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 წუთი"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 საათი"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 საათი"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"ბოლო"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"დაგეგმილი"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"სერიები"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"სხვა"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"არხის ჩაწერა ვერ მოხერხდება."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"პროგრამის ჩაწერა ვერ მოხერხდება."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> დაიგეგმა ჩასაწერად"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> იწერება ამ მომენტიდან <xliff:g id="ENDTIME">%2$s</xliff:g>-მდე"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"სრული განრიგი"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">შემდეგი %1$d დღე</item>
- <item quantity="one">შემდეგი %1$d დღე</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d წუთი</item>
- <item quantity="one">%1$d წუთი</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d ახალი ჩანაწერი</item>
- <item quantity="one">%1$d ახალი ჩანაწერი</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d ჩანაწერი</item>
- <item quantity="one">%1$d ჩანაწერი</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d ჩანაწერი დაიგეგმა</item>
- <item quantity="one">%1$d ჩანაწერი დაიგეგმა</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"ყურება"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"თავიდან დაკვრა"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"დაკვრის განახლება"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"წაშლა"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ჩანაწერების წაშლა"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"განახლება"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"სეზონი <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"განრიგის ნახვა"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"მეტის წაკითხვა"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ჩანაწერების წაშლა"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"აირჩიეთ ეპიზოდები, რომელთა წაშლაც გსურთ. წაშლის შემდეგ, მათი აღდგენა ვეღარ მოხერხდება."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"წასაშლელი ჩანაწერები არ არის."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"ნაყურები ეპიზოდების არჩევა"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"ყველა ეპიზოდის არჩევა"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"ყველა მონიშვნის მოხსნა"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"ნაყურებია <xliff:g id="DURATION">%2$d</xliff:g>-დან <xliff:g id="WATCHED">%1$d</xliff:g> წუთი"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"ნაყურებია <xliff:g id="DURATION">%2$d</xliff:g>-დან <xliff:g id="WATCHED">%1$d</xliff:g> წამი"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"არასოდეს ნაყურები"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%2$d-დან %1$d ეპიზოდი წაიშალა</item>
- <item quantity="one">%2$d-დან %1$d ეპიზოდი წაიშალა</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"პრიორიტეტი"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ყველაზე მაღალი"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ყველაზე დაბალი"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"№ <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"არხები"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ნებისმიერი"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"აირჩიეთ პრიორიტეტი"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"თუ ჩასაწერად მეტისმეტად ბევრი პროგრამა დაიგეგმება, ჩაიწერება მხოლოდ მაღალი პრიორიტეტის მქონე პროგრამები."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"შენახვა"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ერთჯერად ჩანაწერებს მიენიჭოს მეტი პრიორიტეტი"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"გაუქმება"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"გაუქმება"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"დავიწყება"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"შეწყვეტა"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ჩაწერის განრიგის ნახვა"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"მხოლოდ ეს პროგრამა"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ახლა — <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"მთლიანი სერიალი…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"მაინც დაგეგმვა"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"სანაცვლოდ, ჩაიწეროს ეს"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ამ ჩანაწერის გაუქმება"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"ახლავე ყურება"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"შესაძლებელია ჩაწერა"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ჩაწერა დაგეგმილია"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ჩაწერის კონფლიქტი"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"მიმდინარეობს ჩაწერა"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ჩაწერა ვერ მოხერხდა"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"მიმდინარეობს პროგრამების წაკითხვა ჩაწერის განრიგების შესაქმნელად"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"მიმდინარეობს პროგრამების წაკითხვა"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR მეტ მეხსიერებას საჭიროებს"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR-ის მეშვეობით პროგრამების ჩაწერა შესაძლებელია, თუმცა თქვენს მოწყობილობაზე ამჟამად ხელმისაწვდომი მეხსიერება DVR-ის მუშაობისთვის არასაკმარისია. გთხოვთ, დააკავშიროთ <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> გბაიტი ან მეტი მოცულობის დისკწამყვანი და მიჰყვეთ ინსტრუქციას, რომელიც დაგეხმარებათ, დააფორმატოთ ის მოწყობილობის მეხსიერების სახით."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"აკლია მეხსიერება"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR-ის მიერ გამოყენებული მეხსიერების ნაწილი ვერ მოიძებნა. DVR-ის ხელახლა ჩასართავად, გთხოვთ, დააკავშიროთ გარე დისკი, რომლითაც ადრე სარგებლობდით. თუ მეხსიერება ხელმისაწვდომი აღარ არის, შეგიძლიათ მეხსიერების დავიწყება აირჩიოთ."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"გსურთ მეხსიერების დავიწყება?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"მთელი თქვენი ჩაწერილი კონტენტი და ყველა განრიგი დაიკარგება."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"გსურთ ჩაწერის შეწყვეტა?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ჩაწერილი კონტენტი შეინახება."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ჩაწერა დაგეგმილია, თუმცა ის კონფლიქტშია"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ჩაწერა დაიწყო, თუმცა ის კონფლიქტშია"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ჩაიწერება."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> იწერება."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ნაწილობრივ არ ჩაიწერება."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> და <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ნაწილობრივ არ ჩაიწერება."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> და კიდევ ერთი განრიგი ნაწილობრივ არ ჩაიწერება."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> და კიდევ %3$d განრიგი ნაწილობრივ არ ჩაიწერება.</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> და კიდევ %3$d განრიგი ნაწილობრივ არ ჩაიწერება.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"გსურთ ჩაწერა?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"რამდენი ხანი გსურთ, გაგრძელდეს ჩაწერა?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"უკვე დაგეგმილია"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"იგივე პროგრამა უკვე დაიგეგმა ჩასაწერად <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>-ზე."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"უკვე ჩაწერილია"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ეს პროგრამა უკვე ჩაწერილია და DVR ბიბლიოთეკაშია ხელმისაწვდომი."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"ჩაწერილი პროგრამა ვერ მოიძებნა."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"დაკავშირებული ჩანაწერები"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(პროგრამის აღწერა არ არის)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d ჩანაწერი</item>
- <item quantity="one">%1$d ჩანაწერი</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ამოიშალა ჩაწერის განრიგიდან"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ჩაიწერება ნაწილობრივ ტუნერის კონფლიქტების გამო."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"არ ჩაიწერება ტუნერის კონფლიქტების გამო."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ჩაწერა ჯერ დაგეგმილი არ არის.\nჩაწერის დაგეგმვა პროგრამების მეგზურიდან შეგიძლიათ."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d ჩაწერის კონფლიქტი</item>
- <item quantity="one">%1$d ჩაწერის კონფლიქტი</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"სერიალის პარამეტრები"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"სერიალის ჩაწერის დაწყება"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"სერიალის ჩაწერის შეწყვეტა"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"გსურთ სერიალის ჩაწერის შეწყვეტა?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ჩაწერილი ეპიზოდები DVR ბიბლიოთეკაში კვლავ იქნება ხელმისაწვდომი."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"შეწყვეტა"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ეპიზოდები მიუწვდომელია.\nმათი ჩაწერა მოხდება მაშინ, როცა ისინი ხელმისაწვდომი გახდება."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d წუთი)</item>
- <item quantity="one">(%1$d წუთი) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"დღეს"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"ხვალ"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"გუშინ"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"დღეს, <xliff:g id="TIME_RANGE">%1$s</xliff:g>-ზე"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"ხვალ, <xliff:g id="TIME_RANGE">%1$s</xliff:g>-ზე"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"შეფასება"</string>
-</resources>
diff --git a/res/values-kk-v23/strings.xml b/res/values-kk-rKZ-v23/strings.xml
index 4da42f69..4da42f69 100644
--- a/res/values-kk-v23/strings.xml
+++ b/res/values-kk-rKZ-v23/strings.xml
diff --git a/res/values-kk/arrays.xml b/res/values-kk-rKZ/arrays.xml
index bbb0282c..bbb0282c 100644
--- a/res/values-kk/arrays.xml
+++ b/res/values-kk-rKZ/arrays.xml
diff --git a/res/values-kk/rating_system_strings.xml b/res/values-kk-rKZ/rating_system_strings.xml
index efeb4715..efeb4715 100644
--- a/res/values-kk/rating_system_strings.xml
+++ b/res/values-kk-rKZ/rating_system_strings.xml
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
new file mode 100644
index 00000000..44441192
--- /dev/null
+++ b/res/values-kk-rKZ/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Ойын тетіктері"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Арналар"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"ТД опциялары"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Бұл арна үшін ойнатуды басқару элементтерін қол жетімсіз"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Ойнату немесе кідірту"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Жылдам алға айналдыру"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Кері айналдыру"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Келесі"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Алдыңғы"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Бағдарламалар нұс-ғы"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Жаңа арналар қол жетім."</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын ашу"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Жасырын титрлер"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Дисплей режимі"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Мультиаудио"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Басқа арналар"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Параметрлер"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ТД (антенна/кабель)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Бағдарлама туралы ақпарат жоқ"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Ақпарат жоқ"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Бөгелген арна"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Белгісіз тіл"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Субтитрлер: %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Жасырын титрлер"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Өшірулі"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Пішімдеуді теңшеу"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Жасырын титрлер үшін жүйелік пар-ді орн."</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Дисплей режимі"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Мультиаудио"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"моно"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"стерео"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 көлемді"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 көлемді"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d арна"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Арналар тіз. тең."</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Топты таңдау"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Топтан таңдауды алу"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Топтау шарты"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Арна көзі"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Топтау шарты"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Бұл бағдарламаға тыйым салынған"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Бұл бағдарламаның жас бойынша шектеуі белгіленбеген"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Бұл бағдарламаға <xliff:g id="RATING">%1$s</xliff:g> бағасы қойылған"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Кіріс автоматты түрде іздеуді қолдамайды"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"«<xliff:g id="TV_INPUT">%s</xliff:g>» үшін автоматты түрде іздеуді бастау мүмкін болмады"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Жасырын титрлер үшін жүйелік параметрлерді іске қосу мүмкін болмады."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d арна қосылды</item>
+ <item quantity="one">%1$d арна қосылды</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Арналар қосылмаған"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Ата-аналық бақылау"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Қосулы"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Өшірулі"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Арналар бөгелген"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Барлығын бөгеу"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Бәрін бөгеуден шығ."</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Жасырын арналар"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Бағдарлама шек-рі"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN кодын өзгерту"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Бағалау жүйелері"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Рейтингтер"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Бар. бағ. жүй-н көру"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Басқа елдер"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Ешқандай"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ешқандай"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Жас бойынша шектеуі белгіленбеген"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Жас бойынша шектеуі белгіленбеген бағдарламаларды бөгеу"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Ешқандай"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Жоғары шектеулер"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Орташа шектеулер"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Төмен шектеулер"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Теңшелетін"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Мазмұн балалар үшін жарамды"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Үлкенірек балаларға жарамды мазмұн"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Мазмұн жасөспірімдерге жарамды"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Қолмен реттелетін шектеулер"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s және ішкі бағ-р"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Ішкі бағалар"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Бұл арнаны көру үшін PIN кодын енгізіңіз"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Бұл бағдарламаны көру үшін PIN кодын енгізіңіз"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Бұл бағдарламаға <xliff:g id="RATING">%1$s</xliff:g> бағасы берілген. Оны көру үшін PIN кодын енгізіңіз"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Бұл бағдарламаның жас бойынша шектеуі белгіленбеген. Бұл бағдарламаны көру үшін PIN кодын енгізіңіз"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"PIN кодын енгізіңіз"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Ата-аналық бақылауды орнату үшін PIN кодын жасаңыз"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Жаңа PIN кодын енгізіңіз"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"PIN кодын растау"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Ағымдағы PIN кодын енгізіңіз"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Қате PIN кодын 5 рет қате енгіздіңіз.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секундтан кейін қайталап көріңіз.</item>
+ <item quantity="one">Қате PIN кодын 5 рет қате енгіздіңіз.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> секундтан кейін қайталап көріңіз.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"Бұл PIN қате болды. Әрекетті қайталаңыз."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Әрекетті қайталаңыз, PIN кодтары сәйкес емес"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Пошта индексін енгізіңіз."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Тікелей арналар қолданбасы телеарналардың толық бағдарламалар нұсқаулығын ұсыну үшін пошта индексін пайдаланады."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Индексті енгізіңіз"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Индекс жарамсыз"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Параметрлер"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Арналар тізімін теңшеу"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Бағдарлама нұсқаулығына арналған арналарды таңдау"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Арна көздері"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Жаңа арналар қосылды"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Ата-аналық бақылау"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Уақытты жылжыту"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Тікелей эфирдегі бағдарламаларды көру кезінде тоқтатуға немесе артқа айналдыруға болатын жазу.\nЕскерту: бұл жадты қарқынды пайдалану арқылы ішкі жадтың қызмет көрсету мерзімін азайтуы мүмкін."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Ашық бастапқы код лицензиялары"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Пікір жіберу"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Нұсқа"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Бұл арнаны көру үшін оңға түймесін басып, PIN кодын енгізіңіз"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Бұл бағдарламаны көру үшін оңға түймесін басып, PIN кодын енгізіңіз"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Бұл бағдарламаның жас бойынша шектеуі белгіленбеген.\nБұл бағдарламаны көру үшін оң жаққа бағытталған көрсеткіні басып, PIN кодын енгізіңіз"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Бұл бағдарламаға <xliff:g id="RATING">%1$s</xliff:g> бағасы қойылған.\nБұл бағдарламаны көру үшін \"Оңға\" түймесін басып, PIN кодын енгізіңіз."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Бұл арнаны көру үшін әдепкі Live TV қолданбасын пайдаланыңыз."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Бұл бағдарламаны көру үшін әдепкі Live TV қолданбасын пайдаланыңыз."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Бұл бағдарламаның жас бойынша шектеуі белгіленбеген.\nБұл бағдарламаны көру үшін әдепкі Live TV қолданбасын пайдаланыңыз."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Бұл бағдарлама <xliff:g id="RATING">%1$s</xliff:g> болып бағаланды.\nБұл бағдарламаны көру үшін әдепкі Live TV қолданбасын пайдаланыңыз."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Бағдарлама бөгелген"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Бұл бағдарламаның жас бойынша шектеуі белгіленбеген"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Бұл бағдарламаға <xliff:g id="RATING">%1$s</xliff:g> бағасы қойылған"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Тек аудио"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Cигнал әлсіз"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Интернетпен байланыс жоқ"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">Басқа арналар жазылып жатқандықтан, бұл арна <xliff:g id="END_TIME_1">%1$s</xliff:g> дейін ойнатылмайды. \n\nЖазып алу кестесін реттеу үшін \"Оң жақ\" түймесін басыңыз.</item>
+ <item quantity="one">Басқа арна жазылып жатқандықтан, бұл арна <xliff:g id="END_TIME_0">%1$s</xliff:g> дейін ойнатылмайды. \n\nЖазып алу кестесін реттеу үшін \"Оң жақ\" түймесін басыңыз.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Тақырыпсыз"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Арна бөгелген"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Жаңа"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Дереккөздер"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d арна</item>
+ <item quantity="one">%1$d арна</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Қолжетімді арна жоқ"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Жаңа"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Реттелмеген"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Қосымша дереккөздерді алу"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Тікелей эфир арналарын ұсынатын қолданбаларды шолу"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Жаңа арна көздері қолжетімді"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Жаңа арна көздерінде ұсынатын арналар бар.\nОларды қазір орнатыңыз немесе арна көздері параметрінде кейінірек орындаңыз."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Қазір орнату"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Жарайды, түсіндім"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>"Теледидар мәзіріне кіру үшін ТАҢДАУ"</b>" түймесін басыңыз."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"ТД кіріс сигналы табылмады"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"ТД кіріс сигналын табу мүмкін емес"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Тюнер түрі жарамсыз. Тюнер түрінің ТД кіріс сигналы үшін Тікелей эфир арналары қолданбасын іске қосыңыз."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Арнаға реттелмеді"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Бұл әрекетті орындайтын қолданба табылмады."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Барлық көз арналар жасырылған.\nКөру үшін кемінде бір арнаны таңдаңыз."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Бейне белгісіз себеппен қолжетімсіз болып тұр"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"КЕРІ пернесі қосылған құрылғыға арналған. Шығу үшін НЕГІЗГІ пернесін басыңыз."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Live TV үшін ТД тізімдерін оқу рұқсаты қажет."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Дерек көздерін орнату"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Live арналары қолданбалардағы ағынды арналармен қатар дәстүрлі теледидар арналарын да ұсынады. \n\nІсті бұрын орнатылған арна көздерін реттеуден бастаңыз. Тікелей эфир арналарын ұсынатын басқа қолданбаларды Google Play Store дүкенінен алуға болады."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Жазбалар және кестелер"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 минут"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 минут"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 сағат"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 сағат"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Жақындағы"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Жоспарланған"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Сериялар"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Басқалар"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Арнаны жазу мүмкін емес."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Бағдарламаны жазу мүмкін емес."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> бағдарламасын жазып алу жоспарланды"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> бағдарламасын қазірден бастап <xliff:g id="ENDTIME">%2$s</xliff:g> дейін жазу"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Толық кесте"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">Келесі %1$d күн бойы</item>
+ <item quantity="one">Келесі %1$d күн бойы</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d минут</item>
+ <item quantity="one">%1$d минут</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d жаңа жазба</item>
+ <item quantity="one">%1$d жаңа жазба</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d жазба</item>
+ <item quantity="one">%1$d жазба</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d жазба жоспарланды</item>
+ <item quantity="one">%1$d жазба жоспарланды</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Жазудан бас тарту"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Жазуды тоқтату"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Сағат"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Басынан бастап ойнату"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Ойнатуды жалғастыру"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Жою"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Жазбаларды жою"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Жалғастыру"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-маусым"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Кестені көру"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Толығырақ оқу"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Жазбаларды жою"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Жойғыңыз келетін серияларды таңдаңыз. Олар біржола жойылады және қалпына келтірілмейді."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Жоюға болатын жазбалар жоқ."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Көрген серияларды таңдау"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Барлық серияларды таңдау"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Барлық серияларды таңдаудан алып тастау"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> минут көрілді (жалпы ұзақтығы: <xliff:g id="DURATION">%2$d</xliff:g>)"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> секунд көрілді (жалпы ұзақтығы: <xliff:g id="DURATION">%2$d</xliff:g>)"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Ешқашан көрмеген жазбалар"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%1$d серия жойылды (жалпы саны: %2$d)</item>
+ <item quantity="one">%1$d серия жойылды (жалпы саны: %2$d)</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Маңыздылық"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Ең жоғары"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Ең төмен"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"№ <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Арналар"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Кез келген"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Маңыздылық деңгейін таңдау"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Бір мезгілде тым көп бағдарламаны жазып алу қажет болса, тек маңыздылығы жоғарылары ғана жазылады."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Сақтау"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Бір жолғы жазбалар ең маңызды болып табылады"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Тоқтату"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Жазу кестесін көру"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Тек осы бағдарлама"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"қазір - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Барлық сериялар..."</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Бәрібір жазып алу"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Орнына мына бағдарламаны жазу"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Бұл жазып алу кестесінен бас тарту"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Қазір көру"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Жазбалар жойылуда…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Жазып алуға болады"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Жазып алынады"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Жазу кестесінде қайшылық бар"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Жазылуда"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Жазу сәтсіз аяқталды"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Бағдарлама ақпараты оқылуда"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Соңғы жазбаларды көру"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> бағдарламасын жазу аяқталмады."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> және <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> бағдарламасын жазу аяқталмады."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> және <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> бағдарламасын жазу аяқталмады."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Жад жеткіліксіз болғандықтан, <xliff:g id="PROGRAMNAME">%1$s</xliff:g> бағдарламасын жазу аяқталмады."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Жад жеткіліксіз болғандықтан, <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> және <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> бағдарламасын жазу аяқталмады."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Жад жеткіліксіз болғандықтан, <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> және <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> бағдарламасын жазу аяқталмады."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR көбірек бос орынды қажет етеді"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Бағдарламаларды DVR арқылы жазып алуға болады. Алайда DVR жұмысы үшін құрылғыда бос орын жеткіліксіз. <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> ГБ не одан үлкен сыртқы дискіні жалғап, оны құрылғы жады ретінде форматтау қадамдарын орындаңыз."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Жадта орын жеткіліксіз"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Жадта орын жеткіліксіз болғандықтан, бұл бағдарлама жазылмайды. Кейбір бұрыннан бар жазбаларды жойыңыз."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Жад жоқ"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Жазу тоқтатылсын ба?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Жазылған мазмұн сақталады."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Осы бағдарламамен қайшылық тудырғандықтан, <xliff:g id="PROGRAMNAME">%1$s</xliff:g> жазу тоқтатылды. Жазып алынған мазмұн сақталады."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Жоспарланған, бірақ қайшылықтары бар"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Жазу басталды, бірақ қайшылықтары бар"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> жазылады."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> жазылуда."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> бағдарламасының кейбір бөліктері жазылмайды."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> және <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> бағдарламасының кейбір бөліктері жазылмайды."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> бағдарламаларының және тағы бір жоспарланған бағдарламаның кейбір бөліктері жазылмайды."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> бағдарламалары мен тағы %3$d бағдарламаның кейбір бөліктері жазылмайды.</item>
+ <item quantity="one"> <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> бағдарламалары мен жоспарланған тағы %3$d бағдарламаның кейбір бөліктері жазылмайды.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Нені жазып алғыңыз келеді?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Қаншалықты ұзақ жазасыз?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Әлдеқашан жоспарланған"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Бұл бағдарламаны жазып алу басқа уақытқа (<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>) әлдеқашан жоспарланған."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Бұрын жазылған"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Бұл бағдарлама бұрын жазылған және DVR кітапханасында бар."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Серияларды жазып алу жоспарланды"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> үшін <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> жазба жоспарланды.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> үшін <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> жазба жоспарланды.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> үшін <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> жазба жоспарланды. Олардың ішінде <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> серия қайшылықтарға байланысты жазылмайды.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> үшін <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> жазба жоспарланды. Ол қайшылықтарға байланысты жазылмайды.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> үшін <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> жазба жоспарланды. Бұл сериалдың және басқа сериалдың <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> сериясы қайшылықтарға байланысты жазылмайды.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> үшін <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> жазба жоспарланды. Бұл сериалдың және басқа сериалдың <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> сериясы қайшылықтарға байланысты жазылмайды.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> үшін <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> жазба жоспарланды. Басқа сериалдың 1 сериясы қайшылықтарға байланысты жазылмайды.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> үшін <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> жазба жоспарланды. Басқа сериалдың 1 сериясы қайшылықтарға байланысты жазылмайды.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> үшін <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> жазба .жоспарланды. Басқа сериалдың <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> сериясы қайшылықтарға байланысты жазылмайды.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> үшін <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> жазба .жоспарланды. Басқа сериалдың <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> сериясы қайшылықтарға байланысты жазылмайды.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Жазылған бағдарлама табылмады."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Қатысты жазбалар"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d жазба</item>
+ <item quantity="one">%1$d жазба</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" /  "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> бағдарламасы жазып алу кестесінен өшірілді"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Тюнер қайшылықтарына байланысты толық жазылмайды."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Тюнер қайшылықтарына байланысты жазылмайды."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Кестеде ешқандай жазып алу белгіленбеген.\nМұны бағдарлама нұсқаулығынан жоспарлауға болады."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d жазу қайшылығы</item>
+ <item quantity="one">%1$d жазу қайшылығы</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Сериялар параметрлері"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Серияларды жазуды бастау"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Серияларды жазуды тоқтату"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Серияларды жазу тоқтатылсын ба?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Жазылған серияларды DVR кітапханасынан алуға болады."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Тоқтату"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Ешқандай серия көрсетіліп жатқан жоқ."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Ешқандай серия қолжетімді емес.\nОларды қолжетімді болған кезде ғана жазып алуға болады."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d минут)</item>
+ <item quantity="one">(%1$d минут) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Бүгін"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Ертең"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Кеше"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"Бүгін <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Ертең <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Ұпай саны"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Жазылған бағдарламалар"</string>
+</resources>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
deleted file mode 100644
index 2a47972c..00000000
--- a/res/values-kk/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Ойын тетіктері"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Жақ-ғы арналар"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"ТД опциялары"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP опциялары"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Бұл арна үшін ойнатуды басқару элементтерін қол жетімсіз"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Ойнату немесе кідірту"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Жылдам алға айналдыру"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Кері айналдыру"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Келесі"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Алдыңғы"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Бағдарламалар нұс-ғы"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Жаңа арналар қол жетім."</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын ашу"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Жасырын титрлер"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Дисплей режимі"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Қосулы"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Өшірулі"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Мультиаудио"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Басқа арналар"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Параметрлер"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Көз"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Алмастыру"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Қосулы"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Өшірулі"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Дыбыс"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Негізгі"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP терезесі"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Орналасу"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Төменгі оң жақ"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Жоғарғы оң жақ"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Жоғарғы сол жақ"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Төменгі сол жақ"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Қатар"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Өлшем"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Үлкен"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Кішкентай"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Енгізу көзі"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ТД (антенна/кабель)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Бағдарлама туралы ақпарат жоқ"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Ақпарат жоқ"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Бөгелген арна"</string>
- <string name="default_language" msgid="4122326459624337928">"Белгісіз тіл"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Жасырын титрлер"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Өшірулі"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Пішімдеуді теңшеу"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Жасырын титрлер үшін жүйелік пар-ді орн."</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Дисплей режимі"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Мультиаудио"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"моно"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"стерео"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 көлемді"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 көлемді"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d арна"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Арналар тіз. тең."</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Топты таңдау"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Топтан таңдауды алу"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Топтау шарты"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Арна көзі"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Топтау шарты"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Бұл бағдарламаға тыйым салынған"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Бұл бағдарламаға <xliff:g id="RATING">%1$s</xliff:g> бағасы қойылған"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Кіріс автоматты түрде іздеуді қолдамайды"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"«<xliff:g id="TV_INPUT">%s</xliff:g>» үшін автоматты түрде іздеуді бастау мүмкін болмады"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Жасырын титрлер үшін жүйелік параметрлерді іске қосу мүмкін болмады."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d арна қосылды</item>
- <item quantity="one">%1$d арна қосылды</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Арналар қосылмаған"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Тюнер"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Ата-аналық бақылау"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Қосулы"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Өшірулі"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Арналар бөгелген"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Барлығын бөгеу"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Бәрін бөгеуден шығ."</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Жасырын арналар"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Бағдарлама шек-рі"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN кодын өзгерту"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Бағалау жүйелері"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Рейтингтер"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Бар. бағ. жүй-н көру"</string>
- <string name="other_countries" msgid="8342216398676184749">"Басқа елдер"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Ешқандай"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ешқандай"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Ешқандай"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Жоғары шектеулер"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Орташа шектеулер"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Төмен шектеулер"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Теңшелетін"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Мазмұн балалар үшін жарамды"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Үлкенірек балаларға жарамды мазмұн"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Мазмұн жасөспірімдерге жарамды"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Қолмен реттелетін шектеулер"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s және ішкі бағ-р"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Ішкі бағалар"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Бұл арнаны көру үшін PIN кодын енгізіңіз"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Бұл бағдарламаны көру үшін PIN кодын енгізіңіз"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Бұл бағдарламаға <xliff:g id="RATING">%1$s</xliff:g> бағасы берілген. Оны көру үшін PIN кодын енгізіңіз"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"PIN кодын енгізіңіз"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Ата-аналық бақылауды орнату үшін PIN кодын жасаңыз"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Жаңа PIN кодын енгізіңіз"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"PIN кодын растау"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Ағымдағы PIN кодын енгізіңіз"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">Қате PIN кодын 5 рет қате енгіздіңіз.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секундтан кейін қайталап көріңіз.</item>
- <item quantity="one">Қате PIN кодын 5 рет қате енгіздіңіз.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> секундтан кейін қайталап көріңіз.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"Бұл PIN қате болды. Әрекетті қайталаңыз."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Әрекетті қайталаңыз, PIN кодтары сәйкес емес"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Параметрлер"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Арналар тізімін теңшеу"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Бағдарлама нұсқаулығына арналған арналарды таңдау"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Арна көздері"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Жаңа арналар қосылды"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Ата-аналық бақылау"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Ашық бастапқы код лицензиялары"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Ашық бастапқы код лицензиялары"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Нұсқа"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Бұл арнаны көру үшін оңға түймесін басып, PIN кодын енгізіңіз"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Бұл бағдарламаны көру үшін оңға түймесін басып, PIN кодын енгізіңіз"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Бұл бағдарламаға <xliff:g id="RATING">%1$s</xliff:g> бағасы қойылған.\nБұл бағдарламаны көру үшін \"Оңға\" түймесін басып, PIN кодын енгізіңіз."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Бұл арнаны көру үшін әдепкі Live TV қолданбасын пайдаланыңыз."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Бұл бағдарламаны көру үшін әдепкі Live TV қолданбасын пайдаланыңыз."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Бұл бағдарлама <xliff:g id="RATING">%1$s</xliff:g> болып бағаланды.\nБұл бағдарламаны көру үшін әдепкі Live TV қолданбасын пайдаланыңыз."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Бағдарлама бөгелген"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Бұл бағдарламаға <xliff:g id="RATING">%1$s</xliff:g> бағасы қойылған"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Тек аудио"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Cигнал әлсіз"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Интернетпен байланыс жоқ"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Басқа арналар жазылып жатқандықтан, бұл арна <xliff:g id="END_TIME_1">%1$s</xliff:g> дейін ойнатылмайды. \n\nЖазып алу кестесін реттеу үшін \"Оң жақ\" түймесін басыңыз.</item>
- <item quantity="one">Басқа арна жазылып жатқандықтан, бұл арна <xliff:g id="END_TIME_0">%1$s</xliff:g> дейін ойнатылмайды. \n\nЖазып алу кестесін реттеу үшін \"Оң жақ\" түймесін басыңыз.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Тақырыпсыз"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Арна бөгелген"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Жаңа"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Дереккөздер"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d арна</item>
- <item quantity="one">%1$d арна</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Қолжетімді арна жоқ"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Жаңа"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Реттелмеген"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Қосымша дереккөздерді алу"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Тікелей эфир арналарын ұсынатын қолданбаларды шолу"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Жаңа арна көздері қолжетімді"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Жаңа арна көздерінде ұсынатын арналар бар.\nОларды қазір орнатыңыз немесе арна көздері параметрінде кейінірек орындаңыз."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Қазір орнату"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"Жарайды, түсіндім"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307"><b>"Теледидар мәзіріне кіру үшін ТАҢДАУ"</b>" түймесін басыңыз."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"ТД кіріс сигналы табылмады"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"ТД кіріс сигналын табу мүмкін емес"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP мүмкіндігіне қолдау көрсетілмейді"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP мүмкіндігімен көрсетуге болатын кіріс сигналы жоқ"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Тюнер түрі жарамсыз. Тюнер түрінің ТД кіріс сигналы үшін Тікелей эфир арналары қолданбасын іске қосыңыз."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Арнаға реттелмеді"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Бұл әрекетті орындайтын қолданба табылмады."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Барлық көз арналар жасырылған.\nКөру үшін кемінде бір арнаны таңдаңыз."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Бейне белгісіз себеппен қолжетімсіз болып тұр"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"КЕРІ пернесі қосылған құрылғыға арналған. Шығу үшін НЕГІЗГІ пернесін басыңыз."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Live TV үшін ТД тізімдерін оқу рұқсаты қажет."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Дерек көздерін орнату"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Live арналары қолданбалардағы ағынды арналармен қатар дәстүрлі теледидар арналарын да ұсынады. \n\nІсті бұрын орнатылған арна көздерін реттеуден бастаңыз. Тікелей эфир арналарын ұсынатын басқа қолданбаларды Google Play Store дүкенінен алуға болады."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Жазбалар және кестелер"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 минут"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 минут"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 сағат"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 сағат"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Жақындағы"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Жоспарланған"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Сериялар"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Басқалар"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Арнаны жазу мүмкін емес."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Бағдарламаны жазу мүмкін емес."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> бағдарламасын жазып алу жоспарланды"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> бағдарламасын қазірден бастап <xliff:g id="ENDTIME">%2$s</xliff:g> дейін жазу"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Толық кесте"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">Келесі %1$d күн бойы</item>
- <item quantity="one">Келесі %1$d күн бойы</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d минут</item>
- <item quantity="one">%1$d минут</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d жаңа жазба</item>
- <item quantity="one">%1$d жаңа жазба</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d жазба</item>
- <item quantity="one">%1$d жазба</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d жазба жоспарланды</item>
- <item quantity="one">%1$d жазба жоспарланды</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Сағат"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Басынан бастап ойнату"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Ойнатуды жалғастыру"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Жою"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Жазбаларды жою"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Жалғастыру"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-маусым"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Кестені көру"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Толығырақ оқу"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Жазбаларды жою"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Жойғыңыз келетін серияларды таңдаңыз. Олар біржола жойылады және қалпына келтірілмейді."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Жоюға болатын жазбалар жоқ."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Көрген серияларды таңдау"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Барлық серияларды таңдау"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Барлық серияларды таңдаудан алып тастау"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> минут көрілді (жалпы ұзақтығы: <xliff:g id="DURATION">%2$d</xliff:g>)"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> секунд көрілді (жалпы ұзақтығы: <xliff:g id="DURATION">%2$d</xliff:g>)"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Ешқашан көрмеген жазбалар"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%1$d серия жойылды (жалпы саны: %2$d)</item>
- <item quantity="one">%1$d серия жойылды (жалпы саны: %2$d)</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Маңыздылық"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Ең жоғары"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Ең төмен"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"№ <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Арналар"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Кез келген"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Маңыздылық деңгейін таңдау"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Бір мезгілде тым көп бағдарламаны жазып алу қажет болса, тек маңыздылығы жоғарылары ғана жазылады."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Сақтау"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Бір жолғы жазбалар ең маңызды болып табылады"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Бас тарту"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Бас тарту"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Жою"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Тоқтату"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Жазу кестесін көру"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Тек осы бағдарлама"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"қазір - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Барлық сериялар..."</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Бәрібір жазып алу"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Орнына мына бағдарламаны жазу"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Бұл жазып алу кестесінен бас тарту"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Қазір көру"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Жазып алуға болады"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Жазып алынады"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Жазу кестесінде қайшылық бар"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Жазылуда"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Жазу сәтсіз аяқталды"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Жазу кестелерін жасауға арналған оқу бағдарламалары"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Бағдарлама ақпараты оқылуда"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR көбірек бос орынды қажет етеді"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Бағдарламаларды DVR арқылы жазып алуға болады. Алайда DVR жұмысы үшін құрылғыда бос орын жеткіліксіз. <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> ГБ не одан үлкен сыртқы дискіні жалғап, оны құрылғы жады ретінде форматтау қадамдарын орындаңыз."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Жад жоқ"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR пайдаланатын жадтың бір бөлігі жоқ. DVR құрылғысын қайта іске қосу үшін бұрын пайдаланған сыртқы дискіні жалғаңыз. Сондай-ақ егер жад бұдан әрі қолжетімді болмаса, оны жоюыңызға болады."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Жад жойылсын ба?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Барлық жазылған мазмұндар мен кестелер жойылады."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Жазу тоқтатылсын ба?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Жазылған мазмұн сақталады."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Жоспарланған, бірақ қайшылықтары бар"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Жазу басталды, бірақ қайшылықтары бар"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> жазылады."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> жазылуда."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> бағдарламасының кейбір бөліктері жазылмайды."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> және <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> бағдарламасының кейбір бөліктері жазылмайды."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> бағдарламаларының және тағы бір жоспарланған бағдарламаның кейбір бөліктері жазылмайды."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> бағдарламалары мен тағы %3$d бағдарламаның кейбір бөліктері жазылмайды.</item>
- <item quantity="one"> <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> бағдарламалары мен жоспарланған тағы %3$d бағдарламаның кейбір бөліктері жазылмайды.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Нені жазып алғыңыз келеді?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Қаншалықты ұзақ жазасыз?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Әлдеқашан жоспарланған"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Бұл бағдарламаны жазып алу басқа уақытқа (<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>) әлдеқашан жоспарланған."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Бұрын жазылған"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Бұл бағдарлама бұрын жазылған және DVR кітапханасында бар."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Жазылған бағдарлама табылмады."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Қатысты жазбалар"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Бағдарлама сипаттамасы жоқ)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d жазба</item>
- <item quantity="one">%1$d жазба</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" /  "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> бағдарламасы жазып алу кестесінен өшірілді"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Тюнер қайшылықтарына байланысты толық жазылмайды."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Тюнер қайшылықтарына байланысты жазылмайды."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Кестеде ешқандай жазып алу белгіленбеген.\nМұны бағдарлама нұсқаулығынан жоспарлауға болады."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d жазу қайшылығы</item>
- <item quantity="one">%1$d жазу қайшылығы</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Сериялар параметрлері"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Серияларды жазуды бастау"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Серияларды жазуды тоқтату"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Серияларды жазу тоқтатылсын ба?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Жазылған серияларды DVR кітапханасынан алуға болады."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Тоқтату"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Ешқандай серия қолжетімді емес.\nОларды қолжетімді болған кезде ғана жазып алуға болады."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d минут)</item>
- <item quantity="one">(%1$d минут) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Бүгін"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Ертең"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Кеше"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"Бүгін <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Ертең <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Ұпай саны"</string>
-</resources>
diff --git a/res/values-km-v23/strings.xml b/res/values-km-rKH-v23/strings.xml
index 67c48f05..67c48f05 100644
--- a/res/values-km-v23/strings.xml
+++ b/res/values-km-rKH-v23/strings.xml
diff --git a/res/values-km/arrays.xml b/res/values-km-rKH/arrays.xml
index e46312b4..e46312b4 100644
--- a/res/values-km/arrays.xml
+++ b/res/values-km-rKH/arrays.xml
diff --git a/res/values-km/rating_system_strings.xml b/res/values-km-rKH/rating_system_strings.xml
index 8f5df6b3..8f5df6b3 100644
--- a/res/values-km/rating_system_strings.xml
+++ b/res/values-km-rKH/rating_system_strings.xml
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
new file mode 100644
index 00000000..ca2c337c
--- /dev/null
+++ b/res/values-km-rKH/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"ម៉ូណូ"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"ស្តេរ៉េអូ"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"បញ្ជាការចាក់"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"ឆានែល"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"ជម្រើសទូរទស្សន៍"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"ការបញ្ជាលើការចាក់មិនអាចប្រើបានទេសម្រាប់ឆានែលនេះ។"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ចាក់ ឬផ្អាក"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ទៅមុខរហ័ស"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"ខាថយក្រោយ"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"បន្ទាប់"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"មុន"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"ការ​ណែនាំ​កម្មវិធី"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"មានប៉ុស្តិ៍ថ្មី"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"បើក <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"ចំណងជើង​បិទ"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"របៀប​បង្ហាញ"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"ពហុ​អូឌីយ៉ូ"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"ទទួលយកប៉ុស្តិ៍ជាច្រើនទៀត"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"ការកំណត់"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ទូរទស្សន៍ (អង់តែន/ខ្សែកាប)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"មិន​មាន​ព័ត៌មាន​កម្មវិធី"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"មិនមានព័ត៌មានទេ"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"បណ្តាញដែលបានរារាំង"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"ភាសាមិនស្គាល់"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"អក្សរ​រត់ %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"បានបិទចំណងជើង"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"បិទ"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"ប្ដូររាងតាមត្រូវការ"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"កំណត់ចំណូលចិត្តប្រព័ន្ធទូលាយសម្រាប់ចំណងជើងបិទ"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"របៀប​បង្ហាញ"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"ពហុ​អូឌីយ៉ូ"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"ម៉ូណូ"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ស្តេរ៉េអូ"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 ជុំវិញ"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 ជុំវិញ"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"ឆានែល %d"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ប្ដូរបញ្ជីឆានែលតាម​តម្រូវការ"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ជ្រើស​ក្រុម"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"មិន​ជ្រើស​ក្រុម"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ដាក់​ជា​ក្រុម​តាម"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ប្រភព​ឆា​នែ​ល"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"ដាក់​ជា​ក្រុម​តាម"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"កម្មវិធីនេះត្រូវបានរារាំង"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"កម្មវិធីនេះមិនបានវាយតម្លៃទេ"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"កម្មវិធីនេះត្រូវបានវាយតម្លៃ <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"ការ​បញ្ចូល​មិន​គាំទ្រ​ការ​វិភាគ​រក​ស្វ័យ​ប្រវត្តិ"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"មិន​អាច​ចាប់ផ្ដើម​ការ​វិភាគ​ស្វ័យប្រវត្តិ​សម្រាប់ \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"មិន​អាច​ចាប់ផ្ដើម​ចំណូល​ចិត្ត​ប្រព័ន្ធ​ទូលាយ​សម្រាប់​ចំណងជើង​បិទ​ជិត​។"</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">បានបន្ថែមប៉ុស្តិ៍ %1$d</item>
+ <item quantity="one">បានបន្ថែមប៉ុស្តិ៍ %1$d</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"គ្មាន​ឆា​នែ​ល​បាន​បន្ថែម"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"ការ​ត្រួតពិនិត្យមេ"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"បើក"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"បិទ"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"បាន​ទប់ស្កាត់ឆានែល"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"ទប់ស្កាត់​​ទាំងអស់"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"មិន​ទប់ស្កាត់ទាំងអស់"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"ឆានែល​​ដែល​បាន​លាក់"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"ការដាក់កម្រិតកម្មវិធី"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"ប្ដូរ​កូដ PIN"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"ប្រព័ន្ធ​វាយ​តម្លៃ"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"វាយតម្លៃ"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"មើលប្រព័ន្ធវាយតម្លៃទាំងអស់"</string>
+ <string name="other_countries" msgid="8342216398676184749">"ប្រទេសផ្សេងទៀត"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"គ្មាន"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"គ្មាន"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"មិនបានវាយតម្លៃ"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"ទប់ស្កាត់កម្មវិធីដែលមិនបានវាយតម្លៃ"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"គ្មាន"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"ការ​ដាក់កម្រិត​ខ្ពស់"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"ការដាក់កម្រិតមធ្យម"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"ការ​ដាក់​កម្រិត​ទាប"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"តាម​តម្រូវ​ការ"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"មាតិកា​សមស្រប​សម្រាប់​កុមារ"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"មាតិកា​សមស្រប​សម្រាប់​កុមារ​ធំៗ"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"មាតិកា​សមស្រប​សម្រាប់​យុវវ័យ"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"ការ​ដាក់កម្រិត​ដោយ​ដៃ"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s និងការវាតម្លៃរង"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"ការ​វាយ​តម្លៃ​រង"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"បញ្ចូល​កូដ PIN របស់​អ្នក​ដើម្បី​មើល​​ឆានែល​នេះ"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"បញ្ចូល​កូដ PIN របស់​អ្នក​ដើម្បី​មើល​កម្មវិធី​នេះ"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"កម្មវិធីនេះត្រូវបានវាយតម្លៃ <xliff:g id="RATING">%1$s</xliff:g>។ បញ្ចូលកូដ PIN របស់អ្នកដើម្បីមើលកម្មវិធីនេះ"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"កម្មវិធីនេះមិនបានវាយតម្លៃទេ។ បញ្ចូលកូដ PIN របស់អ្នក ដើម្បីមើលកម្មវិធីនេះ"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"បញ្ចូល​កូដ PIN របស់​អ្នក"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"ដើម្បី​កំណត់​ការ​ពិនិត្យ​របស់​ឪពុកម្ដាយ អ្នក​ត្រូវ​បង្កើត​កូដ PIN"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"បញ្ចូល​កូដ PIN ថ្មី"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"បញ្ជាក់​កូដ PIN របស់​អ្នក"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"បញ្ចូល​កូដ PIN បច្ចុប្បន្ន​របស់​អ្នក"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">អ្នកបានបញ្ចូលកូដ PIN ខុស 5 ដង។\nសូមព្យាយាមម្តងទៀតក្នុងរយៈពេល <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> វិនាទី។</item>
+ <item quantity="one">អ្នកបានបញ្ចូលកូដ PIN ខុស 5 ដង។\nសូមព្យាយាមម្តងទៀតក្នុងរយៈពេល <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> វិនាទី។</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"កូដ PIN មិន​ត្រឹមត្រូវ។ ព្យាយាម​ម្ដងទៀត។"</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"ព្យាយាម​ម្ដង​ទៀត កូដ​ PIN មិន​ដូច​គ្នា"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"បញ្ចូល​លេខ​កូដ​តំបន់​របស់អ្នក។"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"កម្មវិធី​ប៉ុស្តិ៍​ផ្សាយ​ផ្ទាល់​នឹង​ប្រើ​លេខ​កូដ​តំបន់ ដើម្បី​ផ្តល់ជូន​នូវ​ការ​ណែនាំ​អំពីកម្មវិធី​ទាំងស្រុង​សម្រាប់​ប៉ុស្តិ៍​ទូរទស្សន៍។"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"បញ្ចូល​លេខកូដ​តំបន់​របស់​អ្នក"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"លេខកូដ​តំបន់​មិនត្រឹមត្រូវ​ទេ"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"ការកំណត់"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ប្ដូរបញ្ជីប៉ុស្តិ៍តាមបំណង"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ជ្រើសប៉ុស្តិ៍សម្រាប់ការណែនាំកម្មវិធីរបស់អ្នក"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ប្រភពប៉ុស្តិ៍"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"មានប៉ុស្តិ៍ថ្មី"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"ការគ្រប់គ្រងដោយមាតាបិតា"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"ការថតទុកមើលពេលក្រោយ"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"ថតខណៈពេលកំពុងទស្សនា ដើម្បីឲ្យអ្នកអាចផ្អាក ឬខាកម្មវិធីផ្សាយ​​ផ្ទាល់ថយក្រោយបាន។\nព្រមាន៖ វាអាចកាត់បន្ថយអាយុកាលប្រើប្រាស់ទំហំផ្ទុកខាងក្នុង ដោយសារការប្រើប្រាស់ទំហំផ្ទុកយ៉ាងច្រើន។"</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"អាជ្ញាប័ណ្ណប្រភពកូដបើកចំហ"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"ផ្ញើមតិស្ថាបនា"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"កំណែ"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"ដើម្បី​មើល​ឆានែល​នេះ អ្នក​ត្រូវ​ចុច​កណ្ដុរស្ដាំ រួច​បញ្ចូល​កូដ PIN របស់​អ្នក"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"ដើម្បី​មើល​កម្មវិធី​នេះ អ្នក​ត្រូវ​ចុច​កណ្ដុរស្ដាំ រួច​បញ្ចូល​កូដ PIN របស់​អ្នក"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"កម្មវិធីនេះមិនបានវាយតម្លៃទេ។\nដើម្បីមើលកម្មវិធីនេះ សូមចុច ស្ដាំ រួចបញ្ចូលកូដ PIN របស់អ្នក"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"កម្មវិធីនេះត្រូវបានវាយតម្លៃ <xliff:g id="RATING">%1$s</xliff:g>។\n ដើម្បីមើលកម្មវិធីនេះ សូមចុច ស្តាំ រួចបញ្ចូលកូដ PIN របស់អ្នក។"</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ដើម្បីមើលប៉ុស្តិ៍នេះ សូមប្រើកម្មវិធីទូរទស្សន៍ផ្សាយផ្ទាល់លំនាំដើម"</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ដើម្បីមើលកម្មវិធីនេះ សូមប្រើកម្មវិធីទូរទស្សន៍ផ្សាយផ្ទាល់លំនាំដើម"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"កម្មវិធីនេះមិនបានវាយតម្លៃទេ។\nដើម្បីមើលកម្មវិធីនេះ សូមប្រើកម្មវិធីទូរទស្សន៍ផ្សាយផ្ទាល់លំនាំដើម។"</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"កម្មវិធីនេះត្រូវបានវាយតម្លៃ <xliff:g id="RATING">%1$s</xliff:g>\nដើម្បីមើលកម្មវិធីនេះ សូមប្រើកម្មវិធីទូរទស្សន៍ផ្សាយផ្ទាល់លំនាំដើម"</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"កម្មវិធី​នេះ​ត្រូវ​បាន​ទប់ស្កាត់"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"កម្មវិធីនេះមិនបានវាយតម្លៃទេ"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"កម្មវិធីនេះត្រូវបានវាយតម្លៃ <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"តែ​អូឌីយ៉ូ​ប៉ុណ្ណោះ"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"សញ្ញា​ខ្សោយ"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"គ្មានការតភ្ជាប់អ៊ីនធឺណិតទេ"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">ប៉ុស្តិ៍នេះមិនអាចចាក់បានទេរហូតដល់ម៉ោង <xliff:g id="END_TIME_1">%1$s</xliff:g> ដោយសារតែប៉ុស្តិ៍ផ្សេងទៀតកំពុងត្រូវបានថត។ \n\nចុច ស្តាំ ដើម្បីកែសម្រួលកាលវិភាគថត។</item>
+ <item quantity="one">ប៉ុស្តិ៍នេះមិនអាចចាក់បានទេរហូតដល់ម៉ោង <xliff:g id="END_TIME_0">%1$s</xliff:g> ដោយសារតែប៉ុស្តិ៍ផ្សេងទៀតកំពុងត្រូវបានថត។ \n\nចុច ស្តាំ ដើម្បីកែសម្រួលកាលវិភាគថត។</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"គ្មាន​ចំណងជើង"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"បាន​ទប់​ស្កាត់​ឆានែល"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"ថ្មី"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"ប្រភព"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">ប៉ុស្តិ៍ %1$d</item>
+ <item quantity="one">ប៉ុស្តិ៍ %1$d</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"មិនមានប៉ុស្តិ៍ទេ"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"ថ្មី"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"មិន​បាន​កំណត់"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"ទទួលយកប្រភពច្រើនទៀត"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"រុករកកម្មវិធីដែលមានផ្តល់ជូនប៉ុស្តិ៍ផ្សាយផ្ទាល់"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"មានផ្តល់ជូនប្រភពប៉ុស្តិ៍ថ្មី"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"ប្រភពប៉ុស្តិ៍ថ្មីមានប៉ុស្តិ៍ដែលត្រូវផ្តល់ជូន។\nដំឡើងប៉ុស្តិ៍ទាំងនោះឥឡូវនេះ ឬដំឡើងពេលក្រោយនៅក្នុងការកំណត់ប្រភពប៉ុស្តិ៍។"</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"ដំឡើងឥឡូវនេះ"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"យល់​ហើយ"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>"ចុច ជ្រើសរើស"</b>" ដើម្បីចូលប្រើម៉ឺនុយទូរទស្សន៍។"</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"រកមិនឃើញបញ្ចូលទូរទស្សន៍ទេ"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"រកមិនឃើញបញ្ចូលទូរទស្សន៍ទេ"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ប្រភេទឧបករណ៍ចាប់ប៉ុស្តិ៍មិនសមស្រប។ សូមចាប់ផ្តើមដំណើរការកម្មវិធី ប៉ុស្តិ៍ផ្សាយផ្ទាល់ សម្រាប់ធាតុបញ្ជូលទូរទស្សន៍ប្រភេទឧបករណ៍ចាប់ប៉ុស្តិ៍។"</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"កាកែសម្រួលប៉ុស្តិ៍បានបរាជ័យ"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"រកមិនឃើញកម្មវិធីដើម្បីគ្រប់គ្រងសកម្មភាពនេះទេ។"</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"រាល់​​ឆានែល​ប្រភព​គឺ​​លាក់​។ \n ជ្រើស​ឆា​នែ​ល​យ៉ាង​ហោច​ណាស់​មួយ​​ដើម្បី​​មើល​។"</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"មិនបានរំពឹងថាមិនមានវីដេអូនេះទេ"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"ប៊ូតុង​ថយក្រោយ​សម្រាប់​ឧបករណ៍​ដែល​បាន​ភ្ជាប់។ ចុច​ប៊ូតុង​ដើម ដើម្បី​ចាកចេញ។"</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"ប៉ុស្តិ៍ផ្សាយផ្ទាល់ត្រូវការសិទ្ធិអនុញ្ញាតដើម្បីអានបញ្ជីទូរទស្សន៍។"</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"កំណត់ប្រភពរបស់អ្នក"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"ប៉ុស្តិ៍ផ្សាយផ្ទាល់ផ្សាភ្ជាប់បទពិសោធន៍ប្រើប្រាស់ប៉ុស្តិ៍ទូរទស្សន៍លក្ខណៈបុរាណជាមួយប៉ុស្តិ៍ស្រ្ទីមដែលផ្តល់ដោយកម្មវិធី។ \n\nចាប់ផ្តើមដោយកំណត់ប្រភពប៉ុស្តិ៍ដែលបានដំឡើងរួចហើយ។ ឬរុករកក្នុងហាង Google Play ដើម្បីរកកម្មវិធីច្រើនទៀតដែលផ្តល់ជូនប៉ុស្តិ៍ផ្សាយផ្ទាល់។"</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"ការថត និងកាលវិភាក"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 នាទី"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 នាទី"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ម៉ោង"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ម៉ោង"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"ថ្មីៗ"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"បាន​កំណត់​ពេល"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"ស៊េរី"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"ផ្សេងៗ"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"មិនអាចថតប៉ុស្តិ៍នេះបានទេ"</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"មិនអាចថតកម្មវិធីនេះបានទេ"</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ត្រូវបានកំណត់ពេលដើម្បីថត"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ការថត <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ពីឥឡូវនេះដល់ <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"កាលវិភាគពេញហើយ"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">%1$d ថ្ងៃបន្ទាប់</item>
+ <item quantity="one">%1$d ថ្ងៃបន្ទាប់</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d នាទី</item>
+ <item quantity="one">%1$d នាទី</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">ការថតថ្មី %1$d</item>
+ <item quantity="one">ការថតថ្មី %1$d</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">ការថត %1$d</item>
+ <item quantity="one">ការថត %1$d</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">ការថតដែលបានកំណត់ពេល %1$d</item>
+ <item quantity="one">ការថតដែលបានកំណត់ពេល %1$d</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"បោះបង់ការថត"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"បញ្ឈប់ការថត"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"ទស្សនា"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"ចាក់ពីដំបូង"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"ចាក់​បន្ត"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"លុប"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"លុបការថត"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"បន្ត"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"វគ្គ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"មើលកាលវិភាគ"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"អាន​បន្ថែម"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"លុបការថត"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"ជ្រើសភាគដែលអ្នកចង់លុប។ ពួកវាមិនអាចស្តារឡើវិញបានទេបន្ទាប់ពីលុបរួចហើយ។"</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"មិនមានការថតដែលត្រូវលុបទេ"</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"ជ្រើសភាគដែលបានមើល"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"ជ្រើសភាគទាំងអស់"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"ដោះការជ្រើសភាគទាំងអស់"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"បានមើល <xliff:g id="WATCHED">%1$d</xliff:g> នៅនាទីទី <xliff:g id="DURATION">%2$d</xliff:g>"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"បានមើល <xliff:g id="WATCHED">%1$d</xliff:g> នៅវិនាទីទី <xliff:g id="DURATION">%2$d</xliff:g>"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"មិនដែលមើល"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">ភាគចំនួន %1$d ក្នុងចំណោម %2$d ត្រូវបានលុប</item>
+ <item quantity="one">ភាគចំនួន %1$d ក្នុងចំណោម %2$d ត្រូវបានលុប</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"អាទិភាព"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ខ្ពស់បំផុត"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ទាបបំផុត"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"លេខ <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ប៉ុស្តិ៍"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"មួយណាក៏បាន"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"ជ្រើសអាទិភាព"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"នៅពេលដែលមានកម្មវិធីដែលត្រូវថតច្រើនពេកក្នុងពេលតែមួយ នោះមានតែកម្មវិធីដែលមានអាទិភាពខ្ពស់ជាងប៉ុណ្ណោះដែលនឹងត្រូវថត។"</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"រក្សាទុក"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ការថតមួយដងមានអាទិភាពខ្ពស់បំផុត"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"បញ្ឈប់"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"មើលកាលវិភាគថត"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"កម្មវិធីមួយនេះ"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ឥឡូវនេះ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"វគ្គទាំងមូល…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"កាលវិភាគទោះយ៉ាងណាក៏ដោយ"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"ថតកម្មវិធីនេះជំនួសវិញ"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"បោះបង់ការថតនេះ"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"មើលឥឡូវនេះ"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"លុបការថត…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"អាចថតបាន"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"បានកំណត់ពេលការថត"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ការថតជាន់ម៉ោងគ្នា"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ការថត"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"បានបរាជ័យក្នុងការថត"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"កំពុងអានកម្មវិធី"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"មើលការថតថ្មីៗ"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"ការថត <xliff:g id="PROGRAMNAME">%1$s</xliff:g> មិនទាន់បញ្ចប់ទេ។"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"ការថត <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> និង <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> មិនទាន់បញ្ចប់ទេ។"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"ការថត <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> និង <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> មិនទាន់បញ្ចប់ទេ។"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"ការថត <xliff:g id="PROGRAMNAME">%1$s</xliff:g> មិនបានបញ្ចប់ទេ ដោយសារមិនមានទំហំផ្ទុកគ្រប់គ្រាន់។"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"ការថត <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> និង <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> មិនបានបញ្ចប់ទេ ដោយសារមិនមានទំហំផ្ទុកគ្រប់គ្រាន់។"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"ការថត <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> និង <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> មិនបានបញ្ចប់ទេ ដោយសារមិនមានទំហំផ្ទុកគ្រប់គ្រាន់។"</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR ត្រូវការទំហំផ្ទុកបន្ថែមទៀត"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"អ្នកនឹងអាចថតកម្មវិធីដោយប្រើ DVR។ ទោះបីជាយ៉ាងណាក៏ដោយ ឥឡូវនេះមិនមានទំហំផ្ទុកគ្រប់គ្រាន់នៅលើឧបករណ៍របស់អ្នកដើម្បីអនុញ្ញាតឲ្យ DVR ដំណើរការនោះទេ។ សូមភ្ជាប់ទៅឧបករណ៍ផ្ទុកខាងក្រៅដែលមានទំហំផ្ទុក <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB ឬធំជាងនេះ បន្ទាប់មកអនុវត្តតាមជំហានទាំងនេះដើម្បីសម្អាតវាក្នុងនាមជាឧបករណ៍ផ្ទុក។"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"មិនមានទំហំផ្ទុកគ្រប់គ្រាន់ទេ"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"មិនអាចថតកម្មវិធីនេះបានទេ ដោយសារតែមិនមានទំហំផ្ទុកគ្រប់គ្រាន់។ សូមសាកល្បងលុបការថតមួយចំនួនដែលមានស្រាប់។"</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"ឧបករណ៍ផ្ទុកដែលបានបាត់"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"បញ្ឈប់ការថតឬ?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"មាតិកាដែលបានថតនឹងត្រូវបានរក្សាទុក"</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"ការថត <xliff:g id="PROGRAMNAME">%1$s</xliff:g> នឹងត្រូវបានបញ្ឈប់ ដោយសារតែវាជាន់ម៉ោងគ្នាជាមួយកម្មវិធីនេះ។ មាតិកាដែលបានថតនេះនឹងត្រូវបានរក្សាទុក។"</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ការថតបានកំណត់ពេលហើយ ប៉ុន្តែមានម៉ោងជាន់គ្នា"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ការថតបានចាប់ផ្តើមប៉ុន្តែវាជាន់គ្នា"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> នឹងត្រូវបានថត។"</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> កំពុងត្រូវបានថត។"</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"ផ្នែកមួយចំនួននៃ <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> នឹងមិនត្រូវបានថតទេ។"</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"ផ្នែកមួយចំនួននៃ <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> និង <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> នឹងមិនត្រូវបានថតទេ។"</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"ផ្នែកមួយចំនួននៃ <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> និងកាលវិភាគមួយទៀតនឹងមិនត្រូវបានថតទេ។"</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other">ផ្នែកមួយចំនួននៃ <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> និងកាលវិភាគ %3$d ទៀតនឹងមិនត្រូវបានថតទេ។</item>
+ <item quantity="one">ផ្នែកមួយចំនួននៃ <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> និងកាលវិភាគ %3$d ទៀតនឹងមិនត្រូវបានថតទេ។</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"តើអ្នកចង់ថតដែរទេ?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"តើអ្នកចង់ថតរយៈពេលប៉ុន្មានដែរ?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"បានកំណត់ពេលរួចហើយ"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"កម្មវិធីដូចគ្នានេះត្រូវបានកំណត់ពេលថតរួចហើយនៅម៉ោង <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"បានថតរួចហើយ"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"កម្មវិធីនេះត្រូវបានថតរួចហើយ។ វាអាចប្រើបាននៅក្នុងបណ្ណាល័យ DVR ។"</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"បានកំណត់ពេលថតវគ្គ"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">ការថតចំនួន <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ត្រូវបានកំណត់ពេលសម្រាប់ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ។</item>
+ <item quantity="one">ការថតចំនួន <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ត្រូវបានកំណត់ពេលសម្រាប់ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ។</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">ការថតចំនួន <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ត្រូវបានកំណត់ពេលសម្រាប់ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ។ ការថតចំនួន <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> ក្នុងចំណោមនោះនឹងមិនត្រូវបានថតទេ ដោយសារម៉ោងជាន់គ្នា។</item>
+ <item quantity="one">ការថតចំនួន <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ត្រូវបានកំណត់ពេលសម្រាប់ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ។ វានឹងមិនត្រូវបានថតទេ ដោយសារម៉ោងជាន់គ្នា។</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">ការថតចំនួន <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ត្រូវបានកំណត់ពេលសម្រាប់ <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ។ ភាគចំនួន <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> នៃវគ្គនេះ និងវគ្គផ្សេងទៀតនឹងមិនត្រូវបានថតទេ ដោយសារម៉ោងជាន់គ្នា។</item>
+ <item quantity="one">ការថតចំនួន <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ត្រូវបានកំណត់ពេលសម្រាប់ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ។ ភាគចំនួន <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> នៃវគ្គនេះ និងវគ្គផ្សេងទៀតនឹងមិនត្រូវបានថតទេ ដោយសារម៉ោងជាន់គ្នា។</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">ការថតចំនួន <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ត្រូវបានកំណត់ពេលសម្រាប់ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ។ ភាគចំនួន 1 នៃវគ្គផ្សេងនឹងមិនត្រូវបានថតទេ ដោយសារម៉ោងជាន់គ្នា។</item>
+ <item quantity="one">ការថតចំនួន <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ត្រូវបានកំណត់ពេលសម្រាប់ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ។ ភាគចំនួន 1 នៃវគ្គផ្សេងនឹងមិនត្រូវបានថតទេ ដោយសារម៉ោងជាន់គ្នា។</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">ការថតចំនួន <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ត្រូវបានកំណត់ពេលសម្រាប់ <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ។ ភាគចំនួន <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> នៃវគ្គផ្សេងនឹងមិនត្រូវបានថតទេ ដោយសារម៉ោងជាន់គ្នា។</item>
+ <item quantity="one">ការថតចំនួន <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ត្រូវបានកំណត់ពេលសម្រាប់ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ។ ភាគចំនួន <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> នៃវគ្គផ្សេងនឹងមិនត្រូវបានថតទេ ដោយសារម៉ោងជាន់គ្នា។</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"រកមិនឃើញកម្មវិធីដែលបានថតទេ"</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ការថតដែលពាក់ព័ន្ធ"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">ការថត %1$d</item>
+ <item quantity="one">ការថត %1$d</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ត្រូវបានលុបចេញពីកាលវិភាគថត"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"នឹងមិនត្រូវបានថតពេញលេញនោះទេដោយសារតែអង្គរាវប៉ុស្តិ៍ជាន់គ្នា។"</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"នឹងមិនត្រូវបានថតនោះទេដោយសារតែអង្គរាវប៉ុស្តិ៍ជាន់គ្នា។"</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"មិនទាន់មានការថតនៅក្នុងកាលវិភាគនៅឡើយទេ។\nអ្នកអាចកំណត់ពេលថតចេញពីការណែនាំកម្មវិធីនេះ។"</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">ការជាន់ម៉ោងថត %1$d</item>
+ <item quantity="one">ការជាន់ម៉ោងថត %1$d</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"ការកំណត់វគ្គ"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"ចាប់ផ្តើមថតវគ្គ"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"ឈប់ថតវគ្គ"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"បញ្ឈប់ការថតវគ្គឬ?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ភាគដែលបានថតនឹងនៅតែមាននៅក្នុងបណ្ណាល័យ DVR ។"</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"បញ្ឈប់"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ឥឡូវនេះមិនមានការផ្សាយភាគថ្មីទេ។"</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"មិនមានផ្តល់ជូនភាគណាមួយទេ។\nពួកវានឹងត្រូវបានថតបន្ទាប់ពីមានផ្តល់ជូន។"</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d នាទី)</item>
+ <item quantity="one">(%1$d នាទី) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"ថ្ងៃនេះ"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"ថ្ងៃស្អែក"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"ម្សិលមិញ"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ថ្ងៃនេះ"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ថ្ងៃស្អែក"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"ពិន្ទុ"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"កម្មវិធីដែល​បានថត"</string>
+</resources>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
deleted file mode 100644
index 98fa13f5..00000000
--- a/res/values-km/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"ម៉ូណូ"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"ស្តេរ៉េអូ"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"បញ្ជាការចាក់"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"ឆានែល​ថ្មីៗ"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"ជម្រើសទូរទស្សន៍"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"ជម្រើស PIP"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"ការបញ្ជាលើការចាក់មិនអាចប្រើបានទេសម្រាប់ឆានែលនេះ។"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ចាក់ ឬផ្អាក"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ទៅមុខរហ័ស"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"ខាថយក្រោយ"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"បន្ទាប់"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"មុន"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"ការ​ណែនាំ​កម្មវិធី"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"មានប៉ុស្តិ៍ថ្មី"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"បើក <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"ចំណងជើង​បិទ"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"របៀប​បង្ហាញ"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"បើក"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"បិទ"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"ពហុ​អូឌីយ៉ូ"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"ទទួលយកប៉ុស្តិ៍ជាច្រើនទៀត"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"ការកំណត់"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"ប្រភព"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"ប្ដូរ"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"បើក"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"បិទ"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"សំឡេង"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"ចម្បង"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"ផ្ទាំងវិនដូ PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"ប្លង់"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"បាតខាងស្តាំ"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"ចុងខាងស្តាំ"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"ចុងខាងឆ្វេង"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"បាតខាងឆ្វេង"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"នៅក្បែរគ្នា"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"ទំហំ"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"ធំ"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"តូច"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"ប្រភព​ចូល"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ទូរទស្សន៍ (អង់តែន/ខ្សែកាប)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"មិន​មាន​ព័ត៌មាន​កម្មវិធី"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"មិនមានព័ត៌មានទេ"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"បណ្តាញដែលបានរារាំង"</string>
- <string name="default_language" msgid="4122326459624337928">"ភាសាមិនស្គាល់"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"បានបិទចំណងជើង"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"បិទ"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"ប្ដូររាងតាមត្រូវការ"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"កំណត់ចំណូលចិត្តប្រព័ន្ធទូលាយសម្រាប់ចំណងជើងបិទ"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"របៀប​បង្ហាញ"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"ពហុ​អូឌីយ៉ូ"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"ម៉ូណូ"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ស្តេរ៉េអូ"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 ជុំវិញ"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 ជុំវិញ"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"ឆានែល %d"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ប្ដូរបញ្ជីឆានែលតាម​តម្រូវការ"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ជ្រើស​ក្រុម"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"មិន​ជ្រើស​ក្រុម"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ដាក់​ជា​ក្រុម​តាម"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ប្រភព​ឆា​នែ​ល"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"ដាក់​ជា​ក្រុម​តាម"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"កម្មវិធីនេះត្រូវបានរារាំង"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"កម្មវិធីនេះត្រូវបានវាយតម្លៃ <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"ការ​បញ្ចូល​មិន​គាំទ្រ​ការ​វិភាគ​រក​ស្វ័យ​ប្រវត្តិ"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"មិន​អាច​ចាប់ផ្ដើម​ការ​វិភាគ​ស្វ័យប្រវត្តិ​សម្រាប់ \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"មិន​អាច​ចាប់ផ្ដើម​ចំណូល​ចិត្ត​ប្រព័ន្ធ​ទូលាយ​សម្រាប់​ចំណងជើង​បិទ​ជិត​។"</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">បានបន្ថែមប៉ុស្តិ៍ %1$d</item>
- <item quantity="one">បានបន្ថែមប៉ុស្តិ៍ %1$d</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"គ្មាន​ឆា​នែ​ល​បាន​បន្ថែម"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"ការ​ត្រួតពិនិត្យមេ"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"បើក"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"បិទ"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"បាន​ទប់ស្កាត់ឆានែល"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"ទប់ស្កាត់​​ទាំងអស់"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"មិន​ទប់ស្កាត់ទាំងអស់"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"ឆានែល​​ដែល​បាន​លាក់"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"ការដាក់កម្រិតកម្មវិធី"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"ប្ដូរ​កូដ PIN"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"ប្រព័ន្ធ​វាយ​តម្លៃ"</string>
- <string name="option_ratings" msgid="4009116954188688616">"វាយតម្លៃ"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"មើលប្រព័ន្ធវាយតម្លៃទាំងអស់"</string>
- <string name="other_countries" msgid="8342216398676184749">"ប្រទេសផ្សេងទៀត"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"គ្មាន"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"គ្មាន"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"គ្មាន"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"ការ​ដាក់កម្រិត​ខ្ពស់"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"ការដាក់កម្រិតមធ្យម"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"ការ​ដាក់​កម្រិត​ទាប"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"តាម​តម្រូវ​ការ"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"មាតិកា​សមស្រប​សម្រាប់​កុមារ"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"មាតិកា​សមស្រប​សម្រាប់​កុមារ​ធំៗ"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"មាតិកា​សមស្រប​សម្រាប់​យុវវ័យ"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"ការ​ដាក់កម្រិត​ដោយ​ដៃ"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s និងការវាតម្លៃរង"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"ការ​វាយ​តម្លៃ​រង"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"បញ្ចូល​កូដ PIN របស់​អ្នក​ដើម្បី​មើល​​ឆានែល​នេះ"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"បញ្ចូល​កូដ PIN របស់​អ្នក​ដើម្បី​មើល​កម្មវិធី​នេះ"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"កម្មវិធីនេះត្រូវបានវាយតម្លៃ <xliff:g id="RATING">%1$s</xliff:g>។ បញ្ចូលកូដ PIN របស់អ្នកដើម្បីមើលកម្មវិធីនេះ"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"បញ្ចូល​កូដ PIN របស់​អ្នក"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"ដើម្បី​កំណត់​ការ​ពិនិត្យ​របស់​ឪពុកម្ដាយ អ្នក​ត្រូវ​បង្កើត​កូដ PIN"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"បញ្ចូល​កូដ PIN ថ្មី"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"បញ្ជាក់​កូដ PIN របស់​អ្នក"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"បញ្ចូល​កូដ PIN បច្ចុប្បន្ន​របស់​អ្នក"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">អ្នកបានបញ្ចូលកូដ PIN ខុស 5 ដង។\nសូមព្យាយាមម្តងទៀតក្នុងរយៈពេល <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> វិនាទី។</item>
- <item quantity="one">អ្នកបានបញ្ចូលកូដ PIN ខុស 5 ដង។\nសូមព្យាយាមម្តងទៀតក្នុងរយៈពេល <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> វិនាទី។</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"កូដ PIN មិន​ត្រឹមត្រូវ។ ព្យាយាម​ម្ដងទៀត។"</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"ព្យាយាម​ម្ដង​ទៀត កូដ​ PIN មិន​ដូច​គ្នា"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"ការកំណត់"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ប្ដូរបញ្ជីប៉ុស្តិ៍តាមបំណង"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ជ្រើសប៉ុស្តិ៍សម្រាប់ការណែនាំកម្មវិធីរបស់អ្នក"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ប្រភពប៉ុស្តិ៍"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"មានប៉ុស្តិ៍ថ្មី"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"ការគ្រប់គ្រងដោយមាតាបិតា"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"អាជ្ញាប័ណ្ណប្រភពកូដបើកចំហ"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"អាជ្ញាប័ណ្ណប្រភពកូដចំហ"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"កំណែ"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"ដើម្បី​មើល​ឆានែល​នេះ អ្នក​ត្រូវ​ចុច​កណ្ដុរស្ដាំ រួច​បញ្ចូល​កូដ PIN របស់​អ្នក"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"ដើម្បី​មើល​កម្មវិធី​នេះ អ្នក​ត្រូវ​ចុច​កណ្ដុរស្ដាំ រួច​បញ្ចូល​កូដ PIN របស់​អ្នក"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"កម្មវិធីនេះត្រូវបានវាយតម្លៃ <xliff:g id="RATING">%1$s</xliff:g>។\n ដើម្បីមើលកម្មវិធីនេះ សូមចុច ស្តាំ រួចបញ្ចូលកូដ PIN របស់អ្នក។"</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ដើម្បីមើលប៉ុស្តិ៍នេះ សូមប្រើកម្មវិធីទូរទស្សន៍ផ្សាយផ្ទាល់លំនាំដើម"</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ដើម្បីមើលកម្មវិធីនេះ សូមប្រើកម្មវិធីទូរទស្សន៍ផ្សាយផ្ទាល់លំនាំដើម"</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"កម្មវិធីនេះត្រូវបានវាយតម្លៃ <xliff:g id="RATING">%1$s</xliff:g>\nដើម្បីមើលកម្មវិធីនេះ សូមប្រើកម្មវិធីទូរទស្សន៍ផ្សាយផ្ទាល់លំនាំដើម"</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"កម្មវិធី​នេះ​ត្រូវ​បាន​ទប់ស្កាត់"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"កម្មវិធីនេះត្រូវបានវាយតម្លៃ <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"តែ​អូឌីយ៉ូ​ប៉ុណ្ណោះ"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"សញ្ញា​ខ្សោយ"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"គ្មានការតភ្ជាប់អ៊ីនធឺណិតទេ"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">ប៉ុស្តិ៍នេះមិនអាចចាក់បានទេរហូតដល់ម៉ោង <xliff:g id="END_TIME_1">%1$s</xliff:g> ដោយសារតែប៉ុស្តិ៍ផ្សេងទៀតកំពុងត្រូវបានថត។ \n\nចុច ស្តាំ ដើម្បីកែសម្រួលកាលវិភាគថត។</item>
- <item quantity="one">ប៉ុស្តិ៍នេះមិនអាចចាក់បានទេរហូតដល់ម៉ោង <xliff:g id="END_TIME_0">%1$s</xliff:g> ដោយសារតែប៉ុស្តិ៍ផ្សេងទៀតកំពុងត្រូវបានថត។ \n\nចុច ស្តាំ ដើម្បីកែសម្រួលកាលវិភាគថត។</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"គ្មាន​ចំណងជើង"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"បាន​ទប់​ស្កាត់​ឆានែល"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"ថ្មី"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"ប្រភព"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">ប៉ុស្តិ៍ %1$d</item>
- <item quantity="one">ប៉ុស្តិ៍ %1$d</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"មិនមានប៉ុស្តិ៍ទេ"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"ថ្មី"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"មិន​បាន​កំណត់"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"ទទួលយកប្រភពច្រើនទៀត"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"រុករកកម្មវិធីដែលមានផ្តល់ជូនប៉ុស្តិ៍ផ្សាយផ្ទាល់"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"មានផ្តល់ជូនប្រភពប៉ុស្តិ៍ថ្មី"</string>
- <string name="new_sources_description" msgid="749649005588426813">"ប្រភពប៉ុស្តិ៍ថ្មីមានប៉ុស្តិ៍ដែលត្រូវផ្តល់ជូន។\nដំឡើងប៉ុស្តិ៍ទាំងនោះឥឡូវនេះ ឬដំឡើងពេលក្រោយនៅក្នុងការកំណត់ប្រភពប៉ុស្តិ៍។"</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"ដំឡើងឥឡូវនេះ"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"យល់​ហើយ"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307"><b>"ចុច ជ្រើសរើស"</b>" ដើម្បីចូលប្រើម៉ឺនុយទូរទស្សន៍។"</string>
- <string name="msg_no_input" msgid="3897674146985427865">"រកមិនឃើញបញ្ចូលទូរទស្សន៍ទេ"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"រកមិនឃើញបញ្ចូលទូរទស្សន៍ទេ"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"មិនគាំទ្រ PIP ទេ។"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"មិនមានបញ្ចូលដែលអាចបង្ហាញជាមួយ PIP បានទេ។"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ប្រភេទឧបករណ៍ចាប់ប៉ុស្តិ៍មិនសមស្រប។ សូមចាប់ផ្តើមដំណើរការកម្មវិធី ប៉ុស្តិ៍ផ្សាយផ្ទាល់ សម្រាប់ធាតុបញ្ជូលទូរទស្សន៍ប្រភេទឧបករណ៍ចាប់ប៉ុស្តិ៍។"</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"កាកែសម្រួលប៉ុស្តិ៍បានបរាជ័យ"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"រកមិនឃើញកម្មវិធីដើម្បីគ្រប់គ្រងសកម្មភាពនេះទេ។"</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"រាល់​​ឆានែល​ប្រភព​គឺ​​លាក់​។ \n ជ្រើស​ឆា​នែ​ល​យ៉ាង​ហោច​ណាស់​មួយ​​ដើម្បី​​មើល​។"</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"មិនបានរំពឹងថាមិនមានវីដេអូនេះទេ"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"ប៊ូតុង​ថយក្រោយ​សម្រាប់​ឧបករណ៍​ដែល​បាន​ភ្ជាប់។ ចុច​ប៊ូតុង​ដើម ដើម្បី​ចាកចេញ។"</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"ប៉ុស្តិ៍ផ្សាយផ្ទាល់ត្រូវការសិទ្ធិអនុញ្ញាតដើម្បីអានបញ្ជីទូរទស្សន៍។"</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"កំណត់ប្រភពរបស់អ្នក"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"ប៉ុស្តិ៍ផ្សាយផ្ទាល់ផ្សាភ្ជាប់បទពិសោធន៍ប្រើប្រាស់ប៉ុស្តិ៍ទូរទស្សន៍លក្ខណៈបុរាណជាមួយប៉ុស្តិ៍ស្រ្ទីមដែលផ្តល់ដោយកម្មវិធី។ \n\nចាប់ផ្តើមដោយកំណត់ប្រភពប៉ុស្តិ៍ដែលបានដំឡើងរួចហើយ។ ឬរុករកក្នុងហាង Google Play ដើម្បីរកកម្មវិធីច្រើនទៀតដែលផ្តល់ជូនប៉ុស្តិ៍ផ្សាយផ្ទាល់។"</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"ការថត និងកាលវិភាក"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 នាទី"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 នាទី"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ម៉ោង"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ម៉ោង"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"ថ្មីៗ"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"បាន​កំណត់​ពេល"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"ស៊េរី"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"ផ្សេងៗ"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"មិនអាចថតប៉ុស្តិ៍នេះបានទេ"</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"មិនអាចថតកម្មវិធីនេះបានទេ"</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ត្រូវបានកំណត់ពេលដើម្បីថត"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ការថត <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ពីឥឡូវនេះដល់ <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"កាលវិភាគពេញហើយ"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">%1$d ថ្ងៃបន្ទាប់</item>
- <item quantity="one">%1$d ថ្ងៃបន្ទាប់</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d នាទី</item>
- <item quantity="one">%1$d នាទី</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">ការថតថ្មី %1$d</item>
- <item quantity="one">ការថតថ្មី %1$d</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">ការថត %1$d</item>
- <item quantity="one">ការថត %1$d</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">ការថតដែលបានកំណត់ពេល %1$d</item>
- <item quantity="one">ការថតដែលបានកំណត់ពេល %1$d</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"ទស្សនា"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"ចាក់ពីដំបូង"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"ចាក់​បន្ត"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"លុប"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"លុបការថត"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"បន្ត"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"វគ្គ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"មើលកាលវិភាគ"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"អាន​បន្ថែម"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"លុបការថត"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"ជ្រើសភាគដែលអ្នកចង់លុប។ ពួកវាមិនអាចស្តារឡើវិញបានទេបន្ទាប់ពីលុបរួចហើយ។"</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"មិនមានការថតដែលត្រូវលុបទេ"</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"ជ្រើសភាគដែលបានមើល"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"ជ្រើសភាគទាំងអស់"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"ដោះការជ្រើសភាគទាំងអស់"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"បានមើល <xliff:g id="WATCHED">%1$d</xliff:g> នៅនាទីទី <xliff:g id="DURATION">%2$d</xliff:g>"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"បានមើល <xliff:g id="WATCHED">%1$d</xliff:g> នៅវិនាទីទី <xliff:g id="DURATION">%2$d</xliff:g>"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"មិនដែលមើល"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">ភាគចំនួន %1$d ក្នុងចំណោម %2$d ត្រូវបានលុប</item>
- <item quantity="one">ភាគចំនួន %1$d ក្នុងចំណោម %2$d ត្រូវបានលុប</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"អាទិភាព"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ខ្ពស់បំផុត"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ទាបបំផុត"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"លេខ <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ប៉ុស្តិ៍"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"មួយណាក៏បាន"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"ជ្រើសអាទិភាព"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"នៅពេលដែលមានកម្មវិធីដែលត្រូវថតច្រើនពេកក្នុងពេលតែមួយ នោះមានតែកម្មវិធីដែលមានអាទិភាពខ្ពស់ជាងប៉ុណ្ណោះដែលនឹងត្រូវថត។"</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"រក្សាទុក"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ការថតមួយដងមានអាទិភាពខ្ពស់បំផុត"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"បោះបង់"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"បោះបង់"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"បំភ្លេច"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"បញ្ឈប់"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"មើលកាលវិភាគថត"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"កម្មវិធីមួយនេះ"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ឥឡូវនេះ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"វគ្គទាំងមូល…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"កាលវិភាគទោះយ៉ាងណាក៏ដោយ"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"ថតកម្មវិធីនេះជំនួសវិញ"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"បោះបង់ការថតនេះ"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"មើលឥឡូវនេះ"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"អាចថតបាន"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"បានកំណត់ពេលការថត"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ការថតជាន់ម៉ោងគ្នា"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ការថត"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"បានបរាជ័យក្នុងការថត"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"កំពុងអានកម្មវិធីដើម្បីបង្កើតកាលវិភាគថត"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"កំពុងអានកម្មវិធី"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR ត្រូវការទំហំផ្ទុកបន្ថែមទៀត"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"អ្នកនឹងអាចថតកម្មវិធីដោយប្រើ DVR។ ទោះបីជាយ៉ាងណាក៏ដោយ ឥឡូវនេះមិនមានទំហំផ្ទុកគ្រប់គ្រាន់នៅលើឧបករណ៍របស់អ្នកដើម្បីអនុញ្ញាតឲ្យ DVR ដំណើរការនោះទេ។ សូមភ្ជាប់ទៅឧបករណ៍ផ្ទុកខាងក្រៅដែលមានទំហំផ្ទុក <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB ឬធំជាងនេះ បន្ទាប់មកអនុវត្តតាមជំហានទាំងនេះដើម្បីសម្អាតវាក្នុងនាមជាឧបករណ៍ផ្ទុក។"</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"ឧបករណ៍ផ្ទុកដែលបានបាត់"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"ឧបករណ៍ផ្ទុកមួយចំនួនដែលប្រើដោយ DVR បានបាត់បង់។ សូមភ្ជាប់ថាសផ្ទុកផ្នែកខាងក្រៅដែលអ្នកបានប្រើពីមុន ដើម្បីបើកដំណើរការ DVR ឡើងវិញ ឬអ្នកអាចជ្រើសរើសធ្វើការបំភ្លេចឧបករណ៍ផ្ទុកនេះ ប្រសិនបើវាមិនអាចប្រើបានតទៅទៀត។"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"បំភ្លេចឧបករណ៍ផ្ទុកឬ?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"មាតិកា និងកាលវិភាគដែលបានថតទុករបស់អ្នកទាំងអស់នឹងបាត់បង់។"</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"បញ្ឈប់ការថតឬ?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"មាតិកាដែលបានថតនឹងត្រូវបានរក្សាទុក"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ការថតបានកំណត់ពេលហើយ ប៉ុន្តែមានម៉ោងជាន់គ្នា"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ការថតបានចាប់ផ្តើមប៉ុន្តែវាជាន់គ្នា"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> នឹងត្រូវបានថត។"</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> កំពុងត្រូវបានថត។"</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"ផ្នែកមួយចំនួននៃ <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> នឹងមិនត្រូវបានថតទេ។"</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"ផ្នែកមួយចំនួននៃ <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> និង <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> នឹងមិនត្រូវបានថតទេ។"</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"ផ្នែកមួយចំនួននៃ <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> និងកាលវិភាគមួយទៀតនឹងមិនត្រូវបានថតទេ។"</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other">ផ្នែកមួយចំនួននៃ <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> និងកាលវិភាគ %3$d ទៀតនឹងមិនត្រូវបានថតទេ។</item>
- <item quantity="one">ផ្នែកមួយចំនួននៃ <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> និងកាលវិភាគ %3$d ទៀតនឹងមិនត្រូវបានថតទេ។</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"តើអ្នកចង់ថតដែរទេ?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"តើអ្នកចង់ថតរយៈពេលប៉ុន្មានដែរ?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"បានកំណត់ពេលរួចហើយ"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"កម្មវិធីដូចគ្នានេះត្រូវបានកំណត់ពេលថតរួចហើយនៅម៉ោង <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>"</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"បានថតរួចហើយ"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"កម្មវិធីនេះត្រូវបានថតរួចហើយ។ វាអាចប្រើបាននៅក្នុងបណ្ណាល័យ DVR ។"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"រកមិនឃើញកម្មវិធីដែលបានថតទេ"</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ការថតដែលពាក់ព័ន្ធ"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(គ្មានការពិពណ៌នាអំពីកម្មវិធីទេ)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">ការថត %1$d</item>
- <item quantity="one">ការថត %1$d</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ត្រូវបានលុបចេញពីកាលវិភាគថត"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"នឹងមិនត្រូវបានថតពេញលេញនោះទេដោយសារតែអង្គរាវប៉ុស្តិ៍ជាន់គ្នា។"</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"នឹងមិនត្រូវបានថតនោះទេដោយសារតែអង្គរាវប៉ុស្តិ៍ជាន់គ្នា។"</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"មិនទាន់មានការថតនៅក្នុងកាលវិភាគនៅឡើយទេ។\nអ្នកអាចកំណត់ពេលថតចេញពីការណែនាំកម្មវិធីនេះ។"</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">ការជាន់ម៉ោងថត %1$d</item>
- <item quantity="one">ការជាន់ម៉ោងថត %1$d</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"ការកំណត់វគ្គ"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"ចាប់ផ្តើមថតវគ្គ"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"ឈប់ថតវគ្គ"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"បញ្ឈប់ការថតវគ្គឬ?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ភាគដែលបានថតនឹងនៅតែមាននៅក្នុងបណ្ណាល័យ DVR ។"</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"បញ្ឈប់"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"មិនមានផ្តល់ជូនភាគណាមួយទេ។\nពួកវានឹងត្រូវបានថតបន្ទាប់ពីមានផ្តល់ជូន។"</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d នាទី)</item>
- <item quantity="one">(%1$d នាទី) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"ថ្ងៃនេះ"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"ថ្ងៃស្អែក"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"ម្សិលមិញ"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ថ្ងៃនេះ"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ថ្ងៃស្អែក"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"ពិន្ទុ"</string>
-</resources>
diff --git a/res/values-kn-v23/strings.xml b/res/values-kn-rIN-v23/strings.xml
index 95f50839..95f50839 100644
--- a/res/values-kn-v23/strings.xml
+++ b/res/values-kn-rIN-v23/strings.xml
diff --git a/res/values-kn/arrays.xml b/res/values-kn-rIN/arrays.xml
index e6d19c9f..e6d19c9f 100644
--- a/res/values-kn/arrays.xml
+++ b/res/values-kn-rIN/arrays.xml
diff --git a/res/values-kn/rating_system_strings.xml b/res/values-kn-rIN/rating_system_strings.xml
index 4d878099..4d878099 100644
--- a/res/values-kn/rating_system_strings.xml
+++ b/res/values-kn-rIN/rating_system_strings.xml
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
new file mode 100644
index 00000000..28f3395e
--- /dev/null
+++ b/res/values-kn-rIN/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"ಮೊನೊ"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"ಸ್ಟೀರಿಯೋ"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Play ನಿಯಂತ್ರಣಗಳು"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"ಚಾನಲ್‌ಗಳು"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"ಟಿವಿ ಆಯ್ಕೆಗಳು"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"ಈ ಚಾನಲ್‌ಗೆ ಪ್ಲೇ ನಿಯಂತ್ರಣಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ಪ್ಲೇ ಮಾಡಿ ಅಥವಾ ವಿರಾಮಗೊಳಿಸಿ"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ವೇಗವಾಗಿ ಮುಂದಕ್ಕೆ"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"ರೀವೈಂಡ್"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"ಮುಂದೆ"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"ಹಿಂದೆ"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"ಕಾರ್ಯಕ್ರಮ ಮಾರ್ಗಸೂಚಿ"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"ಹೊಸ ಚಾನಲ್‌ಗಳು ಲಭ್ಯವಿವೆ"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ತೆರೆಯಿರಿ"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಗಳು"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"ಪ್ರದರ್ಶನ ಮೋಡ್"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"ಬಹು-ಆಡಿಯೊ"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"ಹೆಚ್ಚು ಚಾನಲ್‌ ಪಡೆ"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ಟಿವಿ (ಆಂಟೆನಾ/ಕೇಬಲ್)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"ಯಾವುದೇ ಕಾರ್ಯಕ್ರಮದ ಮಾಹಿತಿ ಇಲ್ಲ"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"ಯಾವುದೇ ಮಾಹಿತಿ ಇಲ್ಲ"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"ನಿರ್ಬಂಧಿಸಲಾದ ಚಾನಲ್"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"ಅಪರಿಚಿತ ಭಾಷೆ"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಗಳು %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಗಳು"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ಆಫ್"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"ಫಾರ್ಮ್ಯಾಟ್‌ ಮಾಡುವಿಕೆ ವೈಯಕ್ತೀಕರಿಸಿ"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಗಳಿಗಾಗಿ ಸಿಸ್ಟಂನಾದ್ಯಂತ ಪ್ರಾಶಸ್ತ್ಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ಪ್ರದರ್ಶನ ಮೋಡ್"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"ಬಹು-ಆಡಿಯೊ"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"ಮೊನೊ"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ಸ್ಟೀರಿಯೋ"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 ಸರೌಂಡ್"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 ಸರೌಂಡ್"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ಚಾನಲ್‌ಗಳು"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ಚಾನಲ್‌ಪಟ್ಟಿ ಕಸ್ಟಮೈಸ್‌"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ಗುಂಪು ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"ಗುಂಪು ಆಯ್ಕೆರದ್ದು"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ಈ ಪ್ರಕಾರ ಗುಂಪು ಮಾಡಿ"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ಚಾನಲ್ ಮೂಲ"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"ಈ ಪ್ರಕಾರ ಗುಂಪು ಮಾಡಿ"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ರೇಟ್ ಮಾಡಲಾಗಿಲ್ಲ"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು <xliff:g id="RATING">%1$s</xliff:g> ಎಂದು ರೇಟ್‌ ಮಾಡಲಾಗಿದೆ."</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"ಇನ್‌ಪುಟ್ ಸ್ವಯಂ-ಸ್ಕ್ಯಾನ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' ಗಾಗಿ ಸ್ವಯಂ-ಸ್ಕ್ಯಾನ್ ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಗಳಿಗೆ ಸಿಸ್ಟಂ-ವೈಡ್‌ ಪ್ರಾಶಸ್ತ್ಯಗಳನ್ನು ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d ಚಾನಲ್‌ಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ</item>
+ <item quantity="other">%1$d ಚಾನಲ್‌ಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"ಯಾವುದೇ ಚಾನಲ್‌ಗಳನ್ನು ಸೇರಿಸಲಾಗಿಲ್ಲ"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"ಪೋಷಕ ನಿಯಂತ್ರಣಗಳು"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ಆನ್"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ಆಫ್"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"ಚಾನಲ್‌ಗಳನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"ಎಲ್ಲಾ ನಿರ್ಬಂಧಿಸಿ"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"ಎಲ್ಲವನ್ನೂ ಅನಿರ್ಬಂಧಿಸಿ"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"ಮರೆಮಾಡಲಾದ ಚಾನಲ್‌ಗಳು"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"ಕಾರ್ಯಕ್ರಮ ನಿರ್ಬಂಧಗಳು"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN ಬದಲಾಯಿಸಿ"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"ಸಿಸ್ಟಂಗಳನ್ನು ರೇಟ್ ಮಾಡುವುದು"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"ರೇಟಿಂಗ್‌ಗಳು"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"ಎಲ್ಲಾ ರೇಟಿಂಗ್ ಸಿಸ್ಟಂಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
+ <string name="other_countries" msgid="8342216398676184749">"ಇತರ ದೇಶಗಳು"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"ಯಾವುದೂ ಇಲ್ಲ"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ಯಾವುದೂ ಇಲ್ಲ"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"ಅನ್‌ರೇಟೆಡ್"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"ರೇಟ್ ಮಾಡದೇ ಇರುವ ಕಾರ್ಯಕ್ರಮಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"ಯಾವುದೂ ಇಲ್ಲ"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"ಅಧಿಕ ನಿರ್ಬಂಧಗಳು"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"ಮಧ್ಯಮ ರೀತಿಯ ನಿರ್ಬಂಧ"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"ಕಡಿಮೆ ನಿರ್ಬಂಧಗಳು"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"ಕಸ್ಟಮ್"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"ಮಕ್ಕಳಿಗೆ ಸೂಕ್ತವಾದ ವಿಷಯ"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"ಹಿರಿಯ ಮಕ್ಕಳಿಗೆ ಸೂಕ್ತವಾದ ವಿಷಯ"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"ಹದಿಹರೆಯದವರಿಗೆ ಸೂಕ್ತವಾದ ವಿಷಯ"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"ಹಸ್ತಚಾಲಿತ ನಿರ್ಬಂಧಗಳು"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s ಮತ್ತು ಉಪ-ರೇಟಿಂಗ್‌ಗಳು"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"ಉಪ-ರೇಟಿಂಗ್‌ಗಳು"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ಈ ಚಾನಲ್‌ ವೀಕ್ಷಿಸಲು ನಿಮ್ಮ PIN ನಮೂದಿಸಿ"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"ಈ ಕಾರ್ಯಕ್ರಮ ವೀಕ್ಷಿಸಲು ನಿಮ್ಮ PIN ನಮೂದಿಸಿ"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು <xliff:g id="RATING">%1$s</xliff:g> ರೇಟ್ ಮಾಡಲಾಗಿದೆ. ಈ ಕಾರ್ಯಕ್ರಮ ವೀಕ್ಷಿಸಲು ನಿಮ್ಮ ಪಿನ್‌ ನಮೂದಿಸಿ"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ರೇಟ್ ಮಾಡಲಾಗಿಲ್ಲ. ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು ನಿಮ್ಮ ಪಿನ್ ನಮೂದಿಸಿ"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"ನಿಮ್ಮ PIN ಅನ್ನು ನಮೂದಿಸಿ"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"ಪೋಷಕ ನಿಯಂತ್ರಣಗಳನ್ನು ಹೊಂದಿಸಲು, PIN ರಚಿಸಿ"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"ಹೊಸ PIN ನಮೂದಿಸಿ"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"ನಿಮ್ಮ PIN ಅನ್ನು ದೃಢೀಕರಿಸಿ"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"ನಿಮ್ಮ ಪ್ರಸ್ತುತ PIN ಅನ್ನು ನಮೂದಿಸಿ"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">ನೀವು 5 ಬಾರಿ ತಪ್ಪಾದ ಪಿನ್ ನಮೂದಿಸಿದ್ದೀರಿ.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</item>
+ <item quantity="other">ನೀವು 5 ಬಾರಿ ತಪ್ಪಾದ ಪಿನ್ ನಮೂದಿಸಿದ್ದೀರಿ.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"ಆ PIN ತಪ್ಪಾಗಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ, PIN ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"ನಿಮ್ಮ ಪಿನ್ ಕೋಡ್ ನಮೂದಿಸಿ."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"ಲೈವ್ ಚಾನಲ್‌ಗಳ ಅಪ್ಲಿಕೇಶನ್ ಟಿವಿ ಚಾನಲ್‌ಗಳಿಗೆ ಸಂಪೂರ್ಣ ಕಾರ್ಯಕ್ರಮ ಮಾರ್ಗದರ್ಶನವನ್ನು ಒದಗಿಸಲು ಪಿನ್ ಕೋಡ್ ಅನ್ನು ಬಳಸುತ್ತದೆ."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"ನಿಮ್ಮ ಪಿನ್ ಕೋಡ್ ನಮೂದಿಸಿ"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"ಅಮಾನ್ಯ ಪಿನ್‌ ಕೋಡ್"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ಚಾನಲ್‌ಪಟ್ಟಿ ಕಸ್ಟಮೈಸ್‌"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ನಿಮ್ಮ ಕಾರ್ಯಕ್ರಮ ಸೂಚಿಗಾಗಿ ಚಾನಲ್‌ಗಳನ್ನು ಆರಿಸಿ"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ಚಾನಲ್ ಮೂಲಗಳು"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"ಹೊಸ ಚಾನಲ್‌ಗಳು ಲಭ್ಯವಿವೆ"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"ಪೋಷಕ ನಿಯಂತ್ರಣಗಳು"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"ಟೈಮ್‌‌ಶಿಫ್ಟ್‌"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"ಲೈವ್ ಕಾರ್ಯಕ್ರಮಗಳನ್ನು ನೋಡುವಾಗ ರೆಕಾರ್ಡ್ ಮಾಡುವುದರಿಂದ ನೀವು ವಿರಾಮ ಅಥವಾ ರಿವೈಂಡ್ ಮಾಡಬಹುದು.\nಎಚ್ಚರಿಕೆ: ಸಂಗ್ರಹಣೆಯ ತೀವ್ರ ಬಳಕೆಯ ಮೂಲಕ ಆಂತರಿಕ ಸಂಗ್ರಹಣೆಯು ಕಡಿಮೆಯಾಗಬಹುದು."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"ಮುಕ್ತ ಮೂಲ ಪರವಾನಗಿಗಳು"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"ಪ್ರತಿಕ್ರಿಯೆ ಕಳುಹಿಸಿ"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ಆವೃತ್ತಿ"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"ಈ ಚಾನಲ್ ಅನ್ನು ವೀಕ್ಷಿಸಲು, ಬಲಕ್ಕೆ ಒತ್ತಿ ಮತ್ತು ನಿಮ್ಮ PIN ಅನ್ನು ನಮೂದಿಸಿ"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು, ಬಲಕ್ಕೆ ಒತ್ತಿ ಮತ್ತು ನಿಮ್ಮ PIN ಅನ್ನು ನಮೂದಿಸಿ"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ರೇಟ್ ಮಾಡಲಾಗಿಲ್ಲ.\nಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು, ಬಲಭಾಗದಲ್ಲಿ ಒತ್ತಿರಿ ಮತ್ತು ನಿಮ್ಮ ಪಿನ್ ನಮೂದಿಸಿ"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು <xliff:g id="RATING">%1$s</xliff:g> ರೇಟ್ ಮಾಡಲಾಗಿದೆ.\nಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು, ಬಲಕ್ಕೆ ಒತ್ತಿ ಮತ್ತು ನಿಮ್ಮ ಪಿನ್ ನಮೂದಿಸಿ."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ಈ ಚಾನಲ್ ವೀಕ್ಷಿಸಲು, ಡಿಫಾಲ್ಟ್ ಲೈವ್ ಟಿವಿ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಿ."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು, ಡಿಫಾಲ್ಟ್ ಲೈವ್ ಟಿವಿ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಿ."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ರೇಟ್ ಮಾಡಲಾಗಿಲ್ಲ.\nಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು, ಡೀಫಾಲ್ಟ್ ಲೈವ್ ಟಿವಿ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಿ."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು <xliff:g id="RATING">%1$s</xliff:g> ರೇಟ್ ಮಾಡಲಾಗಿದೆ.\nಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು, ಡಿಫಾಲ್ಟ್ ಲೈವ್ ಟಿವಿ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಿ."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"ಕಾರ್ಯಕ್ರಮವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ರೇಟ್ ಮಾಡಲಾಗಿಲ್ಲ"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು <xliff:g id="RATING">%1$s</xliff:g> ಎಂದು ರೇಟ್‌ ಮಾಡಲಾಗಿದೆ."</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ಆಡಿಯೊ ಮಾತ್ರ"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"ದುರ್ಬಲ ಸಿಗ್ನಲ್"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವಿಲ್ಲ"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="one">ಇತರ ಚಾನಲ್‌ಗಳು ರೆಕಾರ್ಡ್ ಆಗುತ್ತಿರುವ ಕಾರಣ <xliff:g id="END_TIME_1">%1$s</xliff:g> ವರೆಗೂ ಈ ಚಾನಲ್‌ ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. \n\nರೆಕಾರ್ಡ್ ಮಾಡುವ ವೇಳಾಪಟ್ಟಿಯನ್ನು ಸರಿಹೊಂದಿಸಲು ಬಲಕ್ಕೆ ಒತ್ತಿರಿ.</item>
+ <item quantity="other">ಇತರ ಚಾನಲ್‌ಗಳು ರೆಕಾರ್ಡ್ ಆಗುತ್ತಿರುವ ಕಾರಣ <xliff:g id="END_TIME_1">%1$s</xliff:g> ವರೆಗೂ ಈ ಚಾನಲ್‌ ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. \n\nರೆಕಾರ್ಡ್ ಮಾಡುವ ವೇಳಾಪಟ್ಟಿಯನ್ನು ಸರಿಹೊಂದಿಸಲು ಬಲಕ್ಕೆ ಒತ್ತಿರಿ.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ಚಾನಲ್ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"ಹೊಸತು"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"ಮೂಲಗಳು"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d ಚಾನಲ್‌ಗಳು</item>
+ <item quantity="other">%1$d ಚಾನಲ್‌ಗಳು</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"ಯಾವುದೇ ಚಾನಲ್‌ಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"ಹೊಸತು"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"ಇನ್ನೂ ಹೊಂದಿಸಿಲ್ಲ"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"ಹೆಚ್ಚು ಮೂಲಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಿ"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"ಲೈವ್ ಚಾನಲ್‌ಗಳನ್ನು ಒದಗಿಸುವಂತಹ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬ್ರೌಸ್ ಮಾಡಿ"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"ಹೊಸ ಚಾನಲ್ ಮೂಲಗಳು ಲಭ್ಯವಿದೆ"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"ಹೊಸ ಚಾನಲ್ ಮೂಲಗಳು ಆಫರ್ ಮಾಡಲು ಚಾನಲ್‌ಗಳನ್ನು ಹೊಂದಿವೆ.\n ಈಗ ಅವುಗಳನ್ನು ಹೊಂದಿಸಿ, ಅಥವಾ ಇದನ್ನು ಚಾನಲ್ ಮೂಲಗಳ ಸೆಟ್ಟಿಂಗ್‌ನಲ್ಲಿ ನಂತರ ಮಾಡಿ."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"ಇದೀಗ ಹೊಂದಿಸಿ"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"ಸರಿ, ಅರ್ಥವಾಯಿತು"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"ಟಿವಿ ಮೆನುವನ್ನು ಪ್ರವೇಶಿಸಲು "<b>"ಆಯ್ಕೆ ಮಾಡು ಒತ್ತಿರಿ"</b>"."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"ಯಾವುದೇ ಟಿವಿ ಇನ್‌ಪುಟ್ ಕಂಡುಬಂದಿಲ್ಲ"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"ಟಿವಿ ಇನ್‌ಪುಟ್ ಹುಡುಕಲಾಗಲಿಲ್ಲ"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ಟ್ಯೂನರ್ ಪ್ರಕಾರವು ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ದಯವಿಟ್ಟು ಟ್ಯೂನರ್ ಪ್ರಕಾರದ ಟಿವಿ ಇನ್‌ಪುಟ್‌ಗೆ ಲೈವ್‌ ಚಾನಲ್‌ಗಳ ಅಪ್ಲಿಕೇಶನ್‌ ಪ್ರಾರಂಭಿಸಿ."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ಟ್ಯೂನ್ ವಿಫಲವಾಗಿದೆ"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"ಈ ಕ್ರಿಯೆಯನ್ನು ನಿರ್ವಹಿಸಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ ಕಂಡುಬಂದಿಲ್ಲ."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"ಎಲ್ಲ ಮೂಲ ಚಾನಲ್‌ಗಳನ್ನು ಮರೆಮಾಡಲಾಗಿದೆ.\nವೀಕ್ಷಿಸಲು ಕನಿಷ್ಠ ಒಂದು ಚಾನಲ್‌‌ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ವೀಡಿಯೊ ಅನಿರೀಕ್ಷಿತವಾಗಿ ಲಭ್ಯವಿಲ್ಲ"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"ಸಂಪರ್ಕಪಡಿಸಲಾದ ಸಾಧನಕ್ಕಾಗಿ ಹಿಂದೆ ಕೀ. ನಿರ್ಗಮಿಸಲು ಮುಖಪುಟ ಬಟನ್ ಒತ್ತಿರಿ."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"ಟಿವಿ ಪಟ್ಟಿಗಳನ್ನು ರೀಡ್ ಮಾಡಲು ಲೈವ್ ಚಾನಲ್‌ಗಳಿಗೆ ಅನುಮತಿ ಅಗತ್ಯವಿದೆ."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"ನಿಮ್ಮ ಮೂಲಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"ಲೈವ್‌ ಚಾನಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ ಮೂಲಕ ಒದಗಿಸಲಾದ ಸ್ಟ್ರೀಮಿಂಗ್ ಚಾನಲ್‌ಗಳ ಜೊತೆಗೆ ಸಾಂಪ್ರದಾಯಿಕ ಟಿವಿ ಅನುಭವವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ. \n\nಈಗಾಗಲೇ ಸ್ಥಾಪಿಸಲಾದ ಚಾನಲ್‌‌ ಮೂಲಗಳನ್ನು ಹೊಂದಿಸುವ ಮೂಲಕ ಪ್ರಾರಂಭಿಸಿ. ಅಥವಾ ಲೈವ್‌ ಚಾನಲ್‌ಗಳನ್ನು ಆಫರ್‌ ಮಾಡುವಂತಹ ಇನ್ನಷ್ಟು ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ Google Play ಸ್ಟೋರ್‌ನಲ್ಲಿ ಬ್ರೌಸ್‌ ಮಾಡಿ."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು ಮತ್ತು ವೇಳಾಪಟ್ಟಿಗಳು"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 ನಿಮಿಷಗಳು"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 ನಿಮಿಷಗಳು"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ಗಂಟೆ"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ಗಂಟೆಗಳು"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"ಇತ್ತೀಚಿನದು"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"ನಿಗದಿಪಡಿಸಲಾಗಿದ್ದು"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"ಸರಣಿ"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"ಇತರರು"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ಚಾನಲ್ ರೆಕಾರ್ಡ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"ಪ್ರೋಗ್ರಾಂ ರೆಕಾರ್ಡ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ಈಗಿನಿಂದ <xliff:g id="ENDTIME">%2$s</xliff:g> ವರೆಗೆ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತದೆ"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"ಪೂರ್ಣ ವೇಳಾಪಟ್ಟಿ"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="one">ಮುಂದಿನ %1$d ದಿನಗಳು</item>
+ <item quantity="other">ಮುಂದಿನ %1$d ದಿನಗಳು</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="one">%1$d ನಿಮಿಷಗಳು</item>
+ <item quantity="other">%1$d ನಿಮಿಷಗಳು</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="one">%1$d ಹೊಸ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
+ <item quantity="other">%1$d ಹೊಸ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="one">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
+ <item quantity="other">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="one">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳ ವೇಳಾಪಟ್ಟಿ</item>
+ <item quantity="other">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳ ವೇಳಾಪಟ್ಟಿ</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"ರೆಕಾರ್ಡಿಂಗ್ ರದ್ದುಗೊಳಿಸಿ"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸಿ"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"ವಾಚ್"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"ಪ್ರಾರಂಭದಿಂದ ಪ್ಲೇ ಮಾಡು"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"ಪ್ಲೇ ಮುಂದುವರಿಸು"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"ಅಳಿಸಿ"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ರೆಕಾರ್ಡಿಂಗ್‌‌ಗಳನ್ನು ಅಳಿಸಿ"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"ಮುಂದುವರಿಸು"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"ಸೀಸನ್ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"ವೇಳಾಪ. ವೀಕ್ಷಿಸಿ"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"ಇನ್ನಷ್ಟು ಓದಿ"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ರೆಕಾರ್ಡಿಂಗ್‌ ಅಳಿಸಿ"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"ನೀವು ಅಳಿಸಲು ಬಯಸುವಂತಹ ಸಂಚಿಕೆಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ. ಅವುಗಳನ್ನು ಒಮ್ಮೆ ಅಳಿಸಿದರೆ ಹಿಂಪಡೆಯಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"ಅಳಿಸಲು ಯಾವುದೇ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳಿಲ್ಲ."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"ವೀಕ್ಷಿಸಿದ ಸಂಚಿಕೆ ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"ಎಲ್ಲಾ ಸಂಚಿಕೆಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"ಎಲ್ಲಾ ಸಂಚಿಕೆಗಳನ್ನು ಅಳಿಸಿ"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="WATCHED">%1$d</xliff:g> ನಿಮಿಷಗಳ ಕಾಲ ವೀಕ್ಷಿಸಲಾಗಿದೆ"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="WATCHED">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳ ಕಾಲ ವೀಕ್ಷಿಸಲಾಗಿದೆ"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"ಎಂದಿಗೂ ವೀಕ್ಷಿಸಲಾಗಿಲ್ಲ"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="one">%2$d ರಲ್ಲಿ %1$d ಸಂಚಿಕೆಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ</item>
+ <item quantity="other">%2$d ರಲ್ಲಿ %1$d ಸಂಚಿಕೆಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ಆದ್ಯತೆ"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ಹೆಚ್ಚು"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ಅತಿ ಕಡಿಮೆ"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"ಸಂ. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ಚಾನಲ್‌ಗಳು"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ಯಾವುದಾದರೂ"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"ಆದ್ಯತೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"ಏಕ ಕಾಲದಲ್ಲಿ ರೆಕಾರ್ಡ್‌ ಮಾಡಲು ಸಾಕಷ್ಟು ಕಾರ್ಯಕ್ರಮಗಳು ಇದ್ದ ಸಂದರ್ಭದಲ್ಲಿ, ಹೆಚ್ಚಿನ ಆದ್ಯತೆ ಇರುವುದನ್ನು ಮಾತ್ರ ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುತ್ತದೆ."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"ಉಳಿಸು"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ಒಂದು ಬಾರಿ ಮಾಡಿದ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು ಹೆಚ್ಚಿನ ಆದ್ಯತೆ ಹೊಂದಿರುತ್ತದೆ"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"ನಿಲ್ಲಿಸಿ"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ರೆಕಾರ್ಡಿಂಗ್ ವೇಳಾಪಟ್ಟಿ ವೀಕ್ಷಿಸಿ"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"ಈ ಏಕೈಕ ಪ್ರೋಗ್ರಾಂ"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ಈಗ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"ಸಂಪೂರ್ಣ ಸರಣಿ…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"ಹೇಗಾದರೂ ನಿಗದಿಪಡಿಸಿ"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"ಬದಲಿಗೆ ಇದನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ಈ ರೆಕಾರ್ಡಿಂಗ್ ರದ್ದುಗೊಳಿಸಿ"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"ಈಗ ವೀಕ್ಷಿಸಿ"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"ರೆಕಾರ್ಡಿಂಗ್‌‌ಗಳನ್ನು ಅಳಿಸಿ..."</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"ರೆಕಾರ್ಡ್ ಮಾಡಬಹುದಾದ"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ರೆಕಾರ್ಡಿಂಗ್ ನಿಗದಿಪಡಿಸಲಾಗಿದೆ"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ರೆಕಾರ್ಡಿಂಗ್ ಸಂಘರ್ಷ"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ರೆಕಾರ್ಡ್ ಆಗುತ್ತಿದೆ"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ರೆಕಾರ್ಡಿಂಗ್ ವಿಫಲವಾಗಿದೆ"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ರೀಡ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"ಇತ್ತೀಚಿನ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ನ ರೆಕಾರ್ಡಿಂಗ್ ಅಪೂರ್ಣವಾಗಿದೆ."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ಮತ್ತು <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ನ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು ಅಪೂರ್ಣವಾಗಿವೆ."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ಮತ್ತು <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ನ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು ಅಪೂರ್ಣವಾಗಿವೆ."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"ಸಾಕಷ್ಟು ಸಂಗ್ರಹಣೆ ಇಲ್ಲದಿರುವ ಕಾರಣ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ನ ರೆಕಾರ್ಡಿಂಗ್ ಪೂರ್ಣಗೊಂಡಿಲ್ಲ."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"ಸಾಕಷ್ಟು ಸಂಗ್ರಹಣೆ ಇಲ್ಲದಿರುವ ಕಾರಣ <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ಮತ್ತು <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ನ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು ಪೂರ್ಣಗೊಂಡಿಲ್ಲ."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"ಸಾಕಷ್ಟು ಸಂಗ್ರಹಣೆ ಇಲ್ಲದಿರುವ ಕಾರಣ <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ಮತ್ತು <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ನ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು ಪೂರ್ಣಗೊಂಡಿಲ್ಲ."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR ಗೆ ಹೆಚ್ಚಿನ ಸಂಗ್ರಹಣೆಯ ಅಗತ್ಯವಿದೆ"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR ಮೂಲಕ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲು ನಿಮಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ. ಅದಾಗ್ಯೂ DVR ಗೆ ಕೆಲಸ ಮಾಡಲು ಇದೀಗ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಸಾಕಷ್ಟು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ. ದಯವಿಟ್ಟು <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB ಅಥವಾ ಅದಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಬಾಹ್ಯ ಡ್ರೈವ್‌ಗೆ ಸಂಪರ್ಕಿಸಿ ಮತ್ತು ಸಾಧನ ಸಂಗ್ರಹಣೆಯಂತೆ ಫಾರ್ಮ್ಯಾಟ್‌ ಮಾಡಲು ಹಂತಗಳನ್ನು ಅನುಸರಿಸಿ."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"ಸಾಕಷ್ಟು ಸಂಗ್ರಹಣೆಯಿಲ್ಲ"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"ಸಾಕಷ್ಟು ಸಂಗ್ರಹಣೆ ಇಲ್ಲದಿರುವ ಕಾರಣ ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ. ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಕೆಲವು ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸಲು ಪ್ರಯತ್ನಿಸಿ."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"ಸಂಗ್ರಹಣೆ ಕಾಣೆಯಾಗಿದೆ"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸುವುದೇ?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾದ ವಿಷಯವನ್ನು ಉಳಿಸಲಾಗುತ್ತದೆ."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"ಈ ಕಾರ್ಯಕ್ರಮದ ಜೊತೆಗೆ ರೆಕಾರ್ಡಿಂಗ್ ಸಂಘರ್ಷಿಸುವ ಕಾರಣದಿಂದಾಗಿ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ನಿಲ್ಲಿಸಲಾಗುವುದು. ರೆಕಾರ್ಡ್ ಮಾಡಲಾದ ವಿಷಯವನ್ನು ಉಳಿಸಲಾಗುವುದು."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ರೆಕಾರ್ಡಿಂಗ್ ನಿಗದಿಪಡಿಸಲಾಗಿದೆ ಆದರೆ ಸಂಘರ್ಷಣೆಗಳನ್ನು ಹೊಂದಿದೆ"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ ಆದರೆ ಸಂಘರ್ಷಣೆಗಳನ್ನು ಹೊಂದಿದೆ"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ಅನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುತ್ತದೆ."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ನ ಕೆಲವು ಭಾಗಗಳನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುವುದಿಲ್ಲ."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> ಮತ್ತು <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ನ ಕೆಲವು ಭಾಗಗಳನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುವುದಿಲ್ಲ."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ಮತ್ತು ಇನ್ನೊಂದು ವೇಳಾಪಟ್ಟಿಯನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುವುದಿಲ್ಲ."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="one"> <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ಮತ್ತು %3$d ಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಕೆಲವು ಭಾಗಗಳ ವೇಳಾಪಟ್ಟಿಗಳನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
+ <item quantity="other"> <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ಮತ್ತು %3$d ಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಕೆಲವು ಭಾಗಗಳ ವೇಳಾಪಟ್ಟಿಗಳನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"ನೀವು ಏನನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಿ?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"ನೀವು ಎಷ್ಟು ಸಮಯ ರೆಕಾರ್ಡ್ ಮಾಡಲು ಬಯಸುವಿರಿ?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ಈಗಾಗಲೇ ನಿಗದಿಪಡಿಸಲಾಗಿದೆ"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"ಅದೇ ಕಾರ್ಯಕ್ರಮವನ್ನು ಈಗಾಗಲೇ <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> ಸಮಯಕ್ಕೆ ರೆಕಾರ್ಡ್ ಮಾಡಲು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ಈಗಾಗಲೇ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗಿದೆ"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ಈ ಪ್ರೋಗ್ರಾಂ ಅನ್ನು ಈಗಾಗಲೇ ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗಿದೆ. ಇದು DVR ಲೈಬ್ರರಿಯಲ್ಲಿ ಲಭ್ಯವಿದೆ."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"ಸರಣಿ ರೆಕಾರ್ಡಿಂಗ್ ನಿಗದಿಪಡಿಸಲಾಗಿದೆ"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ. ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ಅವುಗಳಲ್ಲಿ <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ. ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ಅವುಗಳಲ್ಲಿ <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ. ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ಈ ಸರಣಿಯ ಮತ್ತು ಇತರ ಸರಣಿಯ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ಸಂಚಿಕೆಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ. ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ಈ ಸರಣಿಯ ಮತ್ತು ಇತರ ಸರಣಿಯ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ಸಂಚಿಕೆಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ. ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ಇತರ ಸರಣಿಯ 1 ಸಂಚಿಕೆಯನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ. ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ಇತರ ಸರಣಿಯ 1 ಸಂಚಿಕೆಯನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ. ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ಇತರ ಸರಣಿಯ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ಸಂಚಿಕೆಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ರೆಕಾರ್ಡಿಂಗ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ. ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ಇತರ ಸರಣಿಯ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ಸಂಚಿಕೆಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾದ ಕಾರ್ಯಕ್ರಮ ಕಂಡುಬಂದಿಲ್ಲ."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ಸಂಬಂಧಿಸಿದ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="one">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
+ <item quantity="other">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"ರೆಕಾರ್ಡ್‌ ಮಾಡುವಿಕೆ ವೇಳಾಪಟ್ಟಿಯಿಂದ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ಟ್ಯೂನರ್ ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ಭಾಗಶಃ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತದೆ."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ಟ್ಯೂನರ್ ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ಯಾವುದೇ ರೆಕಾರ್ಡಿಂಗ್ ಇನ್ನೂ ನಿಗದಿಪಡಿಸಿಲ್ಲ.\n ನೀವು ಪ್ರೋಗ್ರಾಂ ಮಾರ್ಗಸೂಚಿ ಮೂಲಕ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ನಿಗದಿಪಡಿಸಬಹುದು."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="one">%1$d ರೆಕಾರ್ಡಿಂಗ್ ಸಂಘರ್ಷಗಳು</item>
+ <item quantity="other">%1$d ರೆಕಾರ್ಡಿಂಗ್ ಸಂಘರ್ಷಗಳು</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"ಸರಣಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"ಸರಣಿ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭ"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"ಸರಣಿ ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸಿ"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"ಸರಣಿ ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸುವುದೇ?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾದ ಭಾಗಗಳು DVR ಲೈಬ್ರರಿಯಲ್ಲಿ ಲಭ್ಯವಿರುತ್ತವೆ."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"ನಿಲ್ಲಿಸಿ"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ಈಗ ಪ್ರಸಾರ ಮಾಡಲು ಯಾವುದೇ ಸಂಚಿಕೆಗಳಿಲ್ಲ."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ಯಾವುದೇ ಸಂಚಿಕೆಗಳು ಲಭ್ಯವಿಲ್ಲ.\nಅವುಗಳು ಒಮ್ಮೆ ಲಭ್ಯವಾದಾಗ ಅವುಗಳನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುತ್ತದೆ."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="one">(%1$d ನಿಮಿಷಗಳು)</item>
+ <item quantity="other">(%1$d ನಿಮಿಷಗಳು)</item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"ಇಂದು"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"ನಾಳೆ"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"ನಿನ್ನೆ"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ಇಂದು"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ನಾಳೆ"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"ಸ್ಕೋರ್"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"ರೆಕಾರ್ಡ್ ಮಾಡಲಾದ ಪ್ರೋಗ್ರಾಂಗಳು"</string>
+</resources>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
deleted file mode 100644
index adc99656..00000000
--- a/res/values-kn/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"ಮೊನೊ"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"ಸ್ಟೀರಿಯೋ"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Play ನಿಯಂತ್ರಣಗಳು"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"ಇತ್ತೀಚಿನ ಚಾನಲ್‌ಗಳು"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"TV ಆಯ್ಕೆಗಳು"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP ಆಯ್ಕೆಗಳು"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"ಈ ಚಾನಲ್‌ಗೆ ಪ್ಲೇ ನಿಯಂತ್ರಣಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ಪ್ಲೇ ಮಾಡಿ ಅಥವಾ ವಿರಾಮಗೊಳಿಸಿ"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ವೇಗವಾಗಿ ಮುಂದಕ್ಕೆ"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"ರೀವೈಂಡ್"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"ಮುಂದೆ"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"ಹಿಂದೆ"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"ಕಾರ್ಯಕ್ರಮ ಮಾರ್ಗಸೂಚಿ"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"ಹೊಸ ಚಾನಲ್‌ಗಳು ಲಭ್ಯವಿವೆ"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ತೆರೆಯಿರಿ"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಗಳು"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"ಪ್ರದರ್ಶನ ಮೋಡ್"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"ಆನ್"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"ಆಫ್"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"ಬಹು-ಆಡಿಯೊ"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"ಹೆಚ್ಚು ಚಾನಲ್‌ ಪಡೆ"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"ಮೂಲ"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"ಸ್ವ್ಯಾಪ್‌ ಮಾಡು"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"ಆನ್"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"ಆಫ್"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"ಶಬ್ದ"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"ಪ್ರಮುಖ"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP ವಿಂಡೋ"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"ಲೇಔಟ್"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"ಕೆಳಗಿನ ಬಲಭಾಗ"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"ಮೇಲಿನ ಬಲಭಾಗ"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"ಮೇಲಿನ ಎಡಭಾಗ"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"ಕೆಳಗಿನ ಎಡಭಾಗ"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"ಅಕ್ಕ ಪಕ್ಕ"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"ಗಾತ್ರ"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"ದೊಡ್ಡದು"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"ಸಣ್ಣ"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"ಇನ್‌ಪುಟ್ ಮೂಲ"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (ಆಂಟೆನಾ/ಕೇಬಲ್)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"ಯಾವುದೇ ಕಾರ್ಯಕ್ರಮದ ಮಾಹಿತಿ ಇಲ್ಲ"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"ಯಾವುದೇ ಮಾಹಿತಿ ಇಲ್ಲ"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"ನಿರ್ಬಂಧಿಸಲಾದ ಚಾನಲ್"</string>
- <string name="default_language" msgid="4122326459624337928">"ಅಪರಿಚಿತ ಭಾಷೆ"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಗಳು"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ಆಫ್"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"ಫಾರ್ಮ್ಯಾಟ್‌ ಮಾಡುವಿಕೆ ವೈಯಕ್ತೀಕರಿಸಿ"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಗಳಿಗಾಗಿ ಸಿಸ್ಟಂನಾದ್ಯಂತ ಪ್ರಾಶಸ್ತ್ಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ಪ್ರದರ್ಶನ ಮೋಡ್"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"ಬಹು-ಆಡಿಯೊ"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"ಮೊನೊ"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ಸ್ಟೀರಿಯೋ"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 ಸರೌಂಡ್"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 ಸರೌಂಡ್"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ಚಾನಲ್‌ಗಳು"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ಚಾನಲ್‌ಪಟ್ಟಿ ಕಸ್ಟಮೈಸ್‌"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ಗುಂಪು ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"ಗುಂಪು ಆಯ್ಕೆರದ್ದು"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ಈ ಪ್ರಕಾರ ಗುಂಪು ಮಾಡಿ"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ಚಾನಲ್ ಮೂಲ"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"ಈ ಪ್ರಕಾರ ಗುಂಪು ಮಾಡಿ"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು <xliff:g id="RATING">%1$s</xliff:g> ಎಂದು ರೇಟ್‌ ಮಾಡಲಾಗಿದೆ."</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"ಇನ್‌ಪುಟ್ ಸ್ವಯಂ-ಸ್ಕ್ಯಾನ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' ಗಾಗಿ ಸ್ವಯಂ-ಸ್ಕ್ಯಾನ್ ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಗಳಿಗೆ ಸಿಸ್ಟಂ-ವೈಡ್‌ ಪ್ರಾಶಸ್ತ್ಯಗಳನ್ನು ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="one">%1$d ಚಾನಲ್‌ಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ</item>
- <item quantity="other">%1$d ಚಾನಲ್‌ಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"ಯಾವುದೇ ಚಾನಲ್‌ಗಳನ್ನು ಸೇರಿಸಲಾಗಿಲ್ಲ"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ಟ್ಯೂನರ್"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"ಪೋಷಕ ನಿಯಂತ್ರಣಗಳು"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ಆನ್"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ಆಫ್"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"ಚಾನಲ್‌ಗಳನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"ಎಲ್ಲಾ ನಿರ್ಬಂಧಿಸಿ"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"ಎಲ್ಲವನ್ನೂ ಅನಿರ್ಬಂಧಿಸಿ"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"ಮರೆಮಾಡಲಾದ ಚಾನಲ್‌ಗಳು"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"ಕಾರ್ಯಕ್ರಮ ನಿರ್ಬಂಧಗಳು"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN ಬದಲಾಯಿಸಿ"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"ಸಿಸ್ಟಂಗಳನ್ನು ರೇಟ್ ಮಾಡುವುದು"</string>
- <string name="option_ratings" msgid="4009116954188688616">"ರೇಟಿಂಗ್‌ಗಳು"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"ಎಲ್ಲಾ ರೇಟಿಂಗ್ ಸಿಸ್ಟಂಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
- <string name="other_countries" msgid="8342216398676184749">"ಇತರ ದೇಶಗಳು"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"ಯಾವುದೂ ಇಲ್ಲ"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ಯಾವುದೂ ಇಲ್ಲ"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"ಯಾವುದೂ ಇಲ್ಲ"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"ಅಧಿಕ ನಿರ್ಬಂಧಗಳು"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"ಮಧ್ಯಮ ರೀತಿಯ ನಿರ್ಬಂಧ"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"ಕಡಿಮೆ ನಿರ್ಬಂಧಗಳು"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"ಕಸ್ಟಮ್"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"ಮಕ್ಕಳಿಗೆ ಸೂಕ್ತವಾದ ವಿಷಯ"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"ಹಿರಿಯ ಮಕ್ಕಳಿಗೆ ಸೂಕ್ತವಾದ ವಿಷಯ"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"ಹದಿಹರೆಯದವರಿಗೆ ಸೂಕ್ತವಾದ ವಿಷಯ"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"ಹಸ್ತಚಾಲಿತ ನಿರ್ಬಂಧಗಳು"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s ಮತ್ತು ಉಪ-ರೇಟಿಂಗ್‌ಗಳು"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"ಉಪ-ರೇಟಿಂಗ್‌ಗಳು"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ಈ ಚಾನಲ್‌ ವೀಕ್ಷಿಸಲು ನಿಮ್ಮ PIN ನಮೂದಿಸಿ"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"ಈ ಕಾರ್ಯಕ್ರಮ ವೀಕ್ಷಿಸಲು ನಿಮ್ಮ PIN ನಮೂದಿಸಿ"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು <xliff:g id="RATING">%1$s</xliff:g> ರೇಟ್ ಮಾಡಲಾಗಿದೆ. ಈ ಕಾರ್ಯಕ್ರಮ ವೀಕ್ಷಿಸಲು ನಿಮ್ಮ ಪಿನ್‌ ನಮೂದಿಸಿ"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"ನಿಮ್ಮ PIN ಅನ್ನು ನಮೂದಿಸಿ"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"ಪೋಷಕ ನಿಯಂತ್ರಣಗಳನ್ನು ಹೊಂದಿಸಲು, PIN ರಚಿಸಿ"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"ಹೊಸ PIN ನಮೂದಿಸಿ"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"ನಿಮ್ಮ PIN ಅನ್ನು ದೃಢೀಕರಿಸಿ"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"ನಿಮ್ಮ ಪ್ರಸ್ತುತ PIN ಅನ್ನು ನಮೂದಿಸಿ"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="one">ನೀವು 5 ಬಾರಿ ತಪ್ಪಾದ ಪಿನ್ ನಮೂದಿಸಿದ್ದೀರಿ.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</item>
- <item quantity="other">ನೀವು 5 ಬಾರಿ ತಪ್ಪಾದ ಪಿನ್ ನಮೂದಿಸಿದ್ದೀರಿ.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"ಆ PIN ತಪ್ಪಾಗಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ, PIN ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ಚಾನಲ್‌ಪಟ್ಟಿ ಕಸ್ಟಮೈಸ್‌"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ನಿಮ್ಮ ಕಾರ್ಯಕ್ರಮ ಸೂಚಿಗಾಗಿ ಚಾನಲ್‌ಗಳನ್ನು ಆರಿಸಿ"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ಚಾನಲ್ ಮೂಲಗಳು"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"ಹೊಸ ಚಾನಲ್‌ಗಳು ಲಭ್ಯವಿವೆ"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"ಪೋಷಕ ನಿಯಂತ್ರಣಗಳು"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"ಮುಕ್ತ ಮೂಲ ಪರವಾನಗಿಗಳು"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"ಮುಕ್ತ ಮೂಲ ಪರವಾನಗಿಗಳು"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"ಆವೃತ್ತಿ"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"ಈ ಚಾನಲ್ ಅನ್ನು ವೀಕ್ಷಿಸಲು, ಬಲಕ್ಕೆ ಒತ್ತಿ ಮತ್ತು ನಿಮ್ಮ PIN ಅನ್ನು ನಮೂದಿಸಿ"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು, ಬಲಕ್ಕೆ ಒತ್ತಿ ಮತ್ತು ನಿಮ್ಮ PIN ಅನ್ನು ನಮೂದಿಸಿ"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು <xliff:g id="RATING">%1$s</xliff:g> ರೇಟ್ ಮಾಡಲಾಗಿದೆ.\nಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು, ಬಲಕ್ಕೆ ಒತ್ತಿ ಮತ್ತು ನಿಮ್ಮ ಪಿನ್ ನಮೂದಿಸಿ."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ಈ ಚಾನಲ್ ವೀಕ್ಷಿಸಲು, ಡಿಫಾಲ್ಟ್ ಲೈವ್ ಟಿವಿ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಿ."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು, ಡಿಫಾಲ್ಟ್ ಲೈವ್ ಟಿವಿ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಿ."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು <xliff:g id="RATING">%1$s</xliff:g> ರೇಟ್ ಮಾಡಲಾಗಿದೆ.\nಈ ಕಾರ್ಯಕ್ರಮವನ್ನು ವೀಕ್ಷಿಸಲು, ಡಿಫಾಲ್ಟ್ ಲೈವ್ ಟಿವಿ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಿ."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"ಕಾರ್ಯಕ್ರಮವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ಈ ಕಾರ್ಯಕ್ರಮವನ್ನು <xliff:g id="RATING">%1$s</xliff:g> ಎಂದು ರೇಟ್‌ ಮಾಡಲಾಗಿದೆ."</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ಆಡಿಯೊ ಮಾತ್ರ"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"ದುರ್ಬಲ ಸಿಗ್ನಲ್"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವಿಲ್ಲ"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="one">ಇತರ ಚಾನಲ್‌ಗಳು ರೆಕಾರ್ಡ್ ಆಗುತ್ತಿರುವ ಕಾರಣ <xliff:g id="END_TIME_1">%1$s</xliff:g> ವರೆಗೂ ಈ ಚಾನಲ್‌ ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. \n\nರೆಕಾರ್ಡ್ ಮಾಡುವ ವೇಳಾಪಟ್ಟಿಯನ್ನು ಸರಿಹೊಂದಿಸಲು ಬಲಕ್ಕೆ ಒತ್ತಿರಿ.</item>
- <item quantity="other">ಇತರ ಚಾನಲ್‌ಗಳು ರೆಕಾರ್ಡ್ ಆಗುತ್ತಿರುವ ಕಾರಣ <xliff:g id="END_TIME_1">%1$s</xliff:g> ವರೆಗೂ ಈ ಚಾನಲ್‌ ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. \n\nರೆಕಾರ್ಡ್ ಮಾಡುವ ವೇಳಾಪಟ್ಟಿಯನ್ನು ಸರಿಹೊಂದಿಸಲು ಬಲಕ್ಕೆ ಒತ್ತಿರಿ.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ಚಾನಲ್ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"ಹೊಸತು"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"ಮೂಲಗಳು"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="one">%1$d ಚಾನಲ್‌ಗಳು</item>
- <item quantity="other">%1$d ಚಾನಲ್‌ಗಳು</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"ಯಾವುದೇ ಚಾನಲ್‌ಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"ಹೊಸತು"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"ಇನ್ನೂ ಹೊಂದಿಸಿಲ್ಲ"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"ಹೆಚ್ಚು ಮೂಲಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಿ"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"ಲೈವ್ ಚಾನಲ್‌ಗಳನ್ನು ಒದಗಿಸುವಂತಹ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬ್ರೌಸ್ ಮಾಡಿ"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"ಹೊಸ ಚಾನಲ್ ಮೂಲಗಳು ಲಭ್ಯವಿದೆ"</string>
- <string name="new_sources_description" msgid="749649005588426813">"ಹೊಸ ಚಾನಲ್ ಮೂಲಗಳು ಆಫರ್ ಮಾಡಲು ಚಾನಲ್‌ಗಳನ್ನು ಹೊಂದಿವೆ.\n ಈಗ ಅವುಗಳನ್ನು ಹೊಂದಿಸಿ, ಅಥವಾ ಇದನ್ನು ಚಾನಲ್ ಮೂಲಗಳ ಸೆಟ್ಟಿಂಗ್‌ನಲ್ಲಿ ನಂತರ ಮಾಡಿ."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"ಇದೀಗ ಹೊಂದಿಸಿ"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"ಸರಿ, ಅರ್ಥವಾಯಿತು"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"TV ಮೆನುವನ್ನು ಪ್ರವೇಶಿಸಲು "<b>"ಆಯ್ಕೆ ಮಾಡು ಒತ್ತಿರಿ"</b>"."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"ಯಾವುದೇ TV ಇನ್‌ಪುಟ್ ಕಂಡುಬಂದಿಲ್ಲ"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"TV ಇನ್‌ಪುಟ್ ಹುಡುಕಲಾಗಲಿಲ್ಲ"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP ಬೆಂಬಲಿತವಾಗಿಲ್ಲ"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP ನೊಂದಿಗೆ ತೋರಿಸಬಹುದಾದ ಯಾವುದೇ ಇನ್‌ಪುಟ್ ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ಟ್ಯೂನರ್ ಪ್ರಕಾರವು ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ದಯವಿಟ್ಟು ಟ್ಯೂನರ್ ಪ್ರಕಾರದ TV ಇನ್‌ಪುಟ್‌ಗೆ ಲೈವ್‌ ಚಾನಲ್‌ಗಳ ಅಪ್ಲಿಕೇಶನ್‌ ಪ್ರಾರಂಭಿಸಿ."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"ಟ್ಯೂನ್ ವಿಫಲವಾಗಿದೆ"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"ಈ ಕ್ರಿಯೆಯನ್ನು ನಿರ್ವಹಿಸಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ ಕಂಡುಬಂದಿಲ್ಲ."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"ಎಲ್ಲ ಮೂಲ ಚಾನಲ್‌ಗಳನ್ನು ಮರೆಮಾಡಲಾಗಿದೆ.\nವೀಕ್ಷಿಸಲು ಕನಿಷ್ಠ ಒಂದು ಚಾನಲ್‌‌ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ವೀಡಿಯೊ ಅನಿರೀಕ್ಷಿತವಾಗಿ ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"ಸಂಪರ್ಕಪಡಿಸಲಾದ ಸಾಧನಕ್ಕಾಗಿ ಹಿಂದೆ ಕೀ. ನಿರ್ಗಮಿಸಲು ಮುಖಪುಟ ಬಟನ್ ಒತ್ತಿರಿ."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"ಟಿವಿ ಪಟ್ಟಿಗಳನ್ನು ರೀಡ್ ಮಾಡಲು ಲೈವ್ ಚಾನಲ್‌ಗಳಿಗೆ ಅನುಮತಿ ಅಗತ್ಯವಿದೆ."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"ನಿಮ್ಮ ಮೂಲಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"ಲೈವ್‌ ಚಾನಲ್‌ಗಳು, ಅಪ್ಲಿಕೇಶನ್‌ ಮೂಲಕ ಒದಗಿಸಲಾದ ಸ್ಟ್ರೀಮಿಂಗ್ ಚಾನಲ್‌ಗಳ ಜೊತೆಗೆ ಸಾಂಪ್ರದಾಯಿಕ ಟಿವಿ ಅನುಭವವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ. \n\nಈಗಾಗಲೇ ಸ್ಥಾಪಿಸಲಾದ ಚಾನಲ್‌‌ ಮೂಲಗಳನ್ನು ಹೊಂದಿಸುವ ಮೂಲಕ ಪ್ರಾರಂಭಿಸಿ. ಅಥವಾ ಲೈವ್‌ ಚಾನಲ್‌ಗಳನ್ನು ಆಫರ್‌ ಮಾಡುವಂತಹ ಇನ್ನಷ್ಟು ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ Google Play ಸ್ಟೋರ್‌ನಲ್ಲಿ ಬ್ರೌಸ್‌ ಮಾಡಿ."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು ಮತ್ತು ವೇಳಾಪಟ್ಟಿಗಳು"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 ನಿಮಿಷಗಳು"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 ನಿಮಿಷಗಳು"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ಗಂಟೆ"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ಗಂಟೆಗಳು"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"ಇತ್ತೀಚಿನದು"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"ನಿಗದಿಪಡಿಸಲಾಗಿದ್ದು"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"ಸರಣಿ"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"ಇತರರು"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ಚಾನಲ್ ರೆಕಾರ್ಡ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"ಪ್ರೋಗ್ರಾಂ ರೆಕಾರ್ಡ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ಈಗಿನಿಂದ <xliff:g id="ENDTIME">%2$s</xliff:g> ವರೆಗೆ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತದೆ"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"ಪೂರ್ಣ ವೇಳಾಪಟ್ಟಿ"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="one">ಮುಂದಿನ %1$d ದಿನಗಳು</item>
- <item quantity="other">ಮುಂದಿನ %1$d ದಿನಗಳು</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="one">%1$d ನಿಮಿಷಗಳು</item>
- <item quantity="other">%1$d ನಿಮಿಷಗಳು</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="one">%1$d ಹೊಸ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
- <item quantity="other">%1$d ಹೊಸ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="one">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
- <item quantity="other">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="one">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳ ವೇಳಾಪಟ್ಟಿ</item>
- <item quantity="other">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳ ವೇಳಾಪಟ್ಟಿ</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"ವಾಚ್"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"ಪ್ರಾರಂಭದಿಂದ ಪ್ಲೇ ಮಾಡು"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"ಪ್ಲೇ ಮುಂದುವರಿಸು"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"ಅಳಿಸಿ"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ರೆಕಾರ್ಡಿಂಗ್‌‌ಗಳನ್ನು ಅಳಿಸು"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"ಮುಂದುವರಿಸು"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"ಸೀಸನ್ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"ವೇಳಾಪ. ವೀಕ್ಷಿಸಿ"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"ಇನ್ನಷ್ಟು ಓದಿ"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ರೆಕಾರ್ಡಿಂಗ್‌ ಅಳಿಸಿ"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"ನೀವು ಅಳಿಸಲು ಬಯಸುವಂತಹ ಸಂಚಿಕೆಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ. ಅವುಗಳನ್ನು ಒಮ್ಮೆ ಅಳಿಸಿದರೆ ಹಿಂಪಡೆಯಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"ಅಳಿಸಲು ಯಾವುದೇ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳಿಲ್ಲ."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"ವೀಕ್ಷಿಸಿದ ಸಂಚಿಕೆ ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"ಎಲ್ಲಾ ಸಂಚಿಕೆಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"ಎಲ್ಲಾ ಸಂಚಿಕೆಗಳನ್ನು ಅಳಿಸಿ"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="WATCHED">%1$d</xliff:g> ನಿಮಿಷಗಳ ಕಾಲ ವೀಕ್ಷಿಸಲಾಗಿದೆ"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="WATCHED">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳ ಕಾಲ ವೀಕ್ಷಿಸಲಾಗಿದೆ"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"ಎಂದಿಗೂ ವೀಕ್ಷಿಸಲಾಗಿಲ್ಲ"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="one">%2$d ರಲ್ಲಿ %1$d ಸಂಚಿಕೆಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ</item>
- <item quantity="other">%2$d ರಲ್ಲಿ %1$d ಸಂಚಿಕೆಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ಆದ್ಯತೆ"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ಹೆಚ್ಚು"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ಅತಿ ಕಡಿಮೆ"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"ಸಂ. <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ಚಾನಲ್‌ಗಳು"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ಯಾವುದಾದರೂ"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"ಆದ್ಯತೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"ಏಕ ಕಾಲದಲ್ಲಿ ರೆಕಾರ್ಡ್‌ ಮಾಡಲು ಸಾಕಷ್ಟು ಕಾರ್ಯಕ್ರಮಗಳು ಇದ್ದ ಸಂದರ್ಭದಲ್ಲಿ, ಹೆಚ್ಚಿನ ಆದ್ಯತೆ ಇರುವುದನ್ನು ಮಾತ್ರ ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುತ್ತದೆ."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"ಉಳಿಸು"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ಒಂದು ಬಾರಿ ಮಾಡಿದ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು ಹೆಚ್ಚಿನ ಆದ್ಯತೆ ಹೊಂದಿರುತ್ತದೆ"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"ರದ್ದುಮಾಡು"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"ರದ್ದುಮಾಡಿ"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"ಮರೆತುಬಿಡು"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"ನಿಲ್ಲಿಸು"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ರೆಕಾರ್ಡಿಂಗ್ ವೇಳಾಪಟ್ಟಿ ವೀಕ್ಷಿಸಿ"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"ಈ ಏಕೈಕ ಪ್ರೋಗ್ರಾಂ"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ಈಗ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"ಸಂಪೂರ್ಣ ಸರಣಿ…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"ಹೇಗಾದರೂ ನಿಗದಿಪಡಿಸಿ"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"ಬದಲಿಗೆ ಇದನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ಈ ರೆಕಾರ್ಡಿಂಗ್ ರದ್ದುಗೊಳಿಸಿ"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"ಈಗ ವೀಕ್ಷಿಸಿ"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"ರೆಕಾರ್ಡ್ ಮಾಡಬಹುದಾದ"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ರೆಕಾರ್ಡಿಂಗ್ ನಿಗದಿಪಡಿಸಲಾಗಿದೆ"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ರೆಕಾರ್ಡಿಂಗ್ ಸಂಘರ್ಷ"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ರೆಕಾರ್ಡ್ ಆಗುತ್ತಿದೆ"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ರೆಕಾರ್ಡಿಂಗ್ ವಿಫಲವಾಗಿದೆ"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"ರೆಕಾರ್ಡಿಂಗ್ ವೇಳಾಪಟ್ಟಿಗಳನ್ನು ರಚಿಸಲು ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ರೀಡ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ರೀಡ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR ಗೆ ಹೆಚ್ಚಿನ ಸಂಗ್ರಹಣೆಯ ಅಗತ್ಯವಿದೆ"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR ಮೂಲಕ ಪ್ರೋಗ್ರಾಂಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲು ನಿಮಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ. ಅದಾಗ್ಯೂ DVR ಗೆ ಕೆಲಸ ಮಾಡಲು ಇದೀಗ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಸಾಕಷ್ಟು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ. ದಯವಿಟ್ಟು <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB ಅಥವಾ ಅದಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಬಾಹ್ಯ ಡ್ರೈವ್‌ಗೆ ಸಂಪರ್ಕಪಡಿಸಿ ಮತ್ತು ಸಾಧನ ಸಂಗ್ರಹಣೆಯಂತೆ ಫಾರ್ಮ್ಯಾಟ್‌ ಮಾಡಲು ಹಂತಗಳನ್ನು ಅನುಸರಿಸಿ."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"ಸಂಗ್ರಹಣೆ ಕಾಣೆಯಾಗಿದೆ"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR ಮೂಲಕ ಬಳಸಲಾದ ಕೆಲವು ಸಂಗ್ರಹಣೆಯು ಕಾಣೆಯಾಗಿದೆ. ನೀವು DVR ಮರು-ಸಕ್ರಿಯಗೊಳಿಸುವ ಮೊದಲು ಬಳಸಲಾದ ಬಾಹ್ಯ ಡ್ರೈವ್ ಅನ್ನು ಸಂಪರ್ಕಪಡಿಸಿ. ಪರ್ಯಾಯವಾಗಿ, ಇನ್ನೂ ಮುಂದೆ ಲಭ್ಯವಿಲ್ಲದಿದ್ದರೆ ಸಂಗ್ರಹಣೆಯನ್ನು ಮರೆಯಲು ನೀವು ಆಯ್ಕೆಮಾಡಬಹುದು."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"ಸಂಗ್ರಹಣೆಯನ್ನು ಮರೆತಿರುವಿರಾ?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"ನಿಮ್ಮ ಎಲ್ಲಾ ರೆಕಾರ್ಡ್ ಮಾಡಲಾದ ವಿಷಯ ಮತ್ತು ವೇಳಾಪಟ್ಟಿಗಳು ಕಳೆದುಹೋಗುತ್ತವೆ."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸುವುದೇ?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾದ ವಿಷಯವನ್ನು ಉಳಿಸಲಾಗುತ್ತದೆ."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ರೆಕಾರ್ಡಿಂಗ್ ನಿಗದಿಪಡಿಸಲಾಗಿದೆ ಆದರೆ ಸಂಘರ್ಷಣೆಗಳನ್ನು ಹೊಂದಿದೆ"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ ಆದರೆ ಸಂಘರ್ಷಣೆಗಳನ್ನು ಹೊಂದಿದೆ"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ಅನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುತ್ತದೆ."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ನ ಕೆಲವು ಭಾಗಗಳನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುವುದಿಲ್ಲ."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> ಮತ್ತು <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ನ ಕೆಲವು ಭಾಗಗಳನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುವುದಿಲ್ಲ."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ಮತ್ತು ಇನ್ನೊಂದು ವೇಳಾಪಟ್ಟಿಯನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುವುದಿಲ್ಲ."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="one"> <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ಮತ್ತು %3$d ಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಕೆಲವು ಭಾಗಗಳ ವೇಳಾಪಟ್ಟಿಗಳನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
- <item quantity="other"> <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ಮತ್ತು %3$d ಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಕೆಲವು ಭಾಗಗಳ ವೇಳಾಪಟ್ಟಿಗಳನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"ನೀವು ಏನನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಿ?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"ನೀವು ಎಷ್ಟು ಸಮಯ ರೆಕಾರ್ಡ್ ಮಾಡಲು ಬಯಸುವಿರಿ?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ಈಗಾಗಲೇ ನಿಗದಿಪಡಿಸಲಾಗಿದೆ"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"ಅದೇ ಕಾರ್ಯಕ್ರಮವನ್ನು ಈಗಾಗಲೇ <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> ಸಮಯಕ್ಕೆ ರೆಕಾರ್ಡ್ ಮಾಡಲು ನಿಗದಿಪಡಿಸಲಾಗಿದೆ."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ಈಗಾಗಲೇ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗಿದೆ"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ಈ ಪ್ರೋಗ್ರಾಂ ಅನ್ನು ಈಗಾಗಲೇ ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗಿದೆ. ಇದು DVR ಲೈಬ್ರರಿಯಲ್ಲಿ ಲಭ್ಯವಿದೆ."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾದ ಕಾರ್ಯಕ್ರಮ ಕಂಡುಬಂದಿಲ್ಲ."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ಸಂಬಂಧಿಸಿದ ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(ಯಾವುದೇ ಪ್ರೋಗ್ರಾಂ ವಿವರಣೆಯಿಲ್ಲ)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="one">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
- <item quantity="other">%1$d ರೆಕಾರ್ಡಿಂಗ್‌ಗಳು</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"ರೆಕಾರ್ಡ್‌ ಮಾಡುವಿಕೆ ವೇಳಾಪಟ್ಟಿಯಿಂದ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ಟ್ಯೂನರ್ ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ಭಾಗಶಃ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತದೆ."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ಟ್ಯೂನರ್ ಸಂಘರ್ಷಗಳ ಕಾರಣದಿಂದಾಗಿ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ಯಾವುದೇ ರೆಕಾರ್ಡಿಂಗ್ ಇನ್ನೂ ನಿಗದಿಪಡಿಸಿಲ್ಲ.\n ನೀವು ಪ್ರೋಗ್ರಾಂ ಮಾರ್ಗಸೂಚಿ ಮೂಲಕ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ನಿಗದಿಪಡಿಸಬಹುದು."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="one">%1$d ರೆಕಾರ್ಡಿಂಗ್ ಸಂಘರ್ಷಗಳು</item>
- <item quantity="other">%1$d ರೆಕಾರ್ಡಿಂಗ್ ಸಂಘರ್ಷಗಳು</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"ಸರಣಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"ಸರಣಿ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭ"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"ಸರಣಿ ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸು"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"ಸರಣಿ ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸುವುದೇ?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾದ ಭಾಗಗಳು DVR ಲೈಬ್ರರಿಯಲ್ಲಿ ಲಭ್ಯವಿರುತ್ತವೆ."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"ನಿಲ್ಲಿಸಿ"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ಯಾವುದೇ ಸಂಚಿಕೆಗಳು ಲಭ್ಯವಿಲ್ಲ.\nಅವುಗಳು ಒಮ್ಮೆ ಲಭ್ಯವಾದಾಗ ಅವುಗಳನ್ನು ರೆಕಾರ್ಡ್‌ ಮಾಡಲಾಗುತ್ತದೆ."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="one">(%1$d ನಿಮಿಷಗಳು)</item>
- <item quantity="other">(%1$d ನಿಮಿಷಗಳು)</item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"ಇಂದು"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"ನಾಳೆ"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"ನಿನ್ನೆ"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ಇಂದು"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ನಾಳೆ"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"ಸ್ಕೋರ್"</string>
-</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 4e9fa6a6..de25fd97 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"모노"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"스테레오"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"재생 컨트롤"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"최근 시청한 채널"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"채널"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV 옵션"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP 옵션"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"이 채널에서 재생 컨트롤을 사용할 수 없습니다."</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"재생 또는 일시중지"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"빨리 감기"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"자막"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"표시 모드"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"사용"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"사용 안함"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"멀티 오디오"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"채널 더보기"</string>
<string name="options_item_settings" msgid="7623205838542400074">"설정"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"소스"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"전환"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"사용"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"사용 안함"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"소리"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"기본"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP 창"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"레이아웃"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"오른쪽 하단"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"오른쪽 상단"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"왼쪽 상단"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"왼쪽 하단"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"나란히"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"크기"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"크게"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"작게"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"입력 소스"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV(안테나/케이블)"</string>
<string name="no_program_information" msgid="1049844207745145132">"프로그램 정보가 없습니다."</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"정보 없음"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"차단된 채널"</string>
- <string name="default_language" msgid="4122326459624337928">"알 수 없는 언어"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"알 수 없는 언어"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"%1$d 자막"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"자막"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"사용 안함"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"포맷 맞춤설정"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"그룹 기준"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"프로그램이 차단되었습니다."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"등급이 없는 프로그램입니다."</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"이 프로그램의 시청 등급은 <xliff:g id="RATING">%1$s</xliff:g>입니다."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"입력이 자동 스캔을 지원하지 않습니다."</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\'의 자동 스캔을 시작할 수 없습니다."</string>
@@ -92,7 +74,6 @@
<item quantity="one">채널 %1$d개 추가됨</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"추가된 채널 없음"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"튜너"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"자녀 보호 기능"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"사용"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"사용 안함"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"기타 국가"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"없음"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"없음"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"등급 없음"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"등급이 없는 프로그램 차단"</string>
<string name="option_rating_none" msgid="5204552587760414879">"없음"</string>
<string name="option_rating_high" msgid="8898400296730158893">"높은 제한"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"중간 제한"</string>
@@ -126,6 +109,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"PIN을 입력하여 이 채널 시청"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"PIN을 입력하여 이 프로그램 시청"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"이 프로그램의 등급은 <xliff:g id="RATING">%1$s</xliff:g>입니다. 이 프로그램을 감상하려면 PIN을 입력하세요."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"등급이 없는 프로그램입니다. 프로그램을 시청하려면 PIN을 입력하세요."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"PIN 입력"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"PIN을 생성하여 자녀 보호 기능 설정"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"새 PIN 입력"</string>
@@ -137,22 +121,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"PIN이 잘못되었습니다. 다시 시도해 주세요."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"다시 시도해 주세요. PIN이 일치하지 않습니다."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"우편번호 입력"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"실시간 채널 앱에서 TV 채널에 관한 전체 프로그램 가이드를 제공하는 데 우편번호가 사용됩니다."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"우편번호를 입력하세요."</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"잘못된 우편번호입니다."</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"설정"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"채널 목록 맞춤설정"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"프로그램 가이드용 채널을 선택합니다."</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"채널 소스"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"새 채널 사용 가능"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"자녀 보호 기능"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"타임시프트"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"생방송 프로그램을 일시중지하거나 되감을 수 있도록 시청하면서 녹화해 보세요.\n경고: 이 기능을 사용하면 저장소가 많이 사용되므로 내부 저장소 수명이 줄어들 수도 있습니다."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"오픈소스 라이선스"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"오픈소스 라이선스"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"의견 보내기"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"버전"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"이 채널을 보려면 오른쪽을 누르고 PIN을 입력하세요."</string>
<string name="tvview_content_locked" msgid="391823084917017730">"이 프로그램을 보려면 오른쪽을 누르고 PIN을 입력하세요."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"등급이 없는 프로그램입니다.\n프로그램을 시청하려면 오른쪽을 누르고 PIN을 입력하세요."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"이 프로그램의 시청 등급은 <xliff:g id="RATING">%1$s</xliff:g>입니다.\n이 프로그램을 보려면 오른쪽을 누르고 PIN을 입력하세요."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"이 채널을 감상하려면 기본 실시간 TV 앱을 사용합니다."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"이 프로그램을 감상하려면 기본 실시간 TV 앱을 사용합니다."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"등급이 없는 프로그램입니다.\n프로그램을 시청하려면 기본 실시간 TV 앱을 사용하세요."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"이 프로그램의 등급은 <xliff:g id="RATING">%1$s</xliff:g>입니다.\n이 프로그램을 감상하려면 기본 실시간 TV 앱을 사용합니다."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"차단된 프로그램입니다."</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"등급이 없는 프로그램입니다."</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"이 프로그램의 시청 등급은 <xliff:g id="RATING">%1$s</xliff:g>입니다."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"오디오 전용"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"신호 약함"</string>
@@ -183,8 +176,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"선택을 눌러"</b>" TV 메뉴에 액세스합니다."</string>
<string name="msg_no_input" msgid="3897674146985427865">"TV 입력이 없습니다."</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"TV 입력을 찾을 수 없습니다."</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP가 지원되지 않습니다."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP로 표시할 수 있는 입력이 없습니다."</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"튜너 유형이 적합하지 않습니다. 튜너 유형 TV 입력에 실시간 채널 앱을 실행하세요."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"조정에 실패했습니다."</string>
<string name="msg_missing_app" msgid="8291542072400042076">"이 작업을 처리하는 앱을 찾을 수 없습니다."</string>
@@ -228,6 +219,8 @@
<item quantity="other">예약된 녹화 %1$d개</item>
<item quantity="one">예약된 녹화 %1$d개</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"녹화 취소"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"녹화 중지"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"시계"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"처음부터 재생"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"이어서 보기"</string>
@@ -260,9 +253,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"동시에 녹화해야 하는 프로그램이 너무 많은 경우 우선순위가 높은 프로그램만 녹화됩니다."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"저장"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"일회 녹화의 우선순위가 가장 높음"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"취소"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"취소"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"삭제"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"중지"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"녹화 일정 보기"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"이 프로그램만"</string>
@@ -272,25 +262,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"대신 이 항목을 녹화하기"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"이 녹화 취소하기"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"지금 보기"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"녹화된 프로그램 삭제 중..."</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"녹화 가능"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"녹화 예약됨"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"녹화 예약 충돌"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"녹화 중"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"녹화 실패"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"프로그램을 확인하고 녹화 일정을 만듭니다."</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"프로그램 정보 읽는 중"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"프로그램 정보 읽는 중"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"최근 녹화 보기"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> 녹화를 완료하지 못했습니다."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> 녹화를 완료하지 못했습니다."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> 녹화를 완료하지 못했습니다."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"저장용량이 부족하여 <xliff:g id="PROGRAMNAME">%1$s</xliff:g> 녹화를 완료하지 못했습니다."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"저장용량이 부족하여 <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> 녹화를 완료하지 못했습니다."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"저장용량이 부족하여 <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> 녹화를 완료하지 못했습니다."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR에 저장용량이 더 필요합니다."</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR을 사용하여 프로그램을 녹화할 수 있습니다. 그러나 DVR을 사용하기에는 기기에 남아있는 저장용량이 충분하지 않습니다. <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB 이상의 외부 드라이브를 연결하고 외부 드라이브를 기기 저장소로 포맷하기 위한 단계를 따르세요."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR을 사용하여 프로그램을 녹화할 수 있습니다. 그러나 DVR을 사용하기에는 기기에 남아있는 저장용량이 충분하지 않습니다. <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB 이상의 외부 드라이브를 연결하고 외부 드라이브를 기기 저장소로 포맷하기 위한 단계를 따르세요."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"저장공간 부족"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"저장용량이 부족하여 이 프로그램을 녹화할 수 없습니다. 기존 녹화 프로그램 일부를 삭제해 주세요."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"저장소 없음"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR에 사용되던 일부 저장소가 없습니다. 사용하던 외부 드라이브를 연결한 다음 DVR을 다시 사용 설정하시기 바랍니다. 또는 저장소를 더 이상 사용할 수 없는 경우 삭제할 수 있습니다."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"저장소를 삭제하시겠습니까?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"기록된 모든 콘텐츠 및 일정이 삭제됩니다."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"녹화를 중지하시겠습니까?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"녹화된 콘텐츠가 저장됩니다."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> 녹화가 이 프로그램과 충돌하여 중지됩니다. 녹화된 콘텐츠는 저장됩니다."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"녹화가 예약되었으나 충돌이 있음"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"녹화가 시작되었으나 충돌이 있음"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>이(가) 녹화됩니다."</string>
@@ -308,17 +301,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"동일한 프로그램이 이미 <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>에 녹화 예약되었습니다."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"이미 녹화됨"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"이 프로그램이 이미 녹화되었습니다. DVR 라이브러리에서 사용할 수 있습니다."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"시리즈 녹화 예약됨"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> 녹화 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>개가 예약되었습니다.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> 녹화 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g>개가 예약되었습니다.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> 녹화 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>개가 예약되었습니다. 충돌이 발생하여 이 중 <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>개는 녹화되지 않습니다.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> 녹화 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g>개가 예약되었습니다. 충돌이 발생하여 녹화되지 않습니다.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> 녹화 <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>개가 예약되었습니다. 충돌이 발생하여 이 시리즈 및 다른 시리즈의 에피소드 <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>개는 녹화되지 않습니다.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> 녹화 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g>개가 예약되었습니다. 충돌이 발생하여 이 시리즈 및 다른 시리즈의 에피소드 <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g>개는 녹화되지 않습니다.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> 녹화 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>개가 예약되었습니다. 충돌이 발생하여 다른 시리즈의 에피소드 1개는 녹화되지 않습니다.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> 녹화 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g>개가 예약되었습니다. 충돌이 발생하여 다른 시리즈의 에피소드 1개는 녹화되지 않습니다.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> 녹화 <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>개가 예약되었습니다. 충돌이 발생하여 다른 시리즈의 에피소드 <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>개는 녹화되지 않습니다.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> 녹화 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g>개가 예약되었습니다. 충돌이 발생하여 다른 시리즈의 에피소드 <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g>개는 녹화되지 않습니다.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"녹화된 프로그램을 찾을 수 없습니다."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"관련 녹화"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(프로그램 설명 없음)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">녹화 %1$d개</item>
<item quantity="one">녹화 %1$d개</item>
@@ -338,6 +343,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"시리즈 녹화를 중지하시겠습니까?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"녹화된 에피소드는 DVR 라이브러리에서 계속 사용할 수 있습니다."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"중지"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"현재 방송 중인 에피소드가 없습니다."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"사용할 수 있는 에피소드가 없습니다.\n사용 가능한 에피소드가 생기면 녹화됩니다."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d분)</item>
@@ -349,4 +355,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"오늘 <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"내일 <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"점수"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"녹화된 프로그램"</string>
</resources>
diff --git a/res/values-ky-v23/strings.xml b/res/values-ky-rKG-v23/strings.xml
index ae85b5f8..ae85b5f8 100644
--- a/res/values-ky-v23/strings.xml
+++ b/res/values-ky-rKG-v23/strings.xml
diff --git a/res/values-ky/arrays.xml b/res/values-ky-rKG/arrays.xml
index 835274e6..835274e6 100644
--- a/res/values-ky/arrays.xml
+++ b/res/values-ky-rKG/arrays.xml
diff --git a/res/values-ky/rating_system_strings.xml b/res/values-ky-rKG/rating_system_strings.xml
index 1d422a0c..1d422a0c 100644
--- a/res/values-ky/rating_system_strings.xml
+++ b/res/values-ky-rKG/rating_system_strings.xml
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
new file mode 100644
index 00000000..088bc631
--- /dev/null
+++ b/res/values-ky-rKG/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Ойнотууну башкаруу"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Каналдар"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"Сынлг прметрлр"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Бул канал үчүн ойнотуу көзөмөлдөрү жеткиликтүү эмес"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Ойнотуу же тындыруу"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Алдыга түрүү"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Артка түрүү"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Кийинки"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Мурунку"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Программа көрсөтмөсү"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Жаңы каналдар бар"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ачуу"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Жабык субттрлр"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Көрсөтүү режими"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Мульти-аудио"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Дагы канлдрд алуу"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Жөндөөлөр"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"Сыналгы (антенна/кабель)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Программанын маалыматы жок"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Маалымат жок"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Бөгөттөлгөн канал"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Белгисиз тил"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Коштомо жазуулар %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Коштомо жазуулар"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Өчүк"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Формттоону өзгөчөлшт"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Жабк субтрл үчн жалп верся жөндөөлр коюу"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Көрсөтүү режими"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Мульти-аудио"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"моно"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"стерео"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 айлана"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 айлана"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d канал"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Канл тизмсн өзгөчл"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Топ тандоо"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Топту тандоодн чыгр"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Топ"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Канал булагы"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Топ"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Бул программа бөгөттөлгөн."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Бул программанын рейтинги жок"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Бул программанын рейтинги <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Киргизмеде авто-скан колдоого алынбайт"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\"<xliff:g id="TV_INPUT">%s</xliff:g>\" үчүн авто издөөнү баштай албайт"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Жабык субтитрлер үчүн жалпы версия жөндөөлөрүн иштетүү мүмкүн болбой жатат."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d канал кошулду</item>
+ <item quantity="one">%1$d канал кошулду</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Каналдар кошулган жок"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Ата-энелик көзөмөл"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Күйүк"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Өчүк"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Каналдар бөгөттлдү"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Баарын бөгөттөө"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Баарн бөгөттн чыгруу"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Жашыруун каналдар"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Программа чектлрү"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN алмаштыруу"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Рейтинг тутумдары"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Баалоолор"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Бард рйтнг тутмд көр"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Башка өлкөлөр"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Эч бири"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Эч бири"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Рейтинги жок"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Рейтинги жок программалар бөгөттөлсүн"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Эч бири"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Катаал чектөөлөр"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Орточо чектөөлөр"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Жумшак чектөөлөр"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Өзгөчөлөштүрүлгөн"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Балдарга ылайыктуу мазмун"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Чоңураак балдарга ылайыктуу мазмун"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Өспүрүмдөргө ылайыктуу мазмун"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Кол менен чектөөлөр"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s жн көмкч рейтнг"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Көмөкчү рейтинг"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Бул каналды көрүү үчүн PIN\'иңизди киргизиңиз"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Бул программаны көрүү үчүн PIN\'иңизди киргизиңиз"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Бул программанын рейтинги <xliff:g id="RATING">%1$s</xliff:g>. Бул программаны көрүү үчүн PIN\'ди киргизиңиз"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Бул программанын рейтинги жок. Бул программаны көрүү үчүн PIN кодуңузду киргизиңиз"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"PIN\'иңизди киргизиңиз"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Ата-энелер көзөмөлүн коюу үчүн, PIN код түзүңүз"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Жаңы PIN киргизиңиз"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"PIN кодуңузду ырастаңыз"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Учурдагы PIN-иңизди киргизиңиз"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">PIN кодду 5 жолу туура эмес киргиздиңиз.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секунддан кийин кайталаңыз.</item>
+ <item quantity="one">PIN кодду 5 жолу туура эмес киргиздиңиз.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> секунддан кийин кайталаңыз.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"Ал PIN туура эмес. Дагы бир жолу киргизиңиз."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"PIN дал келбей жатат, дагы бир жолу аракет кылыңыз"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Почтаңыздын индексин киргизиңиз."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Түз ободогу каналдар колдонмосу сыналгы каналдары боюнча программалардын толук тизмесин түзүү үчүн почта индексин пайдаланат."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Почтаңыздын индексин киргизиңиз"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Почта индекси жараксыз"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Жөндөөлөр"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Канал тизмесин ыңгайлаштыруу"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Программа жетегиңиз үчүн каналдарды тандаңыз"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Канал булактары"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Жаңы каналдар бар"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Ата-эненин көзөмөлү"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Убакытты жылдыруу"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Түз ободогу программаларды тындыруу жана артка түрүү үчүн, аларды көрүп жатканда, жаздырып алыңыз.\nЭскертүү: Бул функция сактагычты көп пайдалангандыктан, ички сактагычтын иштөө мөөнөтүн азайтышы мүмкүн."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Ачык программа уруксаттамалары"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Пикир билдирүү"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Версиясы"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Бул каналды көрүү үчүн, Оңго басып, PIN-иңизди киргизиңиз"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Бул программаны көрүү үчүн, Оңго басып, PIN-иңизди киргизиңиз"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Бул программанын рейтинги жок.\nБул программаны көрүү үчүн баскычтоптогу Оң жебени басып туруп, PIN кодуңузду киргизиңиз"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Бул программанын рейтинги <xliff:g id="RATING">%1$s</xliff:g> \n Бул программаны көрүү үчүн, Оң баскычын басып, PIN\'иңизди киргизиңиз"</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Бул каналды көрүү үчүн демейки Түз ободогу сыналгы колдонмосун пайдаланыңыз."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Бул программаны көрүү үчүн демейки Түз ободогу сыналгы колдонмосун пайдаланыңыз."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Бул программанын рейтинги жок.\nБул программаны көрүү үчүн демейки Түз обо TV колдонмосун пайдаланыңыз."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Бул программанын рейтинги <xliff:g id="RATING">%1$s</xliff:g>.\nБул программаны көрүү үчүн демейки Түз ободогу сыналгы колдонмосун пайдаланыңыз."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Бул программа бөгөттөлгөн"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Бул программанын рейтинги жок"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Бул программанын рейтинги – <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Аудио гана"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Начар сигнал"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Интернет туташуусу жок"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">Бул каналды саат <xliff:g id="END_TIME_1">%1$s</xliff:g> чейин ойнотууга болбойт, себеби башка каналдар жаздырылууда. \n\nЖаздыруунун графигин өзгөртүү үчүн \"Оңго\" деген жебени басыңыз.</item>
+ <item quantity="one">Бул каналды саат <xliff:g id="END_TIME_0">%1$s</xliff:g> чейин ойнотууга болбойт, себеби башка канал жаздырылууда. \n\nЖаздыруунун графигин өзгөртүү үчүн \"Оңго\" деген жебени басыңыз.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Аталышы жок"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Канал бөгөттөлдү"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Жаңы"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Булактар"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d канал</item>
+ <item quantity="one">%1$d канал</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Жеткиликтүү каналдар жок"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Жаңы"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Орнотулган жок"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Дагы булактарды алуу"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Түз ободогу каналдарды сунуштаган колдонмолорду серептөө"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Жаңы канал булактары бар"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Жаңы канал булактарында сунуштай турган каналдар бар.\nАларды азыр жөндөңүз же кийинчерээк канал булактарынын жөндөөсүнөн аткарыңыз."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Азыр жөндөө"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Жарайт, түшүндүм"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"Сыналгынын менюсун ачуу үчүн "<b>"ТАНДОО"</b>" баскычын басыңыз."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"Сыналгыга киргизме табылган жок"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"Сыналгыга киргизме табылбай жатат"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Тюнердин түрү ылайыксыз. Тюнердин түрүндөгү сыналгы киргизмеси үчүн Жандуу каналдар колдонмосун ишке киргизиңиз."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Жөндөлбөй калды"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Бул ишти аткара турган бир дагы колдонмо табылган жок."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Бардык булак каналдары жашырылган.\nКөрүү үчүн кеминде бир канал тандаңыз."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Видео күтүүсүздөн жеткиликсиз болуп калды."</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"АРТКА баскычы – туташкан түзмөккө. Чыгуу үчүн БАШКЫ баскычты басыңыз."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Сыналгы тизмелерин оруу үчүн Түз ободогу каналдарга уруксат керек."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Булактарыңызды жөндөңүз"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Түз ободогу каналдарда - кадимки сыналгы каналдары менен орнотулган колдонмолор аркылуу көрсөтүлүүчү видеоканалдар камтылган. \n\nМурунтан эле орнотулган канал булактарын жөндөөдөн баштаңыз же Google Play Store\'дон башка медиа колдонмолорду карап көрүңүз."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Жаздыруулар жана графиги"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 мүнөт"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 мүнөт"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 саат"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 саат"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Акыркы"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Ыраатталды"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Топтомдор"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Башкалар"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Каналды жаздыруу мүмкүн эмес."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Программаны жаздыруу мүмкүн эмес."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> программасы жаздыруу графигине кошулду"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> программасын азыркы убактан <xliff:g id="ENDTIME">%2$s</xliff:g> чейин жаздыруу"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Толук графиги"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">Кийинки %1$d күн</item>
+ <item quantity="one">Кийинки %1$d күн</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d мүнөт</item>
+ <item quantity="one">%1$d мүнөт</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">жаңы %1$d жаздыруу</item>
+ <item quantity="one">жаңы %1$d жаздыруу</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d жаздыруу</item>
+ <item quantity="one">%1$d жаздыруу</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d жаздыруу ыраатталган</item>
+ <item quantity="one">%1$d жаздыруу ыраатталган</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Жаздырууну жокко чыгаруу"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Жаздырууну токтотуу"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Саат"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Башынан баштап ойнотуу"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Ойнотууну улантуу"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Жок кылуу"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Жаздырылган нерселерди жок кылуу"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Улантуу"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-сезон"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Графикти көрүү"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Көбүрөөк окуу"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Жаздырылган нерселерди жок кылуу"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Жок кылгыңыз келген серияларды тандаңыз. Алар жок кылынгандан кийин кайра калыбына келтирилбейт."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Жок кылына турган жаздыруулар жок."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Көргөн серияларды тандоо"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Бардык серияларды тандоо"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Бардык серияларды тандоодон чыгаруу"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> мүнөттөн <xliff:g id="WATCHED">%1$d</xliff:g> мүнөт көрүлгөн"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> секундадан <xliff:g id="WATCHED">%1$d</xliff:g> секунда көрүлгөн"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Эч качан көрүлгөн эмес"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%2$d сериядан %1$d серия жок кылынды</item>
+ <item quantity="one">%2$d сериядан %1$d серия жок кылынды</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Артыкчылыктуу"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Эң жогорку"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Эң төмөн"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Жок. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Каналдар"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Баары"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Артыкчылыкты тандоо"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Бир эле убакта жаздыра турган программалардын саны өтө көп болгон учурда, эң жогорку артыкчылыгы барлары гана жаздырылат."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Сактоо"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Бир жолку жаздыруулар жогорку артыкчылыкка ээ болот"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Токтотуу"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Жаздыруу графигин көрүү"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Жалгыз ушул программа"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"азыр - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Бардык чыгарылыштары..."</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Баары бир графикке киргизилсин"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Анын ордуна бул жаздырылсын"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Бул жаздыруу жокко чыгарылсын"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Азыр көрүңүз"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Жаздырылган көрсөтүүлөрдү өчүрүү"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Жаздырууга болот"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Пландаштырылган жаздыруу"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Жаздырууда дал келбестик бар"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Жаздырууда"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Жаздырылбай калды"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Программалар окулууда"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Акыркы жаздырууларды көрүңүз"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> жаздырылып бүтпөй калды."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> жана <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> жаздырылып бүтпөй калды."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> жана <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> жаздырылып бүтпөй калды."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Сактагычта орун жетишсиз болгондуктан <xliff:g id="PROGRAMNAME">%1$s</xliff:g> жаздырылып бүтпөй калды."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Сактагычта орун жетишсиз болгондуктан <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> жана <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> жаздырылып бүтпөй калды."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Сактагычта орун жетишсиз болгондуктан <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> жана <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> жаздырылып бүтпөй калды."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR көбүрөөк орунду талап кылат"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Сиз DVR менен программаларды жаздыра аласыз. Бирок, DVR\'ды иштетүү үчүн түзмөгүңүздө бош орун калбай калды. Көлөмү <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>Гб же андан ашык болгон тышкы драйверге туташыңыз да, аны түзмөктүн сактагычы катары жөндөп алыңыз."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Сактагычта орун жетишсиз"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Сактагычта орун жетишсиз болгондуктан, бул көрсөтүү жаздырылбайт. Мурда жаздырылган көрсөтүүлөрдү өчүрүп көрүңүз."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Сактагыч жок болуп жатат"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Жаздыруу токтотулсунбу?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Тартылган мазмун сакталып калат."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Убакыты бул программаныкына дал келип калгандыктан <xliff:g id="PROGRAMNAME">%1$s</xliff:g> жаздыруусу токтотулат. Жаздырылган мазмун сакталып калат."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Пландаштырылган жаздыруу, бирок бир убакытка коюлуп калган"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Жаздыруу башталды, бирок башка программа менен дал келип калган"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> жаздырылат."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> жаздырылууда."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> программасынын кээ бир бөлүктөрү жаздырылбайт."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> жана <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> программаларынын кээ бир бөлүктөрү жаздырылбайт."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> программаларынын кээ бир бөлүктөрү жана графиктеги дагы бирөө жаздырылбайт."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g><xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> программаларынын кээ бир бөлүктөрү жана графиктеги %3$d жаздырылбайт.</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g><xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> программаларынын кээ бир бөлүктөрү жана графиктеги %3$d жаздырылбайт.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Эмнени жаздырууну каалайсыз?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Канча убакыт жаздырууну каалайсыз?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Буга чейин графикке киргизилген"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Ушул эле программа буга чейин <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> жаздыруу графигине кошулган."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Буга чейин жаздырылган"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Бул программа буга чейин жазылган. Ал DVR китепканасында жеткиликтүү."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Сериалдын жаздыруусу пландаштырылды"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> сериалын <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> жолу жаздыруу пландаштырылган.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> сериалын <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> жолу жаздыруу пландаштырылган.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> сериалын <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> жолу жаздыруу пландаштырылган. Убакыттары дал келип калгандыктан, алардын <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> сериясы жаздырылбайт.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> сериалын <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> жолу жаздыруу пландаштырылган. Убакыты дал келип калгандыктан, ал жаздырылбайт.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> сериалын <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> жолу жаздыруу пландаштырылган. Убакыттары дал келип калгандыктан, бул сериалдын <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> сериясы жана башка сериал жаздырылбайт.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> сериалын <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> жолу жаздыруу пландаштырылган. Убакыттары дал келип калгандыктан, бул сериалдын <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> сериясы жана башка сериал жаздырылбайт.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> сериалын <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> жолу жаздыруу пландаштырылган. Убакыттары дал келип калгандыктан, башка сериалдын 1 сериясы жаздырылбайт.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> сериалын <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> жолу жаздыруу пландаштырылган. Убакыттары дал келип калгандыктан, башка сериалдын 1 сериясы жаздырылбайт.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> сериалын <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> жолу жаздыруу пландаштырылган. Убакыттары дал келип калгандыктан, башка сериалдын <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> сериясы жаздырылбайт.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> сериалын <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> жолу жаздыруу пландаштырылган. Убакыттары дал келип калгандыктан, башка сериалдын <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> сериясы жаздырылбайт.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Жаздырылган программа табылган жок."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Окшош жаздыруулар"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d жаздыруу</item>
+ <item quantity="one">%1$d жаздыруу</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> жаздыруу графигинен алынып салынган"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Күүлөгүчтөгү дал келбестиктерге байланыштуу жарым-жартылай жаздырылат."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Күүлөгүчтөгү дал келбестиктерге байланыштуу жаздырылбайт."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Графикке жаздыруу киргизиле элек.\nПрограмма жетегинен жаздыруу графигин түзсөңүз болот."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">Жаздырууда %1$d дал келбестик бар</item>
+ <item quantity="one">Жаздырууда %1$d дал келбестик бар</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Сериал жөндөөлөрү"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Сериал тартып баштоо"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Сериал тартууну токтотуу"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Сериал тартуу токтотулсунбу?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Тартылган сериялар DVR китепканасында сакталып калат."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Токтотуу"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Азыр эч кандай серия көрсөтүлбөй турат"</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Учурда бир да эпизод жок.\nАлар жеткиликтүү болоору менен жаздырылат."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d мүнөт)</item>
+ <item quantity="one">(%1$d мүнөт) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Бүгүн"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Эртең"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Кечээ"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"Бүгүн саат <xliff:g id="TIME_RANGE">%1$s</xliff:g> чейин"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Эртең саат <xliff:g id="TIME_RANGE">%1$s</xliff:g> чейин"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Упай"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Жаздырылган программалар"</string>
+</resources>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
deleted file mode 100644
index 2b9d37ab..00000000
--- a/res/values-ky/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Ойнотууну башкаруу"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Акыркы каналдар"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"Сынлг прметрлр"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP параметрлери"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Бул канал үчүн ойнотуу көзөмөлдөрү жеткиликтүү эмес"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Ойнотуу же тындыруу"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Алдыга түрүү"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Артка түрүү"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Кийинки"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Мурунку"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Программа көрсөтмөсү"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Жаңы каналдар бар"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ачуу"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Жабык субттрлр"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Көрсөтүү режими"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Күйүк"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Өчүк"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Мульти-аудио"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Дагы канлдрд алуу"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Жөндөөлөр"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Булак"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Алмаштыруу"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Күйүк"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Өчүк"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Үн"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Негизги"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP терезеси"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Үлгү"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Төмөнкү оң"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Жогорку оң"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Жогорку сол"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Төмөнкү сол"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Тушма-туш"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Өлчөмү"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Чоң"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Кичине"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Киргизүү булагы"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"Сыналгы (антенна/кабель)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Программанын маалыматы жок"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Маалымат жок"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Бөгөттөлгөн канал"</string>
- <string name="default_language" msgid="4122326459624337928">"Белгисиз тил"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Коштомо жазуулар"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Өчүк"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Формттоону өзгөчөлшт"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Жабк субтрл үчн жалп верся жөндөөлр коюу"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Көрсөтүү режими"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Мульти-аудио"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"моно"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"стерео"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 айлана"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 айлана"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d канал"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Канл тизмсн өзгөчл"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Топ тандоо"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Топту тандоодн чыгр"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Топ"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Канал булагы"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Топ"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Бул программа бөгөттөлгөн."</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Бул программанын рейтинги <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Киргизмеде авто-скан колдоого алынбайт"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\"<xliff:g id="TV_INPUT">%s</xliff:g>\" үчүн авто издөөнү баштай албайт"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Жабык субтитрлер үчүн жалпы версия жөндөөлөрүн иштетүү мүмкүн болбой жатат."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d канал кошулду</item>
- <item quantity="one">%1$d канал кошулду</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Каналдар кошулган жок"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Жөндөгүч"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Ата-энелик көзөмөл"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Күйүк"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Өчүк"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Каналдар бөгөттлдү"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Баарын бөгөттөө"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Баарн бөгөттн чыгруу"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Жашыруун каналдар"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Программа чектлрү"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN алмаштыруу"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Рейтинг тутумдары"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Баалоолор"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Бард рйтнг тутмд көр"</string>
- <string name="other_countries" msgid="8342216398676184749">"Башка өлкөлөр"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Эч бири"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Эч бири"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Эч бири"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Катаал чектөөлөр"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Орточо чектөөлөр"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Жумшак чектөөлөр"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Өзгөчөлөштүрүлгөн"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Балдарга ылайыктуу мазмун"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Чоңураак балдарга ылайыктуу мазмун"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Өспүрүмдөргө ылайыктуу мазмун"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Кол менен чектөөлөр"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s жн көмкч рейтнг"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Көмөкчү рейтинг"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Бул каналды көрүү үчүн PIN\'иңизди киргизиңиз"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Бул программаны көрүү үчүн PIN\'иңизди киргизиңиз"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Бул программанын рейтинги <xliff:g id="RATING">%1$s</xliff:g>. Бул программаны көрүү үчүн PIN\'ди киргизиңиз"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"PIN\'иңизди киргизиңиз"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Ата-энелер көзөмөлүн коюу үчүн, PIN код түзүңүз"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Жаңы PIN киргизиңиз"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"PIN кодуңузду ырастаңыз"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Учурдагы PIN-иңизди киргизиңиз"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">PIN кодду 5 жолу туура эмес киргиздиңиз.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секунддан кийин кайталаңыз.</item>
- <item quantity="one">PIN кодду 5 жолу туура эмес киргиздиңиз.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> секунддан кийин кайталаңыз.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"Ал PIN туура эмес. Дагы бир жолу киргизиңиз."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"PIN дал келбей жатат, дагы бир жолу аракет кылыңыз"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Жөндөөлөр"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Канал тизмесин ыңгайлаштыруу"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Программа жетегиңиз үчүн каналдарды тандаңыз"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Канал булактары"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Жаңы каналдар бар"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Ата-эненин көзөмөлү"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Ачык программа уруксаттамалары"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Ачык программа уруксаттамалары"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Версиясы"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Бул каналды көрүү үчүн, Оңго басып, PIN-иңизди киргизиңиз"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Бул программаны көрүү үчүн, Оңго басып, PIN-иңизди киргизиңиз"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Бул программанын рейтинги <xliff:g id="RATING">%1$s</xliff:g> \n Бул программаны көрүү үчүн, Оң баскычын басып, PIN\'иңизди киргизиңиз"</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Бул каналды көрүү үчүн демейки Түз ободогу сыналгы колдонмосун пайдаланыңыз."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Бул программаны көрүү үчүн демейки Түз ободогу сыналгы колдонмосун пайдаланыңыз."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Бул программанын рейтинги <xliff:g id="RATING">%1$s</xliff:g>.\nБул программаны көрүү үчүн демейки Түз ободогу сыналгы колдонмосун пайдаланыңыз."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Бул программа бөгөттөлгөн"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Бул программанын рейтинги – <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Аудио гана"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Начар сигнал"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Интернет туташуусу жок"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Бул каналды саат <xliff:g id="END_TIME_1">%1$s</xliff:g> чейин ойнотууга болбойт, себеби башка каналдар жаздырылууда. \n\nЖаздыруунун графигин өзгөртүү үчүн \"Оңго\" деген жебени басыңыз.</item>
- <item quantity="one">Бул каналды саат <xliff:g id="END_TIME_0">%1$s</xliff:g> чейин ойнотууга болбойт, себеби башка канал жаздырылууда. \n\nЖаздыруунун графигин өзгөртүү үчүн \"Оңго\" деген жебени басыңыз.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Аталышы жок"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Канал бөгөттөлдү"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Жаңы"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Булактар"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d канал</item>
- <item quantity="one">%1$d канал</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Жеткиликтүү каналдар жок"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Жаңы"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Орнотулган жок"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Дагы булактарды алуу"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Түз ободогу каналдарды сунуштаган колдонмолорду серептөө"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Жаңы канал булактары бар"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Жаңы канал булактарында сунуштай турган каналдар бар.\nАларды азыр жөндөңүз же кийинчерээк канал булактарынын жөндөөсүнөн аткарыңыз."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Азыр жөндөө"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"Жарайт, түшүндүм"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"Сыналгынын менюсун ачуу үчүн "<b>"ТАНДОО"</b>" баскычын басыңыз."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"Сыналгыга киргизме табылган жок"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"Сыналгыга киргизме табылбай жатат"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP колдоого алынбайт"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP аркылуу көрсөтүлө турган эч нерсе киргизилген жок."</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Тюнердин түрү ылайыксыз. Тюнердин түрүндөгү сыналгы киргизмеси үчүн Жандуу каналдар колдонмосун ишке киргизиңиз."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Жөндөлбөй калды"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Бул ишти аткара турган бир дагы колдонмо табылган жок."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Бардык булак каналдары жашырылган.\nКөрүү үчүн кеминде бир канал тандаңыз."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Видео күтүүсүздөн жеткиликсиз болуп калды."</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"АРТКА баскычы – туташкан түзмөккө. Чыгуу үчүн БАШКЫ баскычты басыңыз."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Сыналгы тизмелерин оруу үчүн Түз ободогу каналдарга уруксат керек."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Булактарыңызды жөндөңүз"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Түз ободогу каналдарда - кадимки сыналгы каналдары менен орнотулган колдонмолор аркылуу көрсөтүлүүчү видеоканалдар камтылган. \n\nМурунтан эле орнотулган канал булактарын жөндөөдөн баштаңыз же Google Play Store\'дон башка медиа колдонмолорду карап көрүңүз."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Жаздыруулар жана графиги"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 мүнөт"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 мүнөт"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 саат"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 саат"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Акыркы"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Ыраатталды"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Топтомдор"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Башкалар"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Каналды жаздыруу мүмкүн эмес."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Программаны жаздыруу мүмкүн эмес."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> программасы жаздыруу графигине кошулду"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> программасын азыркы убактан <xliff:g id="ENDTIME">%2$s</xliff:g> чейин жаздыруу"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Толук графиги"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">Кийинки %1$d күн</item>
- <item quantity="one">Кийинки %1$d күн</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d мүнөт</item>
- <item quantity="one">%1$d мүнөт</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">жаңы %1$d жаздыруу</item>
- <item quantity="one">жаңы %1$d жаздыруу</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d жаздыруу</item>
- <item quantity="one">%1$d жаздыруу</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d жаздыруу ыраатталган</item>
- <item quantity="one">%1$d жаздыруу ыраатталган</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Саат"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Башынан баштап ойнотуу"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Ойнотууну улантуу"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Жок кылуу"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Жаздырылган нерселерди жок кылуу"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Улантуу"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-сезон"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Графикти көрүү"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Көбүрөөк окуу"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Жаздырылган нерселерди жок кылуу"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Жок кылгыңыз келген серияларды тандаңыз. Алар жок кылынгандан кийин кайра калыбына келтирилбейт."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Жок кылына турган жаздыруулар жок."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Көргөн серияларды тандоо"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Бардык серияларды тандоо"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Бардык серияларды тандоодон чыгаруу"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> мүнөттөн <xliff:g id="WATCHED">%1$d</xliff:g> мүнөт көрүлгөн"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> секундадан <xliff:g id="WATCHED">%1$d</xliff:g> секунда көрүлгөн"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Эч качан көрүлгөн эмес"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%2$d сериядан %1$d серия жок кылынды</item>
- <item quantity="one">%2$d сериядан %1$d серия жок кылынды</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Артыкчылыктуу"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Эң жогорку"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Эң төмөн"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Жок. <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Каналдар"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Баары"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Артыкчылыкты тандоо"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Бир эле убакта жаздыра турган программалардын саны өтө көп болгон учурда, эң жогорку артыкчылыгы барлары гана жаздырылат."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Сактоо"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Бир жолку жаздыруулар жогорку артыкчылыкка ээ болот"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Баш тартуу"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Жокко чыгаруу"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Унутуу"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Токтотуу"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Жаздыруу графигин көрүү"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Жалгыз ушул программа"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"азыр - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Бардык чыгарылыштары..."</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Баары бир графикке киргизилсин"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Анын ордуна бул жаздырылсын"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Бул жаздыруу жокко чыгарылсын"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Азыр көрүңүз"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Жаздырууга болот"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Пландаштырылган жаздыруу"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Жаздырууда дал келбестик бар"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Жаздырууда"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Жаздырылбай калды"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Ырааттамаларды жаздырууну түзүү үчүн программаларды окуу"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Программалар окулууда"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR көбүрөөк орунду талап кылат"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Сиз DVR менен программаларды жаздыра аласыз. Бирок, DVR\'ды иштетүү үчүн түзмөгүңүздө бош орун калбай калды. Көлөмү <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>Гб же андан ашык болгон тышкы драйверге туташыңыз да, аны түзмөктүн сактагычы катары жөндөп алыңыз."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Сактагыч жок болуп жатат"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR колдонгон сактагычтын айрым бөлүмдөрү жок болуп жатат. DVR\'ды кайра иштетүү үчүн колдонулган тышкы драйверди туташтырыңыз. Же болбосо, жеткиликсиз сактагыч унутулсун дегенди тандасаңыз болот."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Сактагыч унутулсунбу?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Бардык жаздырылган мазмун жана графиктериңиз жоголот."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Жаздыруу токтотулсунбу?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Тартылган мазмун сакталып калат."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Пландаштырылган жаздыруу, бирок бир убакытка коюлуп калган"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Жаздыруу башталды, бирок башка программа менен дал келип калган"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> жаздырылат."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> жаздырылууда."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> программасынын кээ бир бөлүктөрү жаздырылбайт."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> жана <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> программаларынын кээ бир бөлүктөрү жаздырылбайт."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> программаларынын кээ бир бөлүктөрү жана графиктеги дагы бирөө жаздырылбайт."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g><xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> программаларынын кээ бир бөлүктөрү жана графиктеги %3$d жаздырылбайт.</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g><xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> программаларынын кээ бир бөлүктөрү жана графиктеги %3$d жаздырылбайт.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Эмнени жаздырууну каалайсыз?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Канча убакыт жаздырууну каалайсыз?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Буга чейин графикке киргизилген"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Ушул эле программа буга чейин <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> жаздыруу графигине кошулган."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Буга чейин жаздырылган"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Бул программа буга чейин жазылган. Ал DVR китепканасында жеткиликтүү."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Жаздырылган программа табылган жок."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Окшош жаздыруулар"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Программанын сүрөттөлүшү жок)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d жаздыруу</item>
- <item quantity="one">%1$d жаздыруу</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> жаздыруу графигинен алынып салынган"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Күүлөгүчтөгү дал келбестиктерге байланыштуу жарым-жартылай жаздырылат."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Күүлөгүчтөгү дал келбестиктерге байланыштуу жаздырылбайт."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Графикке жаздыруу киргизиле элек.\nПрограмма жетегинен жаздыруу графигин түзсөңүз болот."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">Жаздырууда %1$d дал келбестик бар</item>
- <item quantity="one">Жаздырууда %1$d дал келбестик бар</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Сериал жөндөөлөрү"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Сериал тартып баштоо"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Сериал тартууну токтотуу"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Сериал тартуу токтотулсунбу?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Тартылган сериялар DVR китепканасында сакталып калат."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Токтотуу"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Учурда бир да эпизод жок.\nАлар жеткиликтүү болоору менен жаздырылат."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d мүнөт)</item>
- <item quantity="one">(%1$d мүнөт) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Бүгүн"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Эртең"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Кечээ"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"Бүгүн саат <xliff:g id="TIME_RANGE">%1$s</xliff:g> чейин"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Эртең саат <xliff:g id="TIME_RANGE">%1$s</xliff:g> чейин"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Упай"</string>
-</resources>
diff --git a/res/values-ldrtl/dimens.xml b/res/values-ldrtl/dimens.xml
index 0b79b144..4b030d4e 100644
--- a/res/values-ldrtl/dimens.xml
+++ b/res/values-ldrtl/dimens.xml
@@ -28,7 +28,6 @@
<dimen name="program_guide_table_background_round_radius_right">2dp</dimen>
<dimen name="program_guide_shift_start_to_end_x">-238dp</dimen>
- <dimen name="program_guide_shift_end_to_start_x">238dp</dimen>
<dimen name="program_guide_side_panel_row_pivot_x">
@dimen/program_guide_side_panel_item_width</dimen>
<dimen name="program_guide_side_panel_exit_x">32dp</dimen>
diff --git a/res/values-lo-v23/strings.xml b/res/values-lo-rLA-v23/strings.xml
index 53804594..53804594 100644
--- a/res/values-lo-v23/strings.xml
+++ b/res/values-lo-rLA-v23/strings.xml
diff --git a/res/values-lo/arrays.xml b/res/values-lo-rLA/arrays.xml
index 5e1c1e0c..5e1c1e0c 100644
--- a/res/values-lo/arrays.xml
+++ b/res/values-lo-rLA/arrays.xml
diff --git a/res/values-lo/rating_system_strings.xml b/res/values-lo-rLA/rating_system_strings.xml
index 534b6a89..534b6a89 100644
--- a/res/values-lo/rating_system_strings.xml
+++ b/res/values-lo-rLA/rating_system_strings.xml
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
new file mode 100644
index 00000000..06bb63a3
--- /dev/null
+++ b/res/values-lo-rLA/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"​ໂມ​ໂນ"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"ສະ​ເຕ​ຣິ​ໂອ"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"ຄວບ​ຄຸມ​ການ​ຫຼິ້ນ"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"​ຊ່ອງ"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"ໂຕເລືອກ​ໂທລະພາບ"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"ຫຼິ້ນ​ການ​ຄວບ​ຄຸມ​ບໍ່​ມີ​ໃຫ້​ສຳ​ລັບ​ຊ່ອງ​ນີ້"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ຫຼິ້ນ​ ຫລື​ຢຸດ​ຊົ່ວ​ຄາວ"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ເລື່ອນ​ໄປ​ໜ້າ"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"​ຣີ​ວາຍກັບ"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"ຕໍ່​ໄປ"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"ກ່ອນໜ້າ"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"ຄຳ​ແນະນຳ​ລາຍການ"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"ມີ​ຊ່ອງ​ໃໝ່​ໃຫ້​ຢູ່"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"ເປີດ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"ຄຳ​ບັນຍາຍ​ແບບ​ປິດ"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"ໂໝດ​ການ​ສະແດງຜົນ"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"ຫຼາຍສຽງ"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"ເອົາຊ່ອງເພີ່ມເຕີມ"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"ການ​ຕັ້ງ​ຄ່າ"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (ເສົາ​ສັນ​ຍານ/ສາຍ​ເຄ​ເບິນ)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"ບໍ່​ມີ​ຂໍ້​ມູນ​ລາຍ​ການ"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"ບໍ່ມີຂໍ້ມູນ"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"ຊ່ອງ​ທີ່​ຖືກບ​ລັອກ"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"ພາ​ສາ​ບໍ່​ຮູ້​ຈັກ"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"ຄຳບັນຍາຍ %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"ຄຳ​ບັນຍາຍ​ແບບ​ປິດ"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ປິດ"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"ປັບແຕ່ງການຈັດຮູບແບບ"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"ກຳນົດ​ການຕັ້ງຄ່າ​ລະບົບ​ສຳລັບ​ຄຳ​ບັນຍາຍ​ແບບ​ປິດ"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ໂໝດ​ສະແດງ​ຜົນ"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"ຫຼາຍ​ສຽງ"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"​ໂມ​ໂນ"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ສະເຕຣິໂອ"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"ສຽງ​ຮອບ​ທິດ​ທາງ 5.1"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"ສຽງ​ຮອບ​ທິດ​ທາງ 7.1"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ​ຊ່ອງ"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ປັບແຕ່ງ​ລາຍ​ຊື່​ຊ່ອງ"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ເລືອກກຸ່ມ"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"ບໍ່​ເລືອກ​ກຸ່ມ"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ຈັດກຸ່ມຕາມ"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ທີ່​ມາ​ຂອງ​ຊ່ອງ"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"ຈັດກຸ່ມຕາມ"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"ໂປ​ຣ​ແກ​ຣມ​ນີ້​ຖືກບ​ລັອກ​ແລ້ວ"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"ລາຍການນີ້ບໍ່ໄດ້ຈັດປະເພດເທື່ອ"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"​ລາຍ​ການ​ນີ້​ຖືກ​ຈັດ​ປະ​ເພດ <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"ອິນ​ພຸດ​ນີ້ບໍ່​ຮອງ​ຮັບ​ການ​ສະ​ແກນ​ອັດ​ຕະ​ໂນ​ມັດ"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"ບໍ່​ສາ​ມາດ​ເລີ່ມ​ການ​ສະ​ແກນ​ອັດ​ຕະ​ໂນ​ມັດ​ສຳ​ລັບ \'<xliff:g id="TV_INPUT">%s</xliff:g>\' ໄດ້"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"ບໍ່​ສາ​ມາດ​ເລີ່ມ​ການ​ຕັ້ງ​ຄ່າ​ທົ່ວ​ລະ​ບົບ​ສຳ​ລັບ​ຄຳ​ບັນ​ຍາຍ​ແບບ​ປິດ​ໄດ້."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">ເພີ່ມ %1$d ຊ່ອງແລ້ວ</item>
+ <item quantity="one">ເພີ່ມ %1$d ຊ່ອງແລ້ວ</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"ບໍ່​ໄດ້​ເພີ່ມ​ຊ່ອງ"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"ການ​ຄວບຄຸມ​ຂອງ​ຜູ່​ປົກ​ຄອງ"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ເປີດ"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ປິດ"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"ຊ່ອງ​ຖືກ​ບລັອກ​ແລ້ວ"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"​ບລັອກ​​ທັງ​​ໝົດ"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"ປົດ​ບລັອກ​ທັງ​ໝົດ"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"​ຊ່ອງ​ທີ່​ຖືກ​ເຊື່ອງ"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"ການ​ຈຳກັດ​ລາຍການ"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"​ປ່ຽນ​ PIN"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"​ລະ​ບົບ​ການ​ຈັດ​ປະ​ເພດ"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"​​​ການ​ຈັດ​ປະ​ເພດ"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"ເບິ່ງ​ລະບົບ​ການ​ຈັດ​ປະເພດ​ທັງ​ໝົດ"</string>
+ <string name="other_countries" msgid="8342216398676184749">"ປະ​ເທດ​ອື່ນໆ"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"ບໍ່ມີ"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ບໍ່ມີ"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"ບໍໄດ້ຈັດປະເພດເທື່ອ"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"ບລັອກລາຍການທີ່ຍັງບໍ່ໄດ້ຈັດປະເພດເທື່ອ"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"ບໍ່ມີ"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"ຈຳກັດສູງ"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"ຈຳກັດປານກາງ"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"ຈຳກັດຕ່ຳ"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"ກຳນົດເອງ"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"ເນື້ອຫາ​ເໝາະສົມ​ສຳລັບ​ເດັກນ້ອຍ"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"ເນື້ອຫາ​ເໝາະ​ສຳລັບ​ເດັກ​ທີ່​ບໍ່​ນ້ອຍ​ຫຼາຍ"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"​ເນື້ອ​ຫາ​ເໝາະ​ສົມ​ສຳ​ລັບ​ໄວ​ຮຸ່ນ"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"ຈຳ​ກັດແບບ​​ລະ​ບຸ​ເອງ"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s ແລະປະເພດຍ່ອຍ"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"ປະເພດຍ່ອຍ"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ປ້ອນ​ລະ​ຫັດ​ PIN ຂອງ​ທ່ານ​ເພື່ອ​ເບິ່ງ​ຊ່ອງ​ນີ້"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"​ປ້ອນ​ລະ​ຫັດ PIN ຂອງ​ທ່ານ​ເພື່ອ​ເບິ່ງ​ລາຍ​ການ​ນີ້"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ລາຍການນີ້ຖືກຈັດປະເພດເປັນ <xliff:g id="RATING">%1$s</xliff:g>. ກະລຸນາໃສ່ລະຫັດ PIN ຂອງທ່ານເພື່ອເບິ່ງລາຍການນີ້"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"ລາຍການນີ້ຍັງບໍ່ໄດ້ຈັດປະເພດເທື່ອ. ກະລຸນາລະບຸລະຫັດ PIN ຂອງທ່ານເພື່ອເບິ່ງລາຍການນີ້"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"​ປ້ອນ​ລະ​ຫັດ PIN ຂອງ​ທ່ານ"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"ເພື່ອ​ຕັ້ງ​ຄ່າ​ຄວບ​ຄຸມ​ຂອງ​ຜູ່​ປົກ​ຄອງ, ກະລຸ​ນາຕັ້ງ​ລະ​ຫັດ PIN"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"ໃສ່ລະຫັດ PIN ໂຕໃຫມ່"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"ຢືນຢັນ​ລະຫັດ PIN ຂອງທ່ານ"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"ປ້ອນ​ລະ​ຫັດ PIN ປັດ​ຈຸ​ບັນ​ຂອງ​ທ່ານ"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">ທ່ານປ້ອນ PIN ບໍ່ຖືກຕ້ອງ 5 ເທື່ອແລ້ວ.\nລອງອີກເທື່ອໃນ <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> ວິນາທີ.</item>
+ <item quantity="one">ທ່ານປ້ອນ PIN ບໍ່ຖືກຕ້ອງ 5 ເທື່ອແລ້ວ.\nລອງອີກເທື່ອໃນ <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> ວິນາທີ.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"ລະຫັດ PIN ນັ້ນບໍ່​ຖືກ​ຕ້ອງ, ກະ​ລຸ​ນາລອງ​ໃຫມ່​ອີກ​ຄັ້ງ."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"ລະ​ຫັດ PIN ບໍ່​ກົງ​ກັນ, ກະ​ລຸ​ນາ​ລອງ​ໃໝ່."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"ລະບຸລະຫັດ ZIP ຂອງທ່ານ."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"ແອັບ Live TV ຈະໃຊ້ລະຫັດ ZIP ເພື່ອສະໜອງຄຳແນະນຳລາຍການທີ່ສົມບູນໃຫ້ກັບຊ່ອງໂທລະທັດຕ່າງໆ."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"ໃສ່ລະຫັດ ZIP ຂອງທ່ານ"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"ລະຫັດ ZIP ບໍ່ຖືກຕ້ອງ"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"ການ​ຕັ້ງ​ຄ່າ"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ປັບແຕ່ງ​ລາຍ​ຊື່​ຊ່ອງ"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ເລືອກ​ຊ່ອງ​ສຳລັບການ​ແນະນຳລາຍການ​ຂອງ​ທ່ານ"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ແຫຼ່ງທີ່ມາ​ຂອງ​ຊ່ອງ"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"ມີ​ຊ່ອງ​ໃໝ່​"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"ການ​ຄວບຄຸມ​ຂອງພໍ່ແມ່"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"ບັນທຶກໃນລະຫວ່າງເບິ່ງເພື່ອໃຫ້ທ່ານສາມາດຢຸດ ຫຼື ເບິ່ງລາຍການສົດຄືນຫຼັງໄດ້.\nຄຳເຕືອນ: ນີ້ອາດຫຼຸດອາຍຸຂອງບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນເນື່ອງຈາກມີການໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນຢ່າງຕໍ່ເນື່ອງ."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"​ໃບ​ອະ​ນຸ​ຍາດ​ Open source"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"ສົ່ງຄຳຕິຊົມ"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ເວີຊັນ"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"​ເພື່ອ​ເບິ່ງ​ຊ່ອງ​ນີ້, ກົດ​ປຸ່ມ ຂວາ ແລະ ປ້ອນ​ລະ​ຫັດ PIN ຂອງ​ທ່ານ"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"​ເພື່ອ​ເບິ່ງ​ລາຍ​ການ​ນີ້, ໃຫ້ກົດ​ປຸ່ມ ຂວາ ແລະ ປ້ອນ​ລະ​ຫັດ PIN ຂອງ​ທ່ານ"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"ລາຍການນີ້ບໍ່ໄດ້ຈັດປະເພດເທື່ອ.\nເພື່ອເບິ່ງລາຍການນີ້, ໃຫ້ກົດປຸ່ມຂວາແລ້ວໃສ່ລະຫັດ PIN ຂອງທ່ານ"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"​ລາຍ​ການ​ນີ້​ຖືກ​ຈັດ​ປະ​ເພດ​ <xliff:g id="RATING">%1$s</xliff:g>.\n​ເພື່ອ​ເບິ່ງ​ລາຍ​ການ​ນີ້, ໃຫ້ກົດ​ປຸ່ມ ຂວາ ແລະ ປ້ອນ​ລະ​ຫັດ PIN ຂອງ​ທ່ານ"</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ເພື່ອເບິ່ງຊ່ອງນີ້, ໃຊ້ແອັບ Live TV ມາດຕະຖານ."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ເພື່ອເບິ່ງໂປຣແກຣມນີ້, ໃຊ້ແອັບ Live TV ມາດຕະຖານ."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"ລາຍການນີ້ບໍ່ໄດ້ຈັດປະເພດເທື່ອ.\nເພື່ອເບິ່ງລາຍການນີ້, ໃຫ້ໃຊ້ແອັບ Live TV ເລີ່ມຕົ້ນ."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ໂປຣແກຣມນີ້ຖືກຈັດປະເພດ <xliff:g id="RATING">%1$s</xliff:g>.\nເພື່ອເບິ່ງໂປຣແກຣມນີ້, ໃຊ້ແອັບ Live TV ມາດຕະຖານ."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"​ລາຍ​ການ​ຖືກບລັອກ"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"ລາຍການນີ້ບໍ່ໄດ້ຈັດປະເພດເທື່ອ"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"​ລາຍ​ການ​ນີ້​ຖືກ​ຈັດ​ປະ​ເພດ <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ສຽງເທົ່ານັ້ນ"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"ສັນຍານອ່ອນ"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">ບໍ່ສາມາດຫຼິ້ນຊ່ອງນີ້ໄດ້ຈົນກວ່າຈະຮອດ <xliff:g id="END_TIME_1">%1$s</xliff:g> ເນື່ອງຈາກກຳລັງບັນທຶກຊ່ອງອື່ນຢູ່. \n\nກົດຂວາເພື່ອປັບແຕ່ງເວລາການບັນທຶກ.</item>
+ <item quantity="one">ບໍ່ສາມາດຫຼິ້ນຊ່ອງນີ້ໄດ້ຈົນກວ່າຈະຮອດ <xliff:g id="END_TIME_0">%1$s</xliff:g> ເນື່ອງຈາກກຳລັງບັນທຶກຊ່ອງອື່ນຢູ່. \n\nກົດຂວາເພື່ອປັບແຕ່ງເວລາການບັນທຶກ.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"ບໍ່ມີຫົວຂໍ້"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"​ຊ່ອງ​ຖືກບລັອກ"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"ໃໝ່"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"ແຫຼ່ງທີ່ມາຂອງຊ່ອງ"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d ຊ່ອງ</item>
+ <item quantity="one">%1$d ຊ່ອງ</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"ບໍ່​ມີ​ຊ່ອງ​ພ້ອມ​ໃຊ້​ງານ​ໄດ້​ຢູ່"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"ໃໝ່"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"ບໍ່ໄດ້​ຕິດ​ຕັ້ງ"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"ເບິ່ງແຫຼ່ງທີ່ມາຂອງຊ່ອງເພີ່ມເຕີມ"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"ທ່ອງເບິ່ງແອັບທີ່ໃຫ້ຊ່ອງຖ່າຍທອດສົດ"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"ມີແຫຼ່ງ​ຊ່ອງ​ໃໝ່"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"ແຫຼ່ງຊ່ອງໃໝ່ມີຊ່ອງຕ່າງໆໄວ້ໃຫ້ບໍລິການ.\nຕັ້ງພວກມັນດຽວນີ້, ຫຼືເຮັດສິ່ງນີ້ໃນພາຍຫຼັງໃນການຕັ້ງຄ່າແຫຼ່ງຊ່ອງ."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"ຕັ້ງດຽວນີ້"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"ຕົກລົງ, ເຂົ້າ​ໃຈ​ແລ້ວ"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>"ກົດ SELECT"</b>" ເພື່ອ​ເຂົ້າ​ຫາ​ເມ​ນູ TV."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"ບໍ່​ພົບການ​ປ້ອນ​ເຂົ້າ TV"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"ບໍ່​ສາ​ມາດ​ຊອກ​ຫາການ​ປ້ອນ​ເຂົ້າ TV ​ໄດ້"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ປະ​ເພດ​ເຄື່ອງ​ຈູນ​ບໍ່​ເໝາະ​ສົມ; ກະ​ລຸ​ນາ​ເປີດ​ໃຊ້​ແອັບ​ຊ່ອງ​ສົດ​ສຳ​ລັບ​ການ​ປ້ອນ​ເຂົ້າ TV ປະ​ເພດ​ເຄື່ອງ​ຈູນ."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ການ​ປັບ​ຊ່ອງ​ລົ້ມ​ເຫລວ"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"ບໍ່ພົບແອັບຯທີ່ໃຊ້ເພື່ອດຳເນີນການ."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"ຊ່ອງ​ແຫລ່ງ​ຂໍ້​ມູນ​ທັງ​ໝົດ​ຖືກ​ເຊື່ອງ​ໄວ້​ແລ້ວ.\nກະ​ລຸ​ນາ​ເລືອກ​ຢ່າງ​ໜ້ອຍ​ນຶ່ງ​ຊ່ອງ​ເພື່ອ​ເບິ່ງ."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ວິ​ດີ​ໂອບໍ່​ສາ​ມາດ​ເບິ່ງ​ໄດ້​ໂດຍບໍ່​ຄາດ​ຄິດ"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"ປຸ່ມ Back ແມ່ນ​ສຳ​ລັບ​ອຸ​ປະ​ກອນ​ທີ່​ເຊື່ອມ​ຕໍ່​ແລ້ວ. ໃຫ້​ກົດ​ປຸ່ມ Home ເພື່ອອອກ."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"ຊ່ອງ​ສົດ​ຕ້ອງ​ມີ​ການ​ອະ​ນຸ​ຍາດ​ເພື່ອ​ອ່ານ​ການ​ຈັດ​ລາຍ​ການ TV."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"ຕັ້ງຄ່າແຫຼ່ງຊ່ອງຂອງທ່ານ"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"ຊ່ອງອອກອາກາດສົດລວມເອົາປະສົບການຂອງຊ່ອງໂທລະພາບແບບເດີມເຂົ້າກັບຊ່ອງທີ່ໃຊ້ການສະຕຣີມທີ່ສະໜອງໃຫ້ໂດຍແອັບ. \n\nເລີ່ມຕົ້ນນຳໃຊ້ໂດຍການຕັ້ງຄ່າແຫຼ່ງຊ່ອງທີ່ຕິດຕັ້ງແລ້ວ. ຫຼື ຊອກຫາແອັບເພີ່ມເຕີມທີ່ໃຫ້ຊ່ອງອອກອາກາດສົດໃນ Google Play Store."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"ການບັນທຶກ ແລະ ການຕັ້ງເວລາ"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 ນາທີ"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 ນາທີ"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ຊົ່ວໂມງ"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ຊົ່ວໂມງ"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"ຫຼ້າສຸດ"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"ຕັ້ງເວລາໄວ້ແລ້ວ"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"ຊີຣີ"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"ອື່ນໆ"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ບໍ່ສາມາດບັນທຶກຊ່ອງໄດ້."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"ບໍ່ສາມາດບັນທຶກລາຍການໄດ້."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ຖືກຕັ້ງເວລາໃຫ້ບັນທຶກໄວ້ແລ້ວ"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ກຳລັງບັນທຶກ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ຈາກຕອນນີ້ຫາ <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"ຕາລາງແບບເຕັມ"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">%1$d ມື້ຖັດໄປ</item>
+ <item quantity="one">%1$d ມື້ຖັດໄປ</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d ນາທີ</item>
+ <item quantity="one">%1$d ນາທີ</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d ການບັນທຶກສຽງໃໝ່</item>
+ <item quantity="one">%1$d ການບັນທຶກສຽງໃໝ່</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d ການບັນທຶກ</item>
+ <item quantity="one">%1$d ການບັນທຶກ</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d ການບັນທຶກທີ່ຕັ້ງເວລາໄວ້ແລ້ວ</item>
+ <item quantity="one">%1$d ການບັນທຶກທີ່ຕັ້ງເວລາໄວ້ແລ້ວ</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"ຍົກເລີກການບັນທຶກ"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"ຢຸດການບັນທຶກ"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"ເບິ່ງ"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"ຫຼິ້ນຕັ້ງແຕ່ຕົ້ນ"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"ສືບຕໍ່ຫຼິ້ນວິດີໂອ"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"​ລຶບ"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ລຶບການບັນທຶກອອກ"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"ສືບຕໍ່"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"ຊີຊັນ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"ເບິ່ງຕາຕາລາງ"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"ອ່ານເພີ່ມເຕີມ"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ລຶບການບັນທຶກອອກ"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"ເລືອກເອັບພິໂສດທີ່ທ່ານຕ້ອງການລຶບອອກ. ພວກມັນຈະບໍ່ສາມາດກູ້ກັບຄືນມາໄດ້ຫຼັງຈາກທີ່ລຶບອອກໄປແລ້ວ."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"ບໍ່ມີການບັນທຶກໃຫ້ລຶບ."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"ເລືອກເອັບພິໂສດທີ່ເບິ່ງແລ້ວ"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"ເລືອກເອັບພິໂສດທັງໝົດ"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"ບໍ່ເລືອກເອັບພິໂສດທັງໝົດ"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"ເບິ່ງໄປແລ້ວ <xliff:g id="WATCHED">%1$d</xliff:g> ນາທີຈາກທັງໝົດ <xliff:g id="DURATION">%2$d</xliff:g> ນາທີ"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"ເບິ່ງໄປແລ້ວ <xliff:g id="WATCHED">%1$d</xliff:g> ວິນາທີຈາກທັງໝົດ <xliff:g id="DURATION">%2$d</xliff:g> ວິນາທີ"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"ຍັງບໍ່ເຄີຍເບິ່ງ"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">ລຶບເອັບພິໂສດ %1$d ຕອນຈາກທັງໝົດ %2$d ຕອນອອກແລ້ວ</item>
+ <item quantity="one">ລຶບເອັບພິໂສດ %1$d ຕອນຈາກທັງໝົດ %2$d ຕອນອອກແລ້ວ</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ຄວາມສຳຄັນ"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ສູງສຸດ"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ຕ່ຳສຸດ"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"ບໍ່. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"​ຊ່ອງ"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ອັນ​ໃດ​ກໍ່​ໄດ້"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"ເລືອກຄວາມສຳຄັນ"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"ເມື່ອມີໂປຣແກຣມໃຫ້ບັນທຶກຫຼາຍເກີນໄປໃນເວລາດຽວກັນ, ລະບົບຈະບັນທຶກລາຍການທີ່ມີຄວາມສຳຄັນສູງກວ່າເທົ່ານັ້ນ."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"ບັນທຶກ"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ການບັນທຶກຕາມເວລາມີຄວາມສຳຄັນສູງສຸດ"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"ຢຸດ"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ເບິ່ງຕາຕາລາງການບັນທຶກ"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"ນີ້ເປັນລາຍການດ່ຽວ"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ຕອນນີ້ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"ທັງຊີຣີ…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"ຕັ້ງເວລາຕໍ່ໄປໂລດ"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"ບັນທຶກອັນນີ້ແທນ"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ຍົກເລີກການບັນທຶກນີ້"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"ເບິ່ງດຽວນີ້"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"ລຶບການບັນທຶກອອກ…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"ບັນທຶກໄດ້"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ຕັ້ງເວລາບັນທຶກແລ້ວ"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ເກີດຄວາມຂັດແຍ່ງໃນການບັນທຶກ"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ກຳລັງບັນທຶກ"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ບັນທຶກບໍ່ສຳເລັດ"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"ກຳລັງອ່ານລາຍການ"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"ເບິ່ງການບັນທຶກຫຼ້າສຸດ"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"ບັນທຶກ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ບໍ່ສົມບູນ."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"ບັນທຶກ <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ແລະ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ບໍ່ສົມບູນ."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"ບັນທຶກ <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ແລະ <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ບໍ່ສົມບູນ."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"ບັນທຶກ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ບໍ່ສຳເລັດເນື່ອງຈາກບ່ອນຈັດເກັບຂໍ້ມູນບໍ່ພຽງພໍ."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"ບັນທຶກ <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ແລະ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ບໍ່ສຳເລັດເນື່ອງຈາກບ່ອນຈັດເກັບຂໍ້ມູນບໍ່ພຽງພໍ."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"ບັນທຶກ <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ແລະ <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ບໍ່ສຳເລັດເນື່ອງຈາກບ່ອນຈັດເກັບຂໍ້ມູນບໍ່ພຽງພໍ."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR ຕ້ອງໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນເພີ່ມເຕີມ"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"ທ່ານຈະສາມາດບັນທຶກລາຍການດ້ວຍ DVR ໄດ້. ຢ່າງໃດກໍຕາມ, ອຸປະກອນຂອງທ່ານບໍ່ມີບ່ອນຈັດເກັບຂໍ້ມູນພຽງພໍໃຫ້ DVR ເຮັດວຽກໄດ້. ກະລຸນາເຊື່ອມຕໍ່ຫາໄດຣຟ໌ພາຍນອກທີ່ມີຂະໜາດ <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB ຫຼືໃຫຍ່ກວ່າ ແລ້ວເຮັດຕາມຂັ້ນຕອນໃນການໃຊ້ມັນເປັນອຸປະກອນຈັດເກັບຂໍ້ມູນ."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"ບ່ອນຈັດເກັບຂໍ້ມູນບໍ່ພຽງພໍ"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"ຈະບໍ່ບັນທຶກລາຍການນີ້ເນື່ອງຈາກມີບ່ອນຈັດເກັບຂໍ້ມູນບໍ່ພຽງພໍ. ໃຫ້ລອງລຶບການບັນທຶກບາງອັນອອກກ່ອນ."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"ບໍ່ພົບບ່ອນຈັດເກັບຂໍ້ມູນ"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ຢຸດການບັນທຶກໄວ້ບໍ?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ເນື້ອຫາທີ່ອັດໄວ້ແລ້ວຈະຖືກບັຍທຶກໄວ້."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"ການບັນທຶກ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ຈະຖືກຢຸດໄວ້ເພາະມັນຂັດແຍ່ງກັບລາຍການນີ້. ເນື້ອຫາທີ່ບັນທຶກໄປແລ້ວຈະຖືກຈັດເກັບໄວ້."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ຕັ້ງເວລາການບັນທຶກແລ້ວແຕ່ມີຂໍ້ຂັດແຍ່ງເກີດຂຶ້ນ"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ເລີ່ມການບັນທຶກແລ້ວແຕ່ມີຂໍ້ຂັດແຍ່ງ"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ຈະຖືກບັນທຶກໄວ້."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"ກຳລັງບັນທຶກ <xliff:g id="CHANNELNAME">%1$s</xliff:g>."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"ບາງສ່ວນຂອງ <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ຈະບໍ່ຖືກບັນທຶກ."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"ບາງສ່ວນຂອງ <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> ແລະ <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ຈະບໍ່ຖືກບັນທຶກ."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"ບາງສ່ວນຂອງ <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ແລະ ອີກໜຶ່ງລາຍການຈະບໍ່ຖືກບັນທຶກ."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other">ບາງສ່ວນຂອງ <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ແລະ ເພີ່ມເຕີມອີກ %3$d ລາຍການຈະບໍ່ມີການບັນທຶກໄວ້.</item>
+ <item quantity="one">ບາງສ່ວນຂອງ <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> ແລະ ເພີ່ມເຕີມອີກ %3$d ລາຍການຈະບໍ່ມີການບັນທຶກໄວ້.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"ທ່ານຕ້ອງການບັນທຶກຫຍັງ?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"ທ່ານຕ້ອງການບັນທຶກດົນປານໃດ?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ມີການຕັ້ງເວລາຢູ່ກ່ອນແລ້ວ"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"ລາຍການດຽວກັນນີ້ໄດ້ຕັ້ງເວລາໃຫ້ບັນທຶກໄວ້ແລ້ວເວລາ <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ບັນທຶກໄປກ່ອນແລ້ວ"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ລາຍການນີ້ຖືກບັນທຶກໄປກ່ອນແລ້ວ. ມັນສາມາດເບິ່ງໄດ້ໃນຫ້ອງສະໝຸດ DVR."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"ຕັ້ງເວລາບັນທຶກຊີຣີແລ້ວ"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">ຕັ້ງເວລາບັນທຶກ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ລາຍການສຳລັບ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ແລ້ວ.</item>
+ <item quantity="one">ຕັ້ງເວລາບັນທຶກ <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ລາຍການສຳລັບ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ແລ້ວ.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">ຕັ້ງເວລາບັນທຶກ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ລາຍການສຳລັບ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ແລ້ວ. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> ລາຍການຈະບໍ່ຖືກບັນທຶກເນື່ອງຈາກມີຂໍ້ຂັດແຍ່ງ.</item>
+ <item quantity="one">ຕັ້ງເວລາບັນທຶກ <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ລາຍການສຳລັບ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ແລ້ວ. ມັນຈະບໍ່ຖືກບັນທຶກເນື່ອງຈາກມີຂໍ້ຂັດແຍ່ງ.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">ຕັ້ງເວລາບັນທຶກ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ລາຍການສຳລັບ <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ແລ້ວ. ຈະບໍ່ບັນທຶກເອັບພິໂສດ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ຕອນຂອງຊີຣີອື່ນເນື່ອງຈາກເວລາຂັດແຍ່ງກັນ.</item>
+ <item quantity="one">ຕັ້ງເວລາບັນທຶກ <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ລາຍການສຳລັບ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ແລ້ວ. ຈະບໍ່ບັນທຶກເອັບພິໂສດ <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ຕອນຂອງຊີຣີອື່ນເນື່ອງຈາກເວລາຂັດແຍ່ງກັນ.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">ຕັ້ງເວລາບັນທຶກ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ລາຍການສຳລັບ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ແລ້ວ. ຈະບໍ່ບັນທຶກເອັບພິໂສດ 1 ຕອນຂອງຊີຣີອື່ນເນື່ອງຈາກເວລາຂັດແຍ່ງກັນ.</item>
+ <item quantity="one">ຕັ້ງເວລາບັນທຶກ <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ລາຍການສຳລັບ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ແລ້ວ. ຈະບໍ່ບັນທຶກເອັບພິໂສດ 1 ຕອນຂອງຊີຣີອື່ນເນື່ອງຈາກເວລາຂັດແຍ່ງກັນ.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">ຕັ້ງເວລາບັນທຶກ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ລາຍການສຳລັບ <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ແລ້ວ. ຈະບໍ່ບັນທຶກເອັບພິໂສດ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ຕອນຂອງຊີຣີອື່ນເນື່ອງຈາກເວລາຂັດແຍ່ງກັນ.</item>
+ <item quantity="one">ຕັ້ງເວລາບັນທຶກ <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ລາຍການສຳລັບ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ແລ້ວ. ຈະບໍ່ບັນທຶກເອັບພິໂສດ <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ຕອນຂອງຊີຣີອື່ນເນື່ອງຈາກເວລາຂັດແຍ່ງກັນ.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"ບໍ່ພົບໂປຣແກຣມທີ່ບັນທຶໄວ້."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ການບັນທຶກທີ່ກ່ຽວຂ້ອງ"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d ການບັນທຶກ</item>
+ <item quantity="one">%1$d ການບັນທຶກ</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"ລຶບ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ອອກຈາກກຳນົດການບັນທຶກແລ້ວ"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ຈະຖືກບັນທຶກບາງສ່ວນເນື່ອງຈາກມີຄວາມຂັດແຍ່ງໃນຕົວປັບຫາສັນຍານ."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ຈະບໍ່ຖືກບັນທຶກເນື່ອງຈາກມີຄວາມຂັດແຍ່ງໃນຕົວປັບຫາສັນຍານ."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ຍັງບໍ່ມີການຕັ້ງເວລາບັນທຶກເທື່ອ.\nທ່ານສາມາດຕັ້ງເວລາບັນທຶກໄດ້ຈາກຄຳແນະນຳລາຍການ."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d ການບັນທຶກທີ່ຂັດແຍ່ງກັນ</item>
+ <item quantity="one">%1$d ການບັນທຶກທີ່ຂັດແຍ່ງກັນ</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"ການຕັ້ງຄ່າຊີຣີ"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"ເລີ່ມການບັນທຶກຊີຣີ"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"ຢຸດການບັນທຶກຊີຣີ"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"ຢຸດການບັນທຶກຊີຣີບໍ່?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ເອັບພິໂສດທີ່ບັນທຶກໄວ້ແລ້ວຈະຍັງຄົງສາມາດເບິ່ງໄດ້ໃນຫ້ອງສະໝຸດ DVR ຢູ່."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"ຢຸດ"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ບໍ່ມີເອັບພິໂສດໃດທີ່ກຳລັງສາຍຢູ່ໃນຕອນນີ້."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ຍັງບໍ່ມີເອບພິໂສດທີ່ສາມາດເບິ່ງໄດ້ເທື່ອ.\nພວກມັນຈະຖືກບັນທຶອຶກເມື່ອມີການສາຍ."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d ນາທີ)</item>
+ <item quantity="one">(%1$d ນາທີ) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"ມື້ນີ້"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"ມື້ອື່ນ"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"ມື້ວານນີ້"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ມື້ນີ້"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ມື້ອື່ນ"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"ຄະແນນ"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"ລາຍການທີ່ບັນທຶກໄວ້ແລ້ວ"</string>
+</resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
deleted file mode 100644
index 05aba1ce..00000000
--- a/res/values-lo/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"​ໂມ​ໂນ"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"ສະ​ເຕ​ຣິ​ໂອ"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"ຄວບ​ຄຸມ​ການ​ຫຼິ້ນ"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"ຊ່ອງ​ບໍ່ດົນ​ມານີ້"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"ໂຕເລືອກ​ໂທລະພາບ"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"​ຕົວ​ເລືອກ PIP"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"ຫຼິ້ນ​ການ​ຄວບ​ຄຸມ​ບໍ່​ມີ​ໃຫ້​ສຳ​ລັບ​ຊ່ອງ​ນີ້"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ຫຼິ້ນ​ ຫລື​ຢຸດ​ຊົ່ວ​ຄາວ"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ເລື່ອນ​ໄປ​ໜ້າ"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"​ຣີ​ວາຍກັບ"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"ຕໍ່​ໄປ"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"ກ່ອນໜ້າ"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"ຄຳ​ແນະນຳ​ລາຍການ"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"ມີ​ຊ່ອງ​ໃໝ່​ໃຫ້​ຢູ່"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"ເປີດ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"ຄຳ​ບັນຍາຍ​ແບບ​ປິດ"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"ໂໝດ​ການ​ສະແດງຜົນ"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"​ເປີດ"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"ປິດ"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"ຫຼາຍສຽງ"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"ເອົາຊ່ອງເພີ່ມເຕີມ"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"ການ​ຕັ້ງ​ຄ່າ"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"ທີ່​ມາ"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"ສະຫຼັບ"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"​ເປີດ"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"ປິດ"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"ສຽງ"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"ຫຼັກ"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"ໜ້າ​ຕ່າງ PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"ຮູບ​ແບບ"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"ເບື້ອງ​ຂວາ​ທາງ​ລຸ່ມ"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"ເບື້ອງ​ຂວາ​ດ້ານ​ເທິງ"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"ເບື້ອງ​ຊ້າຍ​ດ້ານ​ເທິງ"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"ເບື້ອງ​ຊ້າຍທາງ​ລຸ່ມ"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"ເທື່ອ​ລະ​ດ້ານ"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"ຂະໜາດ"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"ໃຫຍ່"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"ນ້ອຍ"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"​ແຫຼ່ງ​ສັນ​ຍານ"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (ເສົາ​ສັນ​ຍານ/ສາຍ​ເຄ​ເບິນ)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"ບໍ່​ມີ​ຂໍ້​ມູນ​ລາຍ​ການ"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"ບໍ່ມີຂໍ້ມູນ"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"ຊ່ອງ​ທີ່​ຖືກບ​ລັອກ"</string>
- <string name="default_language" msgid="4122326459624337928">"ພາ​ສາ​ບໍ່​ຮູ້​ຈັກ"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"ຄຳ​ບັນຍາຍ​ແບບ​ປິດ"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ປິດ"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"ປັບແຕ່ງການຈັດຮູບແບບ"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"ກຳນົດ​ການຕັ້ງຄ່າ​ລະບົບ​ສຳລັບ​ຄຳ​ບັນຍາຍ​ແບບ​ປິດ"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ໂໝດ​ສະແດງ​ຜົນ"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"ຫຼາຍ​ສຽງ"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"​ໂມ​ໂນ"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ສະເຕຣິໂອ"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"ສຽງ​ຮອບ​ທິດ​ທາງ 5.1"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"ສຽງ​ຮອບ​ທິດ​ທາງ 7.1"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ​ຊ່ອງ"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ປັບແຕ່ງ​ລາຍ​ຊື່​ຊ່ອງ"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ເລືອກກຸ່ມ"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"ບໍ່​ເລືອກ​ກຸ່ມ"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ຈັດກຸ່ມຕາມ"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ທີ່​ມາ​ຂອງ​ຊ່ອງ"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"ຈັດກຸ່ມຕາມ"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"ໂປ​ຣ​ແກ​ຣມ​ນີ້​ຖືກບ​ລັອກ​ແລ້ວ"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"​ລາຍ​ການ​ນີ້​ຖືກ​ຈັດ​ປະ​ເພດ <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"ອິນ​ພຸດ​ນີ້ບໍ່​ຮອງ​ຮັບ​ການ​ສະ​ແກນ​ອັດ​ຕະ​ໂນ​ມັດ"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"ບໍ່​ສາ​ມາດ​ເລີ່ມ​ການ​ສະ​ແກນ​ອັດ​ຕະ​ໂນ​ມັດ​ສຳ​ລັບ \'<xliff:g id="TV_INPUT">%s</xliff:g>\' ໄດ້"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"ບໍ່​ສາ​ມາດ​ເລີ່ມ​ການ​ຕັ້ງ​ຄ່າ​ທົ່ວ​ລະ​ບົບ​ສຳ​ລັບ​ຄຳ​ບັນ​ຍາຍ​ແບບ​ປິດ​ໄດ້."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">ເພີ່ມ %1$d ຊ່ອງແລ້ວ</item>
- <item quantity="one">ເພີ່ມ %1$d ຊ່ອງແລ້ວ</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"ບໍ່​ໄດ້​ເພີ່ມ​ຊ່ອງ"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"​ທູນ​ເນີ"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"ການ​ຄວບຄຸມ​ຂອງ​ຜູ່​ປົກ​ຄອງ"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ເປີດ"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ປິດ"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"ຊ່ອງ​ຖືກ​ບລັອກ​ແລ້ວ"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"​ບລັອກ​​ທັງ​​ໝົດ"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"ປົດ​ບລັອກ​ທັງ​ໝົດ"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"​ຊ່ອງ​ທີ່​ຖືກ​ເຊື່ອງ"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"ການ​ຈຳກັດ​ລາຍການ"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"​ປ່ຽນ​ PIN"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"​ລະ​ບົບ​ການ​ຈັດ​ປະ​ເພດ"</string>
- <string name="option_ratings" msgid="4009116954188688616">"​​​ການ​ຈັດ​ປະ​ເພດ"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"ເບິ່ງ​ລະບົບ​ການ​ຈັດ​ປະເພດ​ທັງ​ໝົດ"</string>
- <string name="other_countries" msgid="8342216398676184749">"ປະ​ເທດ​ອື່ນໆ"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"ບໍ່ມີ"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ບໍ່ມີ"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"ບໍ່ມີ"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"ຈຳກັດສູງ"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"ຈຳກັດປານກາງ"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"ຈຳກັດຕ່ຳ"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"ກຳນົດເອງ"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"ເນື້ອຫາ​ເໝາະສົມ​ສຳລັບ​ເດັກນ້ອຍ"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"ເນື້ອຫາ​ເໝາະ​ສຳລັບ​ເດັກ​ທີ່​ບໍ່​ນ້ອຍ​ຫຼາຍ"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"​ເນື້ອ​ຫາ​ເໝາະ​ສົມ​ສຳ​ລັບ​ໄວ​ຮຸ່ນ"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"ຈຳ​ກັດແບບ​​ລະ​ບຸ​ເອງ"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s ແລະປະເພດຍ່ອຍ"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"ປະເພດຍ່ອຍ"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ປ້ອນ​ລະ​ຫັດ​ PIN ຂອງ​ທ່ານ​ເພື່ອ​ເບິ່ງ​ຊ່ອງ​ນີ້"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"​ປ້ອນ​ລະ​ຫັດ PIN ຂອງ​ທ່ານ​ເພື່ອ​ເບິ່ງ​ລາຍ​ການ​ນີ້"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ລາຍການນີ້ຖືກຈັດປະເພດເປັນ <xliff:g id="RATING">%1$s</xliff:g>. ກະລຸນາໃສ່ລະຫັດ PIN ຂອງທ່ານເພື່ອເບິ່ງລາຍການນີ້"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"​ປ້ອນ​ລະ​ຫັດ PIN ຂອງ​ທ່ານ"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"ເພື່ອ​ຕັ້ງ​ຄ່າ​ຄວບ​ຄຸມ​ຂອງ​ຜູ່​ປົກ​ຄອງ, ກະລຸ​ນາຕັ້ງ​ລະ​ຫັດ PIN"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"ໃສ່ລະຫັດ PIN ໂຕໃຫມ່"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"ຢືນຢັນ​ລະຫັດ PIN ຂອງທ່ານ"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"ປ້ອນ​ລະ​ຫັດ PIN ປັດ​ຈຸ​ບັນ​ຂອງ​ທ່ານ"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">ທ່ານປ້ອນ PIN ບໍ່ຖືກຕ້ອງ 5 ເທື່ອແລ້ວ.\nລອງອີກເທື່ອໃນ <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> ວິນາທີ.</item>
- <item quantity="one">ທ່ານປ້ອນ PIN ບໍ່ຖືກຕ້ອງ 5 ເທື່ອແລ້ວ.\nລອງອີກເທື່ອໃນ <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> ວິນາທີ.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"ລະຫັດ PIN ນັ້ນບໍ່​ຖືກ​ຕ້ອງ, ກະ​ລຸ​ນາລອງ​ໃຫມ່​ອີກ​ຄັ້ງ."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"ລະ​ຫັດ PIN ບໍ່​ກົງ​ກັນ, ກະ​ລຸ​ນາ​ລອງ​ໃໝ່."</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"ການ​ຕັ້ງ​ຄ່າ"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ປັບແຕ່ງ​ລາຍ​ຊື່​ຊ່ອງ"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ເລືອກ​ຊ່ອງ​ສຳລັບການ​ແນະນຳລາຍການ​ຂອງ​ທ່ານ"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ແຫຼ່ງທີ່ມາ​ຂອງ​ຊ່ອງ"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"ມີ​ຊ່ອງ​ໃໝ່​"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"ການ​ຄວບຄຸມ​ຂອງພໍ່ແມ່"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"​ໃບ​ອະ​ນຸ​ຍາດ​ Open source"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"​ໃບ​ອະ​ນຸ​ຍາດ​ແຫຼ່ງ​ເປີດ"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"ເວີຊັນ"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"​ເພື່ອ​ເບິ່ງ​ຊ່ອງ​ນີ້, ກົດ​ປຸ່ມ ຂວາ ແລະ ປ້ອນ​ລະ​ຫັດ PIN ຂອງ​ທ່ານ"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"​ເພື່ອ​ເບິ່ງ​ລາຍ​ການ​ນີ້, ໃຫ້ກົດ​ປຸ່ມ ຂວາ ແລະ ປ້ອນ​ລະ​ຫັດ PIN ຂອງ​ທ່ານ"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"​ລາຍ​ການ​ນີ້​ຖືກ​ຈັດ​ປະ​ເພດ​ <xliff:g id="RATING">%1$s</xliff:g>.\n​ເພື່ອ​ເບິ່ງ​ລາຍ​ການ​ນີ້, ໃຫ້ກົດ​ປຸ່ມ ຂວາ ແລະ ປ້ອນ​ລະ​ຫັດ PIN ຂອງ​ທ່ານ"</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ເພື່ອເບິ່ງຊ່ອງນີ້, ໃຊ້ແອັບ Live TV ມາດຕະຖານ."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ເພື່ອເບິ່ງໂປຣແກຣມນີ້, ໃຊ້ແອັບ Live TV ມາດຕະຖານ."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ໂປຣແກຣມນີ້ຖືກຈັດປະເພດ <xliff:g id="RATING">%1$s</xliff:g>.\nເພື່ອເບິ່ງໂປຣແກຣມນີ້, ໃຊ້ແອັບ Live TV ມາດຕະຖານ."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"​ລາຍ​ການ​ຖືກບລັອກ"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"​ລາຍ​ການ​ນີ້​ຖືກ​ຈັດ​ປະ​ເພດ <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ສຽງເທົ່ານັ້ນ"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"ສັນຍານອ່ອນ"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">ບໍ່ສາມາດຫຼິ້ນຊ່ອງນີ້ໄດ້ຈົນກວ່າຈະຮອດ <xliff:g id="END_TIME_1">%1$s</xliff:g> ເນື່ອງຈາກກຳລັງບັນທຶກຊ່ອງອື່ນຢູ່. \n\nກົດຂວາເພື່ອປັບແຕ່ງເວລາການບັນທຶກ.</item>
- <item quantity="one">ບໍ່ສາມາດຫຼິ້ນຊ່ອງນີ້ໄດ້ຈົນກວ່າຈະຮອດ <xliff:g id="END_TIME_0">%1$s</xliff:g> ເນື່ອງຈາກກຳລັງບັນທຶກຊ່ອງອື່ນຢູ່. \n\nກົດຂວາເພື່ອປັບແຕ່ງເວລາການບັນທຶກ.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"ບໍ່ມີຫົວຂໍ້"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"​ຊ່ອງ​ຖືກບລັອກ"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"ໃໝ່"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"ແຫຼ່ງທີ່ມາຂອງຊ່ອງ"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d ຊ່ອງ</item>
- <item quantity="one">%1$d ຊ່ອງ</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"ບໍ່​ມີ​ຊ່ອງ​ພ້ອມ​ໃຊ້​ງານ​ໄດ້​ຢູ່"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"ໃໝ່"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"ບໍ່ໄດ້​ຕິດ​ຕັ້ງ"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"ເບິ່ງແຫຼ່ງທີ່ມາຂອງຊ່ອງເພີ່ມເຕີມ"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"ທ່ອງເບິ່ງແອັບທີ່ໃຫ້ຊ່ອງຖ່າຍທອດສົດ"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"ມີແຫຼ່ງ​ຊ່ອງ​ໃໝ່"</string>
- <string name="new_sources_description" msgid="749649005588426813">"ແຫຼ່ງຊ່ອງໃໝ່ມີຊ່ອງຕ່າງໆໄວ້ໃຫ້ບໍລິການ.\nຕັ້ງພວກມັນດຽວນີ້, ຫຼືເຮັດສິ່ງນີ້ໃນພາຍຫຼັງໃນການຕັ້ງຄ່າແຫຼ່ງຊ່ອງ."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"ຕັ້ງດຽວນີ້"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"ຕົກລົງ, ເຂົ້າ​ໃຈ​ແລ້ວ"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307"><b>"ກົດ SELECT"</b>" ເພື່ອ​ເຂົ້າ​ຫາ​ເມ​ນູ TV."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"ບໍ່​ພົບການ​ປ້ອນ​ເຂົ້າ TV"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"ບໍ່​ສາ​ມາດ​ຊອກ​ຫາການ​ປ້ອນ​ເຂົ້າ TV ​ໄດ້"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"ບໍ່​ຮອງ​ຮັບ PIP"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"ບໍ່ມີການຮັບສັນຍານທີ່ສາມາດສະແດງໄດ້ດ້ວຍຮູບພາບຊ້ອນຮູບພາບ PIP"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ປະ​ເພດ​ເຄື່ອງ​ຈູນ​ບໍ່​ເໝາະ​ສົມ; ກະ​ລຸ​ນາ​ເປີດ​ໃຊ້​ແອັບ​ຊ່ອງ​ສົດ​ສຳ​ລັບ​ການ​ປ້ອນ​ເຂົ້າ TV ປະ​ເພດ​ເຄື່ອງ​ຈູນ."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"ການ​ປັບ​ຊ່ອງ​ລົ້ມ​ເຫລວ"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"ບໍ່ພົບແອັບຯທີ່ໃຊ້ເພື່ອດຳເນີນການ."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"ຊ່ອງ​ແຫລ່ງ​ຂໍ້​ມູນ​ທັງ​ໝົດ​ຖືກ​ເຊື່ອງ​ໄວ້​ແລ້ວ.\nກະ​ລຸ​ນາ​ເລືອກ​ຢ່າງ​ໜ້ອຍ​ນຶ່ງ​ຊ່ອງ​ເພື່ອ​ເບິ່ງ."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ວິ​ດີ​ໂອບໍ່​ສາ​ມາດ​ເບິ່ງ​ໄດ້​ໂດຍບໍ່​ຄາດ​ຄິດ"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"ປຸ່ມ Back ແມ່ນ​ສຳ​ລັບ​ອຸ​ປະ​ກອນ​ທີ່​ເຊື່ອມ​ຕໍ່​ແລ້ວ. ໃຫ້​ກົດ​ປຸ່ມ Home ເພື່ອອອກ."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"ຊ່ອງ​ສົດ​ຕ້ອງ​ມີ​ການ​ອະ​ນຸ​ຍາດ​ເພື່ອ​ອ່ານ​ການ​ຈັດ​ລາຍ​ການ TV."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"ຕັ້ງຄ່າແຫຼ່ງຊ່ອງຂອງທ່ານ"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"ຊ່ອງອອກອາກາດສົດລວມເອົາປະສົບການຂອງຊ່ອງໂທລະພາບແບບເດີມເຂົ້າກັບຊ່ອງທີ່ໃຊ້ການສະຕຣີມທີ່ສະໜອງໃຫ້ໂດຍແອັບ. \n\nເລີ່ມຕົ້ນນຳໃຊ້ໂດຍການຕັ້ງຄ່າແຫຼ່ງຊ່ອງທີ່ຕິດຕັ້ງແລ້ວ. ຫຼື ຊອກຫາແອັບເພີ່ມເຕີມທີ່ໃຫ້ຊ່ອງອອກອາກາດສົດໃນ Google Play Store."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"ການບັນທຶກ ແລະ ການຕັ້ງເວລາ"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 ນາທີ"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 ນາທີ"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ຊົ່ວໂມງ"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ຊົ່ວໂມງ"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"ຫຼ້າສຸດ"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"ຕັ້ງເວລາໄວ້ແລ້ວ"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"ຊີຣີ"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"ອື່ນໆ"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ບໍ່ສາມາດບັນທຶກຊ່ອງໄດ້."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"ບໍ່ສາມາດບັນທຶກລາຍການໄດ້."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ຖືກຕັ້ງເວລາໃຫ້ບັນທຶກໄວ້ແລ້ວ"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ກຳລັງບັນທຶກ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ຈາກຕອນນີ້ຫາ <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"ຕາລາງແບບເຕັມ"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">%1$d ມື້ຖັດໄປ</item>
- <item quantity="one">%1$d ມື້ຖັດໄປ</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d ນາທີ</item>
- <item quantity="one">%1$d ນາທີ</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d ການບັນທຶກສຽງໃໝ່</item>
- <item quantity="one">%1$d ການບັນທຶກສຽງໃໝ່</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d ການບັນທຶກ</item>
- <item quantity="one">%1$d ການບັນທຶກ</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d ການບັນທຶກທີ່ຕັ້ງເວລາໄວ້ແລ້ວ</item>
- <item quantity="one">%1$d ການບັນທຶກທີ່ຕັ້ງເວລາໄວ້ແລ້ວ</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"ເບິ່ງ"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"ຫຼິ້ນຕັ້ງແຕ່ຕົ້ນ"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"ສືບຕໍ່ຫຼິ້ນວິດີໂອ"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"​ລຶບ"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ລຶບການບັນທຶກອອກ"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"ສືບຕໍ່"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"ຊີຊັນ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"ເບິ່ງຕາຕາລາງ"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"ອ່ານເພີ່ມເຕີມ"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ລຶບການບັນທຶກອອກ"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"ເລືອກເອັບພິໂສດທີ່ທ່ານຕ້ອງການລຶບອອກ. ພວກມັນຈະບໍ່ສາມາດກູ້ກັບຄືນມາໄດ້ຫຼັງຈາກທີ່ລຶບອອກໄປແລ້ວ."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"ບໍ່ມີການບັນທຶກໃຫ້ລຶບ."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"ເລືອກເອັບພິໂສດທີ່ເບິ່ງແລ້ວ"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"ເລືອກເອັບພິໂສດທັງໝົດ"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"ບໍ່ເລືອກເອັບພິໂສດທັງໝົດ"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"ເບິ່ງໄປແລ້ວ <xliff:g id="WATCHED">%1$d</xliff:g> ນາທີຈາກທັງໝົດ <xliff:g id="DURATION">%2$d</xliff:g> ນາທີ"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"ເບິ່ງໄປແລ້ວ <xliff:g id="WATCHED">%1$d</xliff:g> ວິນາທີຈາກທັງໝົດ <xliff:g id="DURATION">%2$d</xliff:g> ວິນາທີ"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"ຍັງບໍ່ເຄີຍເບິ່ງ"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">ລຶບເອັບພິໂສດ %1$d ຕອນຈາກທັງໝົດ %2$d ຕອນອອກແລ້ວ</item>
- <item quantity="one">ລຶບເອັບພິໂສດ %1$d ຕອນຈາກທັງໝົດ %2$d ຕອນອອກແລ້ວ</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ຄວາມສຳຄັນ"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ສູງສຸດ"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ຕ່ຳສຸດ"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"ບໍ່. <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"​ຊ່ອງ"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ອັນ​ໃດ​ກໍ່​ໄດ້"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"ເລືອກຄວາມສຳຄັນ"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"ເມື່ອມີໂປຣແກຣມໃຫ້ບັນທຶກຫຼາຍເກີນໄປໃນເວລາດຽວກັນ, ລະບົບຈະບັນທຶກລາຍການທີ່ມີຄວາມສຳຄັນສູງກວ່າເທົ່ານັ້ນ."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"ບັນທຶກ"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ການບັນທຶກຕາມເວລາມີຄວາມສຳຄັນສູງສຸດ"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"​ຍົກເລີກ"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"ຍົກເລີກ"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"ລືມ"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"ຢຸດ"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ເບິ່ງຕາຕາລາງການບັນທຶກ"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"ນີ້ເປັນລາຍການດ່ຽວ"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ຕອນນີ້ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"ທັງຊີຣີ…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"ຕັ້ງເວລາຕໍ່ໄປໂລດ"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"ບັນທຶກອັນນີ້ແທນ"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ຍົກເລີກການບັນທຶກນີ້"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"ເບິ່ງດຽວນີ້"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"ບັນທຶກໄດ້"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ຕັ້ງເວລາບັນທຶກແລ້ວ"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ເກີດຄວາມຂັດແຍ່ງໃນການບັນທຶກ"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ກຳລັງບັນທຶກ"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ບັນທຶກບໍ່ສຳເລັດ"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"ກຳລັງອ່ານເນື້ອຫາລາຍການເພື່ອຕັ້ງເວລາບັນທຶກ"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"ກຳລັງອ່ານລາຍການ"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR ຕ້ອງໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນເພີ່ມເຕີມ"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"ທ່ານຈະສາມາດບັນທຶກລາຍການດ້ວຍ DVR ໄດ້. ຢ່າງໃດກໍຕາມ, ອຸປະກອນຂອງທ່ານບໍ່ມີບ່ອນຈັດເກັບຂໍ້ມູນພຽງພໍໃຫ້ DVR ເຮັດວຽກໄດ້. ກະລຸນາເຊື່ອມຕໍ່ຫາໄດຣຟ໌ພາຍນອກທີ່ມີຂະໜາດ <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB ຫຼືໃຫຍ່ກວ່າ ແລ້ວເຮັດຕາມຂັ້ນຕອນໃນການໃຊ້ມັນເປັນອຸປະກອນຈັດເກັບຂໍ້ມູນ."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"ບໍ່ພົບບ່ອນຈັດເກັບຂໍ້ມູນ"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"ບໍ່ພົບບ່ອນຈັດເກັບຂໍ້ມູນບາງອັນທີ່ໃຊ້ໂດຍ DVR. ກະລຸນາເຊື່ອມຕໍ່ໄດຣຟ໌ພາຍນອກທີ່ທ່ານໃຊ້ກ່ອນຈະເປີດໃຊ້ DVR ຄືນໃໝ່. ຫຼືອີກວິທີໜຶ່ງ, ທ່ານສາມາດເລືອກໃຫ້ລືມບ່ອນຈັດເກັບຂໍ້ມູນດັ່ງກ່າວໄດ້ຫາກມັນບໍ່ມີໃຫ້ໃຊ້ອີກຕໍ່ໄປແລ້ວ."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"ລືມການຈັດເກັບຂໍ້ມູນບໍ?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"ທ່ານຈະສູນເສຍເນື້ອຫາ ແລະ ການຕັ້ງເວລາທັງໝົດທີ່ທ່ານບັນທຶກໄວ້ແລ້ວ."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ຢຸດການບັນທຶກໄວ້ບໍ?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ເນື້ອຫາທີ່ອັດໄວ້ແລ້ວຈະຖືກບັຍທຶກໄວ້."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ຕັ້ງເວລາການບັນທຶກແລ້ວແຕ່ມີຂໍ້ຂັດແຍ່ງເກີດຂຶ້ນ"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ເລີ່ມການບັນທຶກແລ້ວແຕ່ມີຂໍ້ຂັດແຍ່ງ"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ຈະຖືກບັນທຶກໄວ້."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"ກຳລັງບັນທຶກ <xliff:g id="CHANNELNAME">%1$s</xliff:g>."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"ບາງສ່ວນຂອງ <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ຈະບໍ່ຖືກບັນທຶກ."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"ບາງສ່ວນຂອງ <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> ແລະ <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ຈະບໍ່ຖືກບັນທຶກ."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"ບາງສ່ວນຂອງ <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ແລະ ອີກໜຶ່ງລາຍການຈະບໍ່ຖືກບັນທຶກ."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other">ບາງສ່ວນຂອງ <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ແລະ ເພີ່ມເຕີມອີກ %3$d ລາຍການຈະບໍ່ມີການບັນທຶກໄວ້.</item>
- <item quantity="one">ບາງສ່ວນຂອງ <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> ແລະ ເພີ່ມເຕີມອີກ %3$d ລາຍການຈະບໍ່ມີການບັນທຶກໄວ້.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"ທ່ານຕ້ອງການບັນທຶກຫຍັງ?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"ທ່ານຕ້ອງການບັນທຶກດົນປານໃດ?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ມີການຕັ້ງເວລາຢູ່ກ່ອນແລ້ວ"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"ລາຍການດຽວກັນນີ້ໄດ້ຕັ້ງເວລາໃຫ້ບັນທຶກໄວ້ແລ້ວເວລາ <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ບັນທຶກໄປກ່ອນແລ້ວ"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ລາຍການນີ້ຖືກບັນທຶກໄປກ່ອນແລ້ວ. ມັນສາມາດເບິ່ງໄດ້ໃນຫ້ອງສະໝຸດ DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"ບໍ່ພົບໂປຣແກຣມທີ່ບັນທຶໄວ້."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ການບັນທຶກທີ່ກ່ຽວຂ້ອງ"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(ບໍ່ມີຄຳອະທິບາຍລາຍການ)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d ການບັນທຶກ</item>
- <item quantity="one">%1$d ການບັນທຶກ</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"ລຶບ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ອອກຈາກກຳນົດການບັນທຶກແລ້ວ"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ຈະຖືກບັນທຶກບາງສ່ວນເນື່ອງຈາກມີຄວາມຂັດແຍ່ງໃນຕົວປັບຫາສັນຍານ."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ຈະບໍ່ຖືກບັນທຶກເນື່ອງຈາກມີຄວາມຂັດແຍ່ງໃນຕົວປັບຫາສັນຍານ."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ຍັງບໍ່ມີການຕັ້ງເວລາບັນທຶກເທື່ອ.\nທ່ານສາມາດຕັ້ງເວລາບັນທຶກໄດ້ຈາກຄຳແນະນຳລາຍການ."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d ການບັນທຶກທີ່ຂັດແຍ່ງກັນ</item>
- <item quantity="one">%1$d ການບັນທຶກທີ່ຂັດແຍ່ງກັນ</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"ການຕັ້ງຄ່າຊີຣີ"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"ເລີ່ມການບັນທຶກຊີຣີ"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"ຢຸດການບັນທຶກຊີຣີ"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"ຢຸດການບັນທຶກຊີຣີບໍ່?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ເອັບພິໂສດທີ່ບັນທຶກໄວ້ແລ້ວຈະຍັງຄົງສາມາດເບິ່ງໄດ້ໃນຫ້ອງສະໝຸດ DVR ຢູ່."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"ຢຸດ"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ຍັງບໍ່ມີເອບພິໂສດທີ່ສາມາດເບິ່ງໄດ້ເທື່ອ.\nພວກມັນຈະຖືກບັນທຶອຶກເມື່ອມີການສາຍ."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d ນາທີ)</item>
- <item quantity="one">(%1$d ນາທີ) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"ມື້ນີ້"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"ມື້ອື່ນ"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"ມື້ວານນີ້"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ມື້ນີ້"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ມື້ອື່ນ"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"ຄະແນນ"</string>
-</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 88afdec0..357b8030 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"monofon."</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereof."</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Leidimo valdikliai"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Naujausi kanal."</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanalai"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV parinktys"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP parinktys"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Leidimo valdikliai negalimi šiame kanale"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Leisti arba pristabdyti"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Sukti pirmyn"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Subtitrai"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Rodymo režimas"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Įjungta"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Išjungta"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Keli garso įr."</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Gauti daug. kan."</string>
<string name="options_item_settings" msgid="7623205838542400074">"Nustatymai"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Šaltinis"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Sukeisti"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Įjungta"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Išjungta"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Garsas"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Pagrindinis"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP langas"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Išdėstymas"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Apač. dešinėje"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Virš. dešinėje"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Viršuje kairėje"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Apač. kairėje"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Šalia"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Dydis"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Didelis"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Mažas"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Įvesties šaltinis"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena / kabelis)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Nėra informacijos apie programą"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Informacijos nėra."</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Užblokuotas kanalas"</string>
- <string name="default_language" msgid="4122326459624337928">"Nežinoma kalba"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Nežinoma kalba"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Subtitrai %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Subtitrai"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Išjungti"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Tinkinti formatavimą"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Grupuoti pagal"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ši programa yra užblokuota"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ši programa neįvertinta"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Ši programa įvertinta kaip <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Įvestis nepalaiko automatinio nuskaitymo"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Nepavyko paleisti „<xliff:g id="TV_INPUT">%s</xliff:g>“ automatinio nuskaitymo"</string>
@@ -94,7 +76,6 @@
<item quantity="other">Pridėta %1$d kanalų</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Nėra pridėtų kanalų"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Radijo imtuvas"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Tėvų kontrolė"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Įjungti"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Išjungti"</string>
@@ -110,6 +91,8 @@
<string name="other_countries" msgid="8342216398676184749">"Kitos šalys"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Nėra"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Nėra"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Neįvertinta"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blokuoti neįvert. programas"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Nėra"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Dideli apribojimai"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Vid. apribojimai"</string>
@@ -126,6 +109,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Įveskite PIN kodą, kad galėt. žiūrėti šį kanalą"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Įveskite PIN kodą, kad galėt. žiūrėti šią programą"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Ši programa įvertinta <xliff:g id="RATING">%1$s</xliff:g>. Įveskite PIN kodą, kad galėtumėte žiūrėti šią programą"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Ši programa neįvertinta. Įveskite PIN kodą, kad galėtumėte žiūrėti šią programą"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Įveskite PIN kodą"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Jei norite nustatyti tėvų valdiklius, sukurkite PIN kodą"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Įveskite naują PIN"</string>
@@ -139,22 +123,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Tas PIN kodas buvo netinkamas. Bandykite dar kartą."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Bandykite dar kartą, PIN kodas neatitinka"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Įveskite pašto kodą."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Tiesioginių kanalų programa naudos pašto kodą, kad galėtų pateikti išsamų TV kanalų programų vadovą."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Įveskite pašto kodą"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Netinkamas pašto kodas"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Nustatymai"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Tinkinti kanalų sąrašą"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Pasirinkite programų vadovo kanalus"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanalų šaltiniai"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Galimi nauji kanalai"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Tėvų kontrolė"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Laiko poslinkis"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Įrašykite žiūrėdami, kad galėtumėte pristabdyti ar atgal atsukti tiesiogines programas.\nĮspėjimas: tai darant vidinės atminties veikimo laiką dėl intensyvaus jos naudojimo."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Atvirojo šaltinio licencijos"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Atvirojo šaltinio licencijos"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Siųsti atsiliepimą"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versija"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Jei norite žiūrėti šį kanalą, paspauskite „Tinkamas“ ir įveskite PIN kodą"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Jei norite žiūrėti šią programą, paspauskite „Tinkama“ ir įveskite PIN kodą"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Ši programa neįvertinta.\nJei norite žiūrėti šią programą, paspauskite „Tinkama“ ir įveskite PIN kodą"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Ši programa įvertinta kaip <xliff:g id="RATING">%1$s</xliff:g>.\nJei norite žiūrėti šią programą, paspauskite „Tinkama“ ir įveskite PIN kodą"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Jei norite žiūrėti šį kanalą, naudokite numatytąją tiesioginės TV programą."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Jei norite žiūrėti šią programą, naudokite numatytąją tiesioginės TV programą."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Ši programa neįvertinta.\nJei norite žiūrėti šią programą, naudokite numatytąją tiesioginės TV programą."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Ši programa įvertinta <xliff:g id="RATING">%1$s</xliff:g>.\nJei norite žiūrėti šią programą, naudokite numatytąją tiesioginės TV programą."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programa užblokuota"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ši programa neįvertinta"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Ši programa įvertinta kaip <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Tik garso įrašas"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Silpnas signalas"</string>
@@ -189,8 +182,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Paspauskite PASIRINKTI,"</b>" kad pasiektumėte TV meniu."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Nerasta jokių TV įvesčių"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Nepavyksta rasti TV įvesties"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP nepalaikoma"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Nėra galimos įvesties, kurią galima rodyti kartu su PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Netinkamas derintuvo tipas. Paleiskite derintuvo tipo TV įvestį, skirtą programai „Live TV“."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Derinimas nepavyko"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Nerasta jokių programų šiam veiksmui apdoroti."</string>
@@ -244,6 +235,8 @@
<item quantity="many">%1$d suplanuoto įrašo</item>
<item quantity="other">%1$d suplanuotų įrašų</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Atšaukti įrašymą"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Sustabdyti įrašymą"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Žiūrėti"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Leisti nuo pradžios"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Tęsti ir leisti"</string>
@@ -278,9 +271,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Kai vienu metu bus per daug įrašomų programų, bus įrašomos tik aukštesnio prioriteto programos."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Išsaugoti"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Vienkartinis įrašymo veiksmas turi didžiausią prioritetą"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Atšaukti"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Atšaukti"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Pamiršti"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Sustabdyti"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Žr. įrašymo tvarkaraštį"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Ši viena programa"</string>
@@ -290,25 +280,29 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Vietoj tos įrašyti šią"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Atšaukti šį įrašymą"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Žiūrėti dabar"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Ištrinti įrašus…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Galima įrašyti"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Įrašymas suplanuotas"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Įrašo nesuderinamumas"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Įrašoma"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Įrašyti nepavyko"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Nuskaitomos programos, kad būtų sukurti įrašymo tvarkaraščiai"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Nuskaitomos programos"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Nuskaitomos programos"</string>
+ <!-- no translation found for dvr_error_insufficient_space_action_view_recent_recordings (137918938589787623) -->
<skip />
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"„<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ įrašymo procesas nebaigtas."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"„<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>“ ir „<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>“ įrašymo procesas nebaigtas."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"„<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>“, „<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>“ ir „<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>“ įrašymo procesas nebaigtas."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"„<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ įrašymo procesas nebaigtas, nes nepakanka saugyklos vietos."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"„<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>“ ir „<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>“ įrašymo procesas nebaigtas, nes nepakanka saugyklos vietos."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"„<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>“, „<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>“ ir „<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>“ įrašymo procesas nebaigtas, nes nepakanka saugyklos vietos."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Norint naudoti DVR reikia daugiau saugyklos vietos"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Naudodami DVR galėsite įrašyti programas. Tačiau dabar įrenginyje nepakanka saugyklos vietos, kad DVR veiktų. Prijunkite išorinį diską, kuris yra <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB arba didesnis, ir atlikite veiksmus, kad formatuotumėte jį kaip įrenginio saugyklą."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Naudodami DVR galėsite įrašyti programas. Tačiau dabar įrenginyje nepakanka saugyklos vietos, kad DVR veiktų. Prijunkite išorinį diską, kuris yra <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB arba didesnis, ir atlikite veiksmus, kad formatuotumėte jį kaip įrenginio saugyklą."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Trūksta saugyklos vietos"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Ši programa nebus įrašyta, nes nepakanka saugyklos vietos. Pabandykite ištrinti kai kuriuos esamus įrašus."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Nėra saugyklos"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Nėra kai kurių saugyklų, kurias naudoja DVR. Prijunkite anksčiau naudotą išorinį diską, kad iš naujo įgalintumėte DVR. Taip pat galite pasirinkti pamiršti saugyklą, jei ji nebepasiekiama."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Pamiršti saugyklą?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Visas įrašytas turinys ir tvarkaraščiai bus prarasti."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Sustabdyti įrašymą?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Įrašytas turinys bus išsaugotas."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"„<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ įrašas bus sustabdytas dėl prieštaravimų su šia programa. Įrašytas turinys bus išsaugotas."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Įrašymas suplanuotas, bet yra neatitikimų"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Įrašymo procesas pradėtas, bet yra neatitikimų"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Programa „<xliff:g id="PROGRAMNAME">%1$s</xliff:g>“ bus įrašyta."</string>
@@ -328,17 +322,39 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Ta pati programa jau suplanuota įrašyti <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Jau įrašyta"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Ši programa jau buvo įrašyta. Ji pasiekiama DVR bibliotekoje."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Suplanuotas serijos įrašas"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one">Suplanuotas <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašas.</item>
+ <item quantity="few">Suplanuoti <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašai.</item>
+ <item quantity="many">Suplanuota <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašo.</item>
+ <item quantity="other">Suplanuota <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašų.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one">Suplanuotas <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašas. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> iš jų nebus įraš. dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="few">Suplanuoti <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašai. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> iš jų nebus įraš. dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="many">Suplanuota <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašo. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> iš jų nebus įraš. dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="other">Suplanuota <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašų. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> iš jų nebus įraš. dėl nesuderinamo tvarkaraščio.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one">Suplanuotas <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> „<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“ įrašas. Šio ir kitų serialų serijos (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) nebus įrašytos dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="few">Suplanuoti <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> „<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“ įrašai. Šio ir kitų serialų serijos (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) nebus įrašytos dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="many">Suplanuota <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> „<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“ įrašo. Šio ir kitų serialų serijos (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) nebus įrašytos dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="other">Suplanuota <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> „<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“ įrašų. Šio ir kitų serialų serijos (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) nebus įrašytos dėl nesuderinamo tvarkaraščio.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one">Suplanuotas <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašas. 1 kitų serialų serija nebus įrašyta dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="few">Suplanuoti <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašai. 1 kitų serialų serija nebus įrašyta dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="many">Suplanuota <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašo. 1 kitų serialų serija nebus įrašyta dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="other">Suplanuota <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> „<xliff:g id="SERIESNAME_3">%2$s</xliff:g>“ įrašų. 1 kitų serialų serija nebus įrašyta dėl nesuderinamo tvarkaraščio.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one">Suplanuotas <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> „<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“ įrašas. Kitų serialų serijos (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) nebus įrašytos dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="few">Suplanuoti <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> „<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“ įrašai. Kitų serialų serijos (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) nebus įrašytos dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="many">Suplanuota <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> „<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“ įrašo. Kitų serialų serijos (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) nebus įrašytos dėl nesuderinamo tvarkaraščio.</item>
+ <item quantity="other">Suplanuota <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> „<xliff:g id="SERIESNAME_4">%2$s</xliff:g>“ įrašų. Kitų serialų serijos (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) nebus įrašytos dėl nesuderinamo tvarkaraščio.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Įrašyta programa nerasta."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Susiję įrašai"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Nėra laidos aprašo)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d įrašas</item>
<item quantity="few">%1$d įrašai</item>
@@ -362,6 +378,8 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Sustabdyti serijos įrašymą?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Įrašytos serijos bus pasiekiamos DVR bibliotekoje."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Sustabdyti"</string>
+ <!-- no translation found for dvr_series_schedules_stopped_empty_state (1464244804664395151) -->
+ <skip />
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Nėra jokių serijų.\nSerijos bus įrašytos, kai jų bus."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d minutė)</item>
@@ -375,4 +393,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> šiandien"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> rytoj"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Įvertinimas"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Įrašytos programos"</string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 00021bca..3aa06a61 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Atskaņošanas vadīklas"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Nesenie kanāli"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanāli"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV iespējas"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP opcijas"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Šim kanālam nav pieejamas atskaņošanas vadīklas."</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Atskaņot vai pauzēt"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Pārtīt uz priekšu"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Slēgtie paraksti"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Attēla režīms"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Ieslēgts"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Izslēgts"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multiaudio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Vairāk kanālu"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Iestatījumi"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Avots"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Mainīt"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Ieslēgts"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Izslēgts"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Skaņa"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Galvenais"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP logs"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Izkārtojums"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Apakšā pa labi"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Augšā pa labi"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Augšā pa kreisi"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Apakšā pa kreisi"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Līdzās"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Izmēri"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Liels"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Mazs"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Ievades avots"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/kabelis)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Nav informācijas par programmu"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Nav informācijas"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Bloķēts kanāls"</string>
- <string name="default_language" msgid="4122326459624337928">"Nezināma valoda"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Nezināma valoda"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Slēgtie paraksti %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Slēgtie paraksti"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Izslēgti"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Pielāgot formatēšanu"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Grupēt pēc:"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Šī programma ir bloķēta."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Šī programma ir bez vērtējuma."</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Šī programma ir novērtēta kā “<xliff:g id="RATING">%1$s</xliff:g>”."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Ieeja neatbalsta automātisko meklēšanu."</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Nevar sākt automātisko skenēšanu ieejā “<xliff:g id="TV_INPUT">%s</xliff:g>”."</string>
@@ -93,7 +75,6 @@
<item quantity="other">Tika pievienoti %1$d kanāli.</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Kanāli netika pievienoti."</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Kanālu meklētājs"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Vecāku kontrole"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Ieslēgts"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Izslēgts"</string>
@@ -109,6 +90,8 @@
<string name="other_countries" msgid="8342216398676184749">"Citas valstis"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Nav"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Nav"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Bez vērtējuma"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Bloķēt programmas bez vērtējuma"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Nav"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Stingri ierobežojumi"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Vidēji ierobežojumi"</string>
@@ -125,6 +108,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"PIN ievade, lai skatītos šo kanālu"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"PIN ievade, lai skatītos šo programmu"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Šī programma ir novērtēta kā <xliff:g id="RATING">%1$s</xliff:g>. Lai skatītos šo programmu, ievadiet PIN kodu."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Šī programma ir bez vērtējuma. Lai skatītos šo programmu, ievadiet PIN."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"PIN ievade"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Lai iestatītu vecāku kontroli, izveidojiet PIN kodu."</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Ievadiet jauno PIN"</string>
@@ -137,22 +121,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"PIN kods nav pareizs. Mēģiniet vēlreiz."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Neatbilstošs PIN. Mēģiniet vēlreiz."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Pasta indeksa ievadīšana"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Lietotnē Live Channels pasta indekss tiks izmantots, lai nodrošinātu visu TV kanālu programmu ceļvedi."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Ievadiet pasta indeksu"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Nederīgs pasta indekss"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Iestatījumi"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Pielāgot kanālu sarakstu"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Izvēlieties kanālus programmu ceļvedim."</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanālu avoti"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Pieejami jauni kanāli"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Vecāku kontrole"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Laika nobīde"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Skatīšanās laikā ierakstiet tiešraides programmas, lai varētu tās apturēt vai attīt atpakaļ.\nBrīdinājums: tas var samazināt iekšējās atmiņas lietojumu, ja atmiņa tiek intensīvi lietota."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Atklātā pirmkoda licences"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Atklātā pirmkoda licences"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Sūtīt atsauksmes"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versija"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Lai skatītos šo kanālu, nospiediet pa labi vērsto bultiņu un ievadiet PIN kodu."</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Lai skatītos šo programmu, nospiediet pa labi vērsto bultiņu un ievadiet PIN kodu."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Šī programma ir bez vērtējuma.\nLai skatītos šo programmu, nospiediet pogu labajā pusē un ievadiet PIN."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Šī programma ir novērtēta kā “<xliff:g id="RATING">%1$s</xliff:g>”.\nLai skatītos šo programmu, nospiediet pa labi vērsto bultiņu un ievadiet PIN kodu."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Lai skatītos šo kanālu, izmantojiet noklusējuma lietotni televīzijas skatīšanai tiešraidē."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Lai skatītos šo programmu, izmantojiet noklusējuma lietotni televīzijas skatīšanai tiešraidē."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Šī programma ir bez vērtējuma.\nLai skatītos šo programmu, izmantojiet noklusējuma lietotni TV skatīšanai tiešraidē."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Šīs programma ir novērtēta kā “<xliff:g id="RATING">%1$s</xliff:g>”.\nLai skatītos šo programmu, izmantojiet noklusējuma programmu televīzijas skatīšanai tiešraidē."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programma ir bloķēta."</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Šī programma ir bez vērtējuma."</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Šī programma ir novērtēta kā “<xliff:g id="RATING">%1$s</xliff:g>”."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Tikai audio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Vājš signāls"</string>
@@ -185,8 +178,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Nospiediet ATLASĪT"</b>", lai piekļūtu TV izvēlnei."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Nav atrasta neviena TV ieeja."</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Nevar atrast TV ieeju."</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Funkcija PIP netiek atbalstīta."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Nav ievades, ko parādīt, izmantojot PIP."</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Kanālu meklētāja veids nav piemērots. Lūdzu, palaidiet lietotni “Tiešraides kanāli” kanālu meklētāja veida TV ievadei."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Kanālu meklēšana neizdevās."</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Netika atrasta neviena lietotne šīs darbības veikšanai."</string>
@@ -235,6 +226,8 @@
<item quantity="one">%1$d ieplānots ieraksts</item>
<item quantity="other">%1$d ieplānoti ieraksti</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Atcelt ierakstīšanu"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Apturēt ierakstīšanu"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Skatīties"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Atskaņot no sākuma"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Atsākt atskaņošanu"</string>
@@ -268,9 +261,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Ja vēlaties ierakstīt pārāk daudz programmu vienlaikus, tiks ierakstītas tikai programmas ar augstāku prioritāti."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Saglabāt"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Vienreizējiem ierakstiem ir visaugstākā prioritāte"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Atcelt"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Atcelt"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Aizmirst"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Apturēt"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Skatīt ierakstīšanas grafiku"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Šī viena programma"</string>
@@ -280,25 +270,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Tā vietā ierakstīt tālāk norādīto"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Atcelt šo ierakstīšanu"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Skatīties tūlīt"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Dzēst ierakstus…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Var ierakstīt"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Ierakstīšana ir ieplānota"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Ierakstīšanas konflikts"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Ierakstīšana"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Neizdevās ierakstīt"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Tiek lasītas programmas, lai izveidotu ierakstīšanas grafikus."</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Tiek lasītas programmas"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Tiek lasītas programmas"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Skatīt nesenos ierakstus"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"“<xliff:g id="PROGRAMNAME">%1$s</xliff:g>” ierakstīšana netika pabeigta."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"“<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>” un “<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>” ierakstīšana netika pabeigta."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"“<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>”, “<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>” un “<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>” ierakstīšana netika pabeigta."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"“<xliff:g id="PROGRAMNAME">%1$s</xliff:g>” ierakstīšana netika pabeigta, jo krātuvē nepietiek vietas."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"“<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>” un “<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>” ierakstīšana netika pabeigta, jo krātuvē nepietiek vietas."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"“<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>”, “<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>” un “<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>” ierakstīšana netika pabeigta, jo krātuvē nepietiek vietas."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Ciparvideo ierakstītājam nepieciešama lielāka krātuve"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Jūs varēsiet ierakstīt programmas, izmantojot ciparvideo ierakstītāju. Taču pašlaik jūsu ierīces krātuvē nav pietiekami daudz vietas, lai tas darbotos. Lūdzu, pievienojiet vismaz <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB lielu ārējo disku un izpildiet sniegtos norādījumus, lai formatētu to kā ierīces krātuvi."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Jūs varēsiet ierakstīt programmas, izmantojot ciparvideo ierakstītāju. Taču pašlaik jūsu ierīces krātuvē nav pietiekami daudz vietas, lai tas darbotos. Lūdzu, pievienojiet vismaz <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB lielu ārējo disku un izpildiet sniegtos norādījumus, lai formatētu to kā ierīces krātuvi."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Krātuvē nepietiek vietas"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Šī programma netiks ierakstīta, jo krātuvē nepietiek vietas. Izdzēsiet dažus esošos ierakstus."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Trūkst krātuves"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Trūkst ciparvideo ierakstītāja izmantotās krātuves. Lūdzu, pievienojiet ārējo disku, ko izmantojāt iepriekš ciparvideo ierakstītāja atkārtotai iespējošanai. Varat arī izvēlēties aizmirst krātuvi, ja tā vairs nav pieejama."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Vai aizmirst krātuvi?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Viss jūsu ierakstītais saturs un grafiki tiks zaudēti."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Vai apturēt ierakstīšanu?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Ierakstītais saturs tiks saglabāts."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Seriāla “<xliff:g id="PROGRAMNAME">%1$s</xliff:g>” ierakstīšana tiks apturēta, jo ir konflikts ar šo programmu. Ierakstītais saturs tiks saglabāts."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Ierakstīšana ir ieplānota, taču ir konflikti"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Ierakstīšana tika sākta, taču ir konflikti"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Programma <xliff:g id="PROGRAMNAME">%1$s</xliff:g> tiks ierakstīta."</string>
@@ -314,17 +307,34 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Šo pārraidi jau ir plānots ierakstīt plkst. <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Jau tika ierakstīta"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Šī pārraide jau ir ierakstīta. Tā ir pieejama DVR bibliotēkā."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Ir ieplānota seriāla ierakstīšana"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="zero">Seriālam <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ir ieplānoti <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ieraksti.</item>
+ <item quantity="one">Seriālam <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ir ieplānots <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ieraksts.</item>
+ <item quantity="other">Seriālam <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ir ieplānoti <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ieraksti.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="zero">Seriālam <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ir ieplānoti <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ieraksti. Konfliktu dēļ netiks ierakstīts(-i) <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> no tiem.</item>
+ <item quantity="one">Seriālam <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ir ieplānots <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ieraksts. Konfliktu dēļ netiks ierakstīts(-i) <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> no tiem.</item>
+ <item quantity="other">Seriālam <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ir ieplānoti <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ieraksti. Konfliktu dēļ netiks ierakstīts(-i) <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> no tiem.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="zero">Seriālam <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ir ieplānoti <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ieraksti. Konfliktu dēļ netiks ierakstītas <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> šī un cita(-u) seriāla(-u) sērijas.</item>
+ <item quantity="one">Seriālam <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ir ieplānots <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ieraksts. Konfliktu dēļ netiks ierakstītas <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> šī un cita(-u) seriāla(-u) sērijas.</item>
+ <item quantity="other">Seriālam <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ir ieplānoti <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ieraksti. Konfliktu dēļ netiks ierakstītas <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> šī un cita(-u) seriāla(-u) sērijas.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="zero">Seriālam <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ir ieplānoti <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ieraksti. Konfliktu dēļ netiks ierakstīta 1 cita seriāla sērija.</item>
+ <item quantity="one">Seriālam <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ir ieplānots <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ieraksts. Konfliktu dēļ netiks ierakstīta 1 cita seriāla sērija.</item>
+ <item quantity="other">Seriālam <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ir ieplānoti <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ieraksti. Konfliktu dēļ netiks ierakstīta 1 cita seriāla sērija.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="zero">Seriālam <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ir ieplānoti <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ieraksti. Konfliktu dēļ netiks ierakstītas <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> cita seriāla sērijas.</item>
+ <item quantity="one">Seriālam <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ir ieplānots <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ieraksts. Konfliktu dēļ netiks ierakstītas <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> cita seriāla sērijas.</item>
+ <item quantity="other">Seriālam <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ir ieplānoti <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ieraksti. Konfliktu dēļ netiks ierakstītas <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> cita seriāla sērijas.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Ierakstītā programma netika atrasta."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Saistītie ieraksti"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Nav programmas apraksta)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="zero">%1$d ierakstu</item>
<item quantity="one">%1$d ieraksts</item>
@@ -346,6 +356,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Vai apturēt sērijas ierakstīšanu?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Ierakstītās sērijas būs pieejamas DVR bibliotēkā."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Apturēt"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Šobrīd nav iznākusi neviena sērija."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Nav pieejama neviena sērija.\nTās tiks ierakstītas, kad būs pieejamas."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="zero">(%1$d minūtes)</item>
@@ -358,4 +369,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Plkst. <xliff:g id="TIME_RANGE">%1$s</xliff:g> šodien"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Plkst. <xliff:g id="TIME_RANGE">%1$s</xliff:g> rīt"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Rezultāts"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Ierakstītās programmas"</string>
</resources>
diff --git a/res/values-mk-v23/strings.xml b/res/values-mk-rMK-v23/strings.xml
index 4fd7f740..4fd7f740 100644
--- a/res/values-mk-v23/strings.xml
+++ b/res/values-mk-rMK-v23/strings.xml
diff --git a/res/values-mk/arrays.xml b/res/values-mk-rMK/arrays.xml
index b1ae7467..b1ae7467 100644
--- a/res/values-mk/arrays.xml
+++ b/res/values-mk-rMK/arrays.xml
diff --git a/res/values-mk/rating_system_strings.xml b/res/values-mk-rMK/rating_system_strings.xml
index da9a40b3..da9a40b3 100644
--- a/res/values-mk/rating_system_strings.xml
+++ b/res/values-mk-rMK/rating_system_strings.xml
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
new file mode 100644
index 00000000..4de54ac4
--- /dev/null
+++ b/res/values-mk-rMK/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Контроли за игри"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Канали"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"ТВ опции"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Контролите за репродуцирање се недостапни за овој канал"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Пуштање или паузирање"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Брзо премотување напред"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Премотување наназад"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Следно"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Претходно"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Програмски водич"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Достапни се нови канали"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Отвори <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Затворени титли"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Реж. на прикаж."</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"ПИП"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Мултиаудио"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Добиј уште канали"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Поставки"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ТВ (антена/кабел)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Нема информации за програмата"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Нема информации"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Блокиран канал"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Непознат јазик"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Затворени титлови %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Затворени титли"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Исклучено"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Прилаг. форматирање"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Пост. парам. за затв, титли во системот"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Реж. на прикаж."</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Мултиаудио"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"моно"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"стерео"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 опкружувачки"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 опкружувачки"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d канали"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Присп.листа канали"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Избери група"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Деселектирај група"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Групирај по"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Извор на канал"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Групирај по"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Оваа програма е блокиранa"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Програмава е неоценета"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Оваа програма е оценета <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Влезот не поддржува автоматско скенирање"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Не може да се вклучи автоскенирање на „<xliff:g id="TV_INPUT">%s</xliff:g>“"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Не можеше да ги активира претпочитањата на целиот систем за објаснувања."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d канал е додаден</item>
+ <item quantity="other">%1$d канали се додадени</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Не се додадени канали"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Родител. контрола"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Вклучено"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Исклучено"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Блокирани канали"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Блокирај ги сите"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Одблокирај ги сите"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Сокриени канали"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Прог. ограничувања"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"Измени PIN"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Систем за процена"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Проценки"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Види ги сите сист."</string>
+ <string name="other_countries" msgid="8342216398676184749">"Останати земји"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Ништо"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ништо"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Неоценето"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Блокирај неоценети програми"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Ништо"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Големи ограничување"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Средно ограничување"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Ниско ограничување"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Приспособено"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Содржина погодна за деца"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Содржина погодна за постари деца"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Содржина погодна за млади"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Рачни ограничувања"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s и под-рејтинг"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Под-рејтинг"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Внесете го вашиот PIN за да го гледате каналот"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Внесете го вашиот PIN за да ја гледате програмата"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Програмава е оценета со <xliff:g id="RATING">%1$s</xliff:g>. Внесете го PIN-кодот за да ја гледате"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Програмава е неоценета. Внесете го PIN-кодот за да ја гледате"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"Внесете го вашиот PIN"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"За да поставите родителска контрола, креирајте PIN."</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Внесете го новиот PIN"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"Потврдете го вашиот PIN"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Внесете го тековниот PIN"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">Внесовте погрешен PIN-код 5 пати.\nОбидете се повторно за <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секунда.</item>
+ <item quantity="other">Внесовте погрешен PIN-код 5 пати.\nОбидете се повторно за <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секунди.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN-кодот е погрешен. Обидете се повторно."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Обидете се повторно, PIN-кодот не се совпаѓа"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Внесете го поштенскиот број."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Апликацијата Live TV ќе го користи поштенскиот број за да обезбеди целосен програмски водич за ТВ-каналите."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Внесете го поштенскиот број"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Неважечки поштенски број"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Поставки"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Приспособи го списокот канали"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Изберете канали за програмскиот водич"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Извори на канали"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Достапни се нови канали"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Родителски надзор"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Снимање"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Снимајте додека гледате за да може да ги паузирате или да ги премотувате наназад програмите во живо.\nПредупредување: ова може да го намали траењето на внатрешната меморија поради нејзиното интензивно искористување."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Лиценци за софтвер со отворен код"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Испратете повратни информации"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Верзија"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"За да го гледате овој канал, притиснете Во ред и внесете го вашиот PIN"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"За да ја гледате оваа програма, притиснете Во ред и внесете го вашиот PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Програмава е неоценета.\nЗа да ја гледате, притиснете Во ред и внесете го PIN-кодот"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Оваа програма е оценета <xliff:g id="RATING">%1$s</xliff:g>.\nЗа да ја гледате оваа програма, притиснете Во ред и внесете го PIN-от."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"За да го гледате овој канал, користете ја стандардната апликација за телевизија во живо."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"За да ја гледате програмава, користете ја стандардната апликација за телевизија во живо."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Програмава е неоценета.\nЗа да ја гледате, користете ја стандардната апликација за телевизија во живо."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Оваа програма е оценета <xliff:g id="RATING">%1$s</xliff:g>.\nЗа да ја гледате програмава, користете ја стандардната апликација за телевизија во живо."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Програмата е блокирана"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Програмава е неоценета"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Оваа програма е оценета <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Само звук"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Слаб сигнал"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Нема интернет-врска"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="one">Каналов не може да се пушти сѐ до <xliff:g id="END_TIME_1">%1$s</xliff:g> бидејќи се снимаат други канали. \n\nДопрете “Десно“ за приспособување на распоредот на снимање.</item>
+ <item quantity="other">Каналов не може да се пушти сѐ до <xliff:g id="END_TIME_1">%1$s</xliff:g> бидејќи се снимаат други канали. \n\nДопрете “Десно“ за приспособување на распоредот на снимање.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Без наслов"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Каналот е блокиран"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Нов"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Извори"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d канал</item>
+ <item quantity="other">%1$d канали</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Нема достапни канали"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Нов"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Не е поставен"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Преземете повеќе извори"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Прелистувајте апликации што нудат канали во живо"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Достапни се нови извори на канали"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Нови извори на канали имаат понуда на канали.\nПоставете ги сега или направете го тоа подоцна во поставките за извори на канали."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Постави сега"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Во ред, разбрав"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>"Притиснете ИЗБЕРИ"</b>" за да пристапите до ТВ-менито."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"Не е пронајден ТВ-влез"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"ТВ-влезот не може да се најде"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Типот приемник не е соодветен. Стартувајте ја апликацијата Live TV за ТВ-влез од типот приемник."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Бирањето не успеа"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Не е пронајдена апликација што ќе се справи со ова дејство."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Сите изворни канали се сокриени.\nИзберете барем еден канал за да го гледате."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Видеото е неочекувано недостапно"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"Копчето НАЗАД е за поврзаниот уред. Притиснете на копчето ПОЧЕТНА СТРАНИЦА за да излезете."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"На каналите во живо им е потребна дозвола за да ги читаат ТВ-листите."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Поставете ги изворите"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"ТВ каналите во живо го комбинираат искуството на традиционалните ТВ канали со преносот на канали што го овозможуваат апликациите. \n\nЗапочнете со поставување на изворите на канали што се веќе инсталирани. Или прелистајте во Google Play Store за повеќе апликации што нудат ТВ канали во живо."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Снимки и распореди"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 минути"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 минути"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 час"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 часа"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Неодамнешни"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Закажани"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Серии"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Други"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Каналот не може да се сними."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Програмата не може да се сними."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> е закажана за снимање."</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Се снима <xliff:g id="PROGRAMNAME">%1$s</xliff:g> од сега до <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Целосен распоред"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="one">Следниот %1$d ден</item>
+ <item quantity="other">Следните %1$d дена</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="one">%1$d минута</item>
+ <item quantity="other">%1$d минути</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="one">%1$d ново снимање</item>
+ <item quantity="other">%1$d нови снимања</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="one">%1$d снимање</item>
+ <item quantity="other">%1$d снимања</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="one">%1$d закажано снимање</item>
+ <item quantity="other">%1$d закажани снимања</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Откажи го снимањето"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Сопри со снимање"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Часовник"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Репродуцирај отпочеток"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Прод. репродукција"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Избриши"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Избриши ги снимките"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Продолжи"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Сезона <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Види распоред"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Прочитајте повеќе"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Избриши ги снимките"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Изберете ги епизодите што сакате да ги избришете. Не може да се вратат откако ќе се избришат."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Нема снимки за бришење."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Изберете ги гледаните епизоди"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Изберете ги сите епизоди"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Откажи избор на сите епизоди"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"Изгледани се <xliff:g id="WATCHED">%1$d</xliff:g> од <xliff:g id="DURATION">%2$d</xliff:g> минути"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"Изгледани се <xliff:g id="WATCHED">%1$d</xliff:g> од <xliff:g id="DURATION">%2$d</xliff:g> секунди"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Никогаш не се гледани"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="one">%1$d од %2$d епизода се избришани</item>
+ <item quantity="other">%1$d од %2$d епизоди се избришани</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Приоритет"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Највисок"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Најнизок"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Бр. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Канали"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Кој било"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Изберете приоритет"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Кога има повеќе програми што треба да се снимаат во исто време, ќе се снимат само оние со повисок приоритет."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Зачувај"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Еднократните снимања имаат највисок приоритет"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Сопри"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Прикажи распоред на снимање"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Само оваа програма"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"сега - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Целата серија…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Сепак закажи"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Наместо неа, снимај ја оваа"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Откажете го снимањево"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Гледајте сега"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Избришете ги снимките…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Може да се снима"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Снимањето е закажано"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Конфликт при снимање"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Се снима"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Неуспешно снимање"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Се читаат програми"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Прегледајте ги последните снимки"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Снимањето на <xliff:g id="PROGRAMNAME">%1$s</xliff:g> е незавршено."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Снимањата на <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> и <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> се незавршени."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Снимањата на <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> и <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> се незавршени."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Снимањето на <xliff:g id="PROGRAMNAME">%1$s</xliff:g> не заврши поради недоволен простор за складирање."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Снимањата <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> и <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> не завршија поради недоволен простор за складирање."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Снимањата <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> и <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> не завршија поради недоволен простор за складирање."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Потребна е поголема меморија за DVR"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Ќе може да снимате програми со DVR. Но во моментов нема доволно простор на вашиот уред за да може DVR да функционира. Поврзете надворешна податочна едница од <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB или повеќе и следете ги чекорите за да ја форматирате како меморија на уредот."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Нема доволно меморија"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Програмава нема да се сними бидејќи нема доволно меморија. Обидете се да избришете постоечки снимки."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Недостасува простор"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Да се сопре со снимање?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Снимените содржини ќе се зачуваат."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Снимањето на <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ќе прекине поради конфликти со програмава. Снимената содржина ќе се зачува."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Снимањето е закажано, но постојат конфликти"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Снимањето започна, но постојат конфликти"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ќе се сними."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> се снима."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Некои делови од <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> нема да се снимат."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Некои делови од <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> и <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> нема да се снимат."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Некои делови од <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> и уште една закажана нема да се снимат."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="one">Некои делови од <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> и уште %4$d закажана нема да се снимат.</item>
+ <item quantity="other">Некои делови од <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> и уште %4$d закажани нема да се снимат.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Што би сакале да снимите?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Колку долго би сакале да снимате?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Веќе е закажана"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Истата програма е веќе закажана за снимање во <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Веќе е снимена"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Програмава е веќе снимена. Достапна е во DVR-збирката."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Закажано е снимање серија"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимање е закажано за <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимања се закажани за <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимање е закажано за <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> од нив нема да се снимат поради конфликти.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимања се закажани за <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> од нив нема да се снимат поради конфликти.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> снимање е закажано за <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизоди од оваа и други серии нема да се снимат поради конфликти.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> снимања се закажани за <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизоди од оваа и други серии нема да се снимат поради конфликти.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимање е закажано за <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 епизода од други серии нема да се сними поради конфликти.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимања се закажани за <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 епизода од други серии нема да се сними поради конфликти.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> снимање е закажано за <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизоди од други серии нема да се снимат поради конфликти.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> снимања се закажани за <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизоди од други серии нема да се снимат поради конфликти.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Снимената програма не е пронајдена."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Поврзани снимки"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="one">%1$d снимка</item>
+ <item quantity="other">%1$d снимки</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> е отстранета од распоредот на снимање"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Ќе се сними делумно поради конфликти со приемникот."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Нема да се сними поради конфликти со приемникот."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Сѐ уште нема закажани снимања.\nМоже да закажете снимање од програмскиот водич."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="one">%1$d конфликт на снимање</item>
+ <item quantity="other">%1$d конфликти на снимање</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Поставки за серии"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Започни со снимање серија"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Сопри го снимањето серија"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Да се сопре снимањето на серијата?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Снимените епизоди ќе останат достапни во DVR-збирката."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Сопри"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Не се емитуваат епизоди во моментов."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Не се достапни епизоди.\nЌе се снимат штом ќе бидат достапни."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="one">(%1$d минута)</item>
+ <item quantity="other">(%1$d минути)</item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Денес"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Утре"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Вчера"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> денес"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> утре"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Оценка"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Снимени програми"</string>
+</resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
deleted file mode 100644
index 566377a8..00000000
--- a/res/values-mk/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Контроли за игри"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Последни канали"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"ТВ опции"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Опции за ПИП"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Контролите за репродуцирање се недостапни за овој канал"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Пуштање или паузирање"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Брзо премотување напред"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Премотување наназад"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Следно"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Претходно"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Програмски водич"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Достапни се нови канали"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Отвори <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Затворени титли"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Реж. на прикаж."</string>
- <string name="options_item_pip" msgid="3951350386626879645">"ПИП"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Вклучено"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Исклучено"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Мултиаудио"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Добиј уште канали"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Поставки"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Извор"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Замени"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Вклучено"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Исклучено"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Звук"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Главен"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"ПИП прозорец"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Распоред"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Долу десно"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Горе десно"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Горе лево"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Долу лево"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Едно до друго"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Големина"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Голема"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Мала"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Влезен извор"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ТВ (антена/кабел)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Нема информации за програмата"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Нема информации"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Блокиран канал"</string>
- <string name="default_language" msgid="4122326459624337928">"Непознат јазик"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Затворени титли"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Исклучено"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Прилаг. форматирање"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Пост. парам. за затв, титли во системот"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Реж. на прикаж."</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Мултиаудио"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"моно"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"стерео"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 опкружувачки"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 опкружувачки"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d канали"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Присп.листа канали"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Избери група"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Деселектирај група"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Групирај по"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Извор на канал"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Групирај по"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Оваа програма е блокиранa"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Оваа програма е оценета <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Влезот не поддржува автоматско скенирање"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Не може да се вклучи автоскенирање на „<xliff:g id="TV_INPUT">%s</xliff:g>“"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Не можеше да ги активира претпочитањата на целиот систем за објаснувања."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="one">%1$d канал е додаден</item>
- <item quantity="other">%1$d канали се додадени</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Не се додадени канали"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Приемник"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Родител. контрола"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Вклучено"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Исклучено"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Блокирани канали"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Блокирај ги сите"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Одблокирај ги сите"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Сокриени канали"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Прог. ограничувања"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"Измени PIN"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Систем за процена"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Проценки"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Види ги сите сист."</string>
- <string name="other_countries" msgid="8342216398676184749">"Останати земји"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Ништо"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ништо"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Ништо"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Големи ограничување"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Средно ограничување"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Ниско ограничување"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Приспособено"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Содржина погодна за деца"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Содржина погодна за постари деца"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Содржина погодна за млади"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Рачни ограничувања"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s и под-рејтинг"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Под-рејтинг"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Внесете го вашиот PIN за да го гледате каналот"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Внесете го вашиот PIN за да ја гледате програмата"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Програмава е оценета со <xliff:g id="RATING">%1$s</xliff:g>. Внесете го PIN-кодот за да ја гледате"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"Внесете го вашиот PIN"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"За да поставите родителска контрола, креирајте PIN."</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Внесете го новиот PIN"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"Потврдете го вашиот PIN"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Внесете го тековниот PIN"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="one">Внесовте погрешен PIN-код 5 пати.\nОбидете се повторно за <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секунда.</item>
- <item quantity="other">Внесовте погрешен PIN-код 5 пати.\nОбидете се повторно за <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секунди.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN-кодот е погрешен. Обидете се повторно."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Обидете се повторно, PIN-кодот не се совпаѓа"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Поставки"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Приспособи го списокот канали"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Изберете канали за програмскиот водич"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Извори на канали"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Достапни се нови канали"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Родителски надзор"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Лиценци за софтвер со отворен код"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Лиценци за отворен код"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Верзија"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"За да го гледате овој канал, притиснете Во ред и внесете го вашиот PIN"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"За да ја гледате оваа програма, притиснете Во ред и внесете го вашиот PIN"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Оваа програма е оценета <xliff:g id="RATING">%1$s</xliff:g>.\nЗа да ја гледате оваа програма, притиснете Во ред и внесете го PIN-от."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"За да го гледате овој канал, користете ја стандардната апликација за телевизија во живо."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"За да ја гледате програмава, користете ја стандардната апликација за телевизија во живо."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Оваа програма е оценета <xliff:g id="RATING">%1$s</xliff:g>.\nЗа да ја гледате програмава, користете ја стандардната апликација за телевизија во живо."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Програмата е блокирана"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Оваа програма е оценета <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Само звук"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Слаб сигнал"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Нема интернет-врска"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="one">Каналов не може да се пушти сѐ до <xliff:g id="END_TIME_1">%1$s</xliff:g> бидејќи се снимаат други канали. \n\nДопрете “Десно“ за приспособување на распоредот на снимање.</item>
- <item quantity="other">Каналов не може да се пушти сѐ до <xliff:g id="END_TIME_1">%1$s</xliff:g> бидејќи се снимаат други канали. \n\nДопрете “Десно“ за приспособување на распоредот на снимање.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Без наслов"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Каналот е блокиран"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Нов"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Извори"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="one">%1$d канал</item>
- <item quantity="other">%1$d канали</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Нема достапни канали"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Нов"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Не е поставен"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Преземете повеќе извори"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Прелистувајте апликации што нудат канали во живо"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Достапни се нови извори на канали"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Нови извори на канали имаат понуда на канали.\nПоставете ги сега или направете го тоа подоцна во поставките за извори на канали."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Постави сега"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"Во ред, разбрав"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307"><b>"Притиснете ИЗБЕРИ"</b>" за да пристапите до ТВ-менито."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"Не е пронајден ТВ-влез"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"ТВ-влезот не може да се најде"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"ПИП не е поддржано"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Нема достапен влез што може да се прикаже со ПИП"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Типот приемник не е соодветен. Стартувајте ја апликацијата Live TV за ТВ-влез од типот приемник."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Бирањето не успеа"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Не е пронајдена апликација што ќе се справи со ова дејство."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Сите изворни канали се сокриени.\nИзберете барем еден канал за да го гледате."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Видеото е неочекувано недостапно"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"Копчето НАЗАД е за поврзаниот уред. Притиснете на копчето ПОЧЕТНА СТРАНИЦА за да излезете."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"На каналите во живо им е потребна дозвола за да ги читаат ТВ-листите."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Поставете ги изворите"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"ТВ каналите во живо го комбинираат искуството на традиционалните ТВ канали со преносот на канали што го овозможуваат апликациите. \n\nЗапочнете со поставување на изворите на канали што се веќе инсталирани. Или прелистајте во Google Play Store за повеќе апликации што нудат ТВ канали во живо."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Снимки и распореди"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 минути"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 минути"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 час"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 часа"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Неодамнешни"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Закажани"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Серии"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Други"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Каналот не може да се сними."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Програмата не може да се сними."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> е закажана за снимање."</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Се снима <xliff:g id="PROGRAMNAME">%1$s</xliff:g> од сега до <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Целосен распоред"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="one">Следниот %1$d ден</item>
- <item quantity="other">Следните %1$d дена</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="one">%1$d минута</item>
- <item quantity="other">%1$d минути</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="one">%1$d ново снимање</item>
- <item quantity="other">%1$d нови снимања</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="one">%1$d снимање</item>
- <item quantity="other">%1$d снимања</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="one">%1$d закажано снимање</item>
- <item quantity="other">%1$d закажани снимања</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Часовник"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Репродуцирај отпочеток"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Прод. репродукција"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Избриши"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Избриши ги снимките"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Продолжи"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Сезона <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Види распоред"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Прочитајте повеќе"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Избриши ги снимките"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Изберете ги епизодите што сакате да ги избришете. Не може да се вратат откако ќе се избришат."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Нема снимки за бришење."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Изберете ги гледаните епизоди"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Изберете ги сите епизоди"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Откажи избор на сите епизоди"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"Изгледани се <xliff:g id="WATCHED">%1$d</xliff:g> од <xliff:g id="DURATION">%2$d</xliff:g> минути"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"Изгледани се <xliff:g id="WATCHED">%1$d</xliff:g> од <xliff:g id="DURATION">%2$d</xliff:g> секунди"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Никогаш не се гледани"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="one">%1$d од %2$d епизода се избришани</item>
- <item quantity="other">%1$d од %2$d епизоди се избришани</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Приоритет"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Највисок"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Најнизок"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Бр. <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Канали"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Кој било"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Изберете приоритет"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Кога има повеќе програми што треба да се снимаат во исто време, ќе се снимат само оние со повисок приоритет."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Зачувај"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Еднократните снимања имаат највисок приоритет"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Откажи"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Откажи"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Заборави"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Сопри"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Прикажи распоред на снимање"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Само оваа програма"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"сега - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Целата серија…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Сепак закажи"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Наместо неа, снимај ја оваа"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Откажете го снимањево"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Гледајте сега"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Може да се снима"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Снимањето е закажано"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Конфликт при снимање"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Се снима"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Неуспешно снимање"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Се читаат програми за да се создадат распореди за снимање"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Се читаат програми"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Потребна е поголема меморија за DVR"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Ќе може да снимате програми со DVR. Но во моментов нема доволно простор на вашиот уред за да може DVR да функционира. Поврзете надворешна податочна едница од <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB или повеќе и следете ги чекорите за да ја форматирате како меморија на уредот."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Недостасува простор"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Недостасува дел од просторот што го користи DVR. Поврзете го надворешниот диск што го користевте претходно за да овозможите DVR повторно. Во спротивно, може да изберете да се заборави просторот ако веќе не е достапен."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Да се заборави просторот?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Сите ваши снимени содржини и распореди ќе се изгубат."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Да се сопре со снимање?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Снимените содржини ќе се зачуваат."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Снимањето е закажано, но постојат конфликти"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Снимањето започна, но постојат конфликти"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ќе се сними."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> се снима."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Некои делови од <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> нема да се снимат."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Некои делови од <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> и <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> нема да се снимат."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Некои делови од <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> и уште една закажана нема да се снимат."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="one">Некои делови од <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> и уште %4$d закажана нема да се снимат.</item>
- <item quantity="other">Некои делови од <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> и уште %4$d закажани нема да се снимат.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Што би сакале да снимите?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Колку долго би сакале да снимате?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Веќе е закажана"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Истата програма е веќе закажана за снимање во <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Веќе е снимена"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Програмава е веќе снимена. Достапна е во DVR-збирката."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Снимената програма не е пронајдена."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Поврзани снимки"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Нема опис на програмата)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="one">%1$d снимка</item>
- <item quantity="other">%1$d снимки</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> е отстранета од распоредот на снимање"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Ќе се сними делумно поради конфликти со приемникот."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Нема да се сними поради конфликти со приемникот."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Сѐ уште нема закажани снимања.\nМоже да закажете снимање од програмскиот водич."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="one">%1$d конфликт на снимање</item>
- <item quantity="other">%1$d конфликти на снимање</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Поставки за серии"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Започни со снимање серија"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Сопри го снимањето серија"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Да се сопре снимањето на серијата?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Снимените епизоди ќе останат достапни во DVR-збирката."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Сопри"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Не се достапни епизоди.\nЌе се снимат штом ќе бидат достапни."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="one">(%1$d минута)</item>
- <item quantity="other">(%1$d минути)</item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Денес"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Утре"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Вчера"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> денес"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> утре"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Оценка"</string>
-</resources>
diff --git a/res/values-ml-v23/strings.xml b/res/values-ml-rIN-v23/strings.xml
index 2333cc0f..2333cc0f 100644
--- a/res/values-ml-v23/strings.xml
+++ b/res/values-ml-rIN-v23/strings.xml
diff --git a/res/values-ml/arrays.xml b/res/values-ml-rIN/arrays.xml
index 383837e7..383837e7 100644
--- a/res/values-ml/arrays.xml
+++ b/res/values-ml-rIN/arrays.xml
diff --git a/res/values-ml/rating_system_strings.xml b/res/values-ml-rIN/rating_system_strings.xml
index e17f91f8..e17f91f8 100644
--- a/res/values-ml/rating_system_strings.xml
+++ b/res/values-ml-rIN/rating_system_strings.xml
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
new file mode 100644
index 00000000..77e46230
--- /dev/null
+++ b/res/values-ml-rIN/strings.xml
@@ -0,0 +1,355 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"മോണോ"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"സ്‌റ്റീരിയോ"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"പ്ലേ നിയന്ത്രണങ്ങൾ"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"ചാനലുകൾ"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"ടിവി ഓപ്‌ഷനുകൾ"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"ഈ ചാനലിന് പ്ലേ നിയന്ത്രണങ്ങൾ ലഭ്യമല്ല"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"പ്ലേ ചെയ്യുക അല്ലെങ്കിൽ താല്‍‌ക്കാലികമായി നിര്‍‌ത്തുക"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"വേഗത്തിലുള്ള കൈമാറൽ"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"റിവൈൻഡുചെയ്യുക"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"അടുത്തത്"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"മുമ്പത്തെ"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"പ്രോഗ്രാം സഹായി"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"പുതിയ ചാനലുകൾ ലഭ്യമാണ്"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> തുറക്കുക"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"അടച്ച അടിക്കുറിപ്പുകൾ"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"ഡിസ്‌പ്ലേ മോഡ്"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"മൾട്ടി ഓഡിയോ"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"കൂടുതൽ ചാനൽ സ്വീകരിക്കൂ"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"ക്രമീകരണം"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ടിവി (ആന്റിന/കേബിൾ)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"പ്രോഗ്രാം വിവരമൊന്നുമില്ല"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"വിവരമൊന്നുമില്ല"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"തടഞ്ഞ ചാനൽ"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"അറിയാത്ത ഭാഷ"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"അടച്ച അടിക്കുറിപ്പുകൾ %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"അടച്ച അടിക്കുറിപ്പുകൾ"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ഓഫ്"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"ഫോർമാറ്റുചെയ്യൽ ഇഷ്‌ടാനുസൃതമാക്കുക"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"അടച്ച അടിക്കുറിപ്പുകൾക്കുള്ള സിസ്‌റ്റം വിസ്‌തൃത മുൻഗണനകൾ സജ്ജമാക്കുക"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ഡിസ്‌പ്ലേ മോഡ്"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"മൾട്ടി ഓഡിയോ"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"മോണോ"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"സ്‌റ്റീരിയോ"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 സറൗണ്ട്"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 സറൗണ്ട്"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ചാനലുകൾ"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ചാനൽ ലിസ്റ്റ് ഇഷ്‌ടാനുസൃതമാക്കുക"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ഗ്രൂപ്പ് തിരഞ്ഞെടുക്കുക"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"ഗ്രൂപ്പ് തിരഞ്ഞെടുത്തത് മാറ്റുക"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ഗ്രൂപ്പ് അനുസരിച്ച്"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ചാനൽ ഉറവിടം"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"ഗ്രൂപ്പ് അനുസരിച്ച്"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"ഈ പ്രോഗ്രാം തടഞ്ഞിരിക്കുന്നു"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"ഈ പ്രോഗ്രാം റേറ്റുചെയ്‌തിട്ടില്ല"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"ഈ പ്രോഗ്രാമിനെ <xliff:g id="RATING">%1$s</xliff:g> എന്ന് റേറ്റുചെയ്‌തു"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"സ്വയമേവ സ്‌കാൻ ചെയ്യുന്നതിനെ ഇൻപുട്ട് പിന്തുണയ്‌ക്കുന്നില്ല"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' എന്നതിനായി യാന്ത്രിക സ്‌കാൻ ആരംഭിക്കാനായില്ല"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"അടച്ച അടിക്കുറിപ്പുകൾക്കായി സിസ്‌‌റ്റത്തിലെ മുൻഗണനകൾ ആരംഭിക്കാനാകില്ല."</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for msg_channel_added (5301526166755938705) -->
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"ചാനലുകളൊന്നും ചേർത്തിട്ടില്ല"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"രക്ഷാകർതൃ നിയന്ത്രണങ്ങൾ"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ഓൺ"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ഓഫ്"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"തടഞ്ഞ ചാനലുകൾ"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"എല്ലാം തടയുക"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"തടഞ്ഞതെല്ലാം മാറ്റുക"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"മറച്ച ചാനലുകൾ"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"പ്രോഗ്രാം നിയന്ത്രണങ്ങൾ"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"പിൻ മാറ്റുക"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"റേറ്റിംഗ് സംവിധാനങ്ങൾ"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"റേറ്റിംഗുകള്‍"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"എല്ലാ റേറ്റിംഗ് സംവിധാനങ്ങളും കാണുക"</string>
+ <string name="other_countries" msgid="8342216398676184749">"മറ്റു രാജ്യങ്ങൾ"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"ഒന്നുമില്ല"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ഒന്നുമില്ല"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"റേറ്റുചെയ്‌തിട്ടില്ല"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"റേറ്റുചെയ്യാത്ത പ്രോഗ്രാം ബ്ലോക്കുചെയ്യുക"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"ഒന്നുമില്ല"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"ഉയർന്ന നിയന്ത്രണങ്ങൾ"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"ഇടത്തരം നിയന്ത്രണങ്ങൾ"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"പരിമിതമായ നിയന്ത്രണങ്ങൾ"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"ഇഷ്‌ടാനുസൃതം"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"കുട്ടികൾക്ക് അനുയോജ്യമായ ഉള്ളടക്കം"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"മുതിർന്ന കുട്ടികൾക്ക് അനുയോജ്യമായ ഉള്ളടക്കം"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"കൗമാരക്കാർക്ക് അനുയോജ്യമായ ഉള്ളടക്കം"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"സ്വമേധയായുള്ള നിയന്ത്രണങ്ങൾ"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s എന്നതും ഉപറേറ്റിംഗുകളും"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"ഉപറേറ്റിംഗുകൾ"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ഈ ചാനൽ കാണാൻ നിങ്ങളുടെ പിൻ നൽകുക"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"ഈ പ്രോഗ്രാം കാണാൻ നിങ്ങളുടെ പിൻ നൽകുക"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ഈ പ്രോഗ്രാമിനെ <xliff:g id="RATING">%1$s</xliff:g> എന്ന് റേറ്റുചെയ്‌തു. ഈ പ്രോഗ്രാം കാണുന്നതിന് നിങ്ങളുടെ പിൻ നൽകുക."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"ഈ പ്രോഗ്രാം റേറ്റുചെയ്‌തിട്ടില്ല. ഇത് കാണാൻ നിങ്ങളുടെ പിൻ നൽകുക"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"നിങ്ങളുടെ പിൻ നൽകുക"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"രക്ഷാകർതൃ നിയന്ത്രണങ്ങൾ സജ്ജമാക്കാൻ, ഒരു പിൻ സൃഷ്‌ടിക്കുക"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"പുതിയ പിൻ നൽകുക"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"നിങ്ങളുടെ പിൻ സ്ഥിരീകരിക്കുക"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"നിങ്ങളുടെ നിലവിലെ പിൻ നൽകുക"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">നിങ്ങൾ 5 തവണ തെറ്റായ പിൻ നൽകി.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> സെക്കൻഡിൽ വീണ്ടും ശ്രമിക്കുക.</item>
+ <item quantity="one">നിങ്ങൾ 5 തവണ തെറ്റായ പിൻ നൽകി.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> സെക്കൻഡിൽ വീണ്ടും ശ്രമിക്കുക.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"നൽകിയ പിൻ തെറ്റാണ്. വീണ്ടും ശ്രമിക്കുക."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"പിൻ യോജിക്കുന്നില്ല, വീണ്ടും ശ്രമിക്കുക"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"നിങ്ങളുടെ തപാൽ കോഡ് നൽകുക."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"ടിവി ചാനലുകൾക്ക് സമ്പൂർണ്ണ പ്രോഗ്രാം ഗൈഡ് നൽകുന്നതിന് തത്സമയ ചാനലുകൾ ആപ്പ്, തപാൽ കോഡ് ഉപയോഗിക്കും."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"നിങ്ങളുടെ തപാൽ കോഡ് നൽകുക"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"തെറ്റായ തപാൽ കോഡ്"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"ക്രമീകരണം"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ചാനൽ ലിസ്റ്റ് ഇഷ്‌ടാനുസൃതമാക്കൂ"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"നിങ്ങളുടെ പ്രോഗ്രാം ഗൈഡിനായി ചാനലുകൾ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ചാനൽ ഉറവിടങ്ങൾ"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"പുതിയ ചാനലുകൾ ലഭ്യമാണ്"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"രക്ഷാകർതൃ നിയന്ത്രണങ്ങൾ"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"ടൈംഷിഫ്റ്റ്"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"കാണുന്നതിനിടയിൽ റെക്കോർഡുചെയ്യുക, അതുവഴി നിങ്ങൾക്ക് തത്സമയ പ്രോഗ്രാമുകൾ തൽക്കാലം നിർത്താനോ റീവൈൻഡുചെയ്യാനോ കഴിയും.\nമുന്നറിയിപ്പ്: ഇങ്ങനെ ചെയ്യുമ്പോൾ, ഇന്റേണൽ സ്റ്റോറേജ് അധികമായി ഉപയോഗിക്കപ്പെടുന്നതിനാൽ സ്റ്റോറേജിന്റെ ലൈഫ് കുറഞ്ഞേക്കാം."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"ഓപ്പൺ സോഴ്‌സ് ലൈസൻസ്"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"ഫീഡ്‍ബാക്ക് അയയ്ക്കുക"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"പതിപ്പ്"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"ഈ ചാനൽ കാണുന്നതിന് വലതുവശത്ത് അമർത്തിക്കൊണ്ട് നിങ്ങളുടെ പിൻ നൽകുക"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"ഈ പ്രോഗ്രാം കാണുന്നതിന് വലതുവശത്ത് അമർത്തിക്കൊണ്ട് നിങ്ങളുടെ പിൻ നൽകുക"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"ഈ പ്രോഗ്രാം റേറ്റുചെയ്‌തിട്ടില്ല.\nഇത് കാണാൻ, വലതുവശത്ത് അമർത്തിയശേഷം നിങ്ങളുടെ പിൻ നൽകുക"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"ഈ പ്രോഗ്രാമിനെ <xliff:g id="RATING">%1$s</xliff:g> എന്ന് റേറ്റുചെയ്‌തു.\nഈ പ്രോഗ്രാം കാണുന്നതിന് വലതുവശത്ത് അമർത്തിക്കൊണ്ട് നിങ്ങളുടെ പിൻ നൽകുക."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ഈ ചാനൽ കാണുന്നതിന്, സ്ഥിര \'തത്സമയ ടിവി ആപ്പ്\' ഉപയോഗിക്കുക."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ഈ പ്രോഗ്രാം കാണുന്നതിന്, സ്ഥിര \'തത്സമയ ടിവി ആപ്പ്\' ഉപയോഗിക്കുക."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"ഈ പ്രോഗ്രാം റേറ്റുചെയ്‌തിട്ടില്ല.\nഇത് കാണാൻ ഡിഫോൾട്ട് തത്സമയ ടിവി ആപ്പ് ഉപയോഗിക്കുക."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ഈ പ്രോഗ്രാമിനെ <xliff:g id="RATING">%1$s</xliff:g> എന്ന് റേറ്റുചെയ്‌തു.\nഈ പ്രോഗ്രാം കാണുന്നതിന് സ്ഥിര \'തത്സമയ ടിവി ആപ്പ്\' ഉപയോഗിക്കുക."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"പ്രോഗ്രാം തടഞ്ഞു"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"ഈ പ്രോഗ്രാം റേറ്റുചെയ്‌തിട്ടില്ല"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ഈ പ്രോഗ്രാമിനെ <xliff:g id="RATING">%1$s</xliff:g> എന്ന് റേറ്റുചെയ്‌തു"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ഓഡിയോ മാത്രം"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"സിഗ്‌നൽ ദുർബലമാണ്"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ഇന്റർനെറ്റ് കണക്ഷനില്ല"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">മറ്റ് ചാനലുകൾ റെക്കോർഡ് ചെയ്തുകൊണ്ടിരിക്കുന്നതിനാൽ <xliff:g id="END_TIME_1">%1$s</xliff:g> വരെ ഈ ചാനൽ പ്ലേ ചെയ്യാൻ കഴിയില്ല. \n\nറെക്കോർഡിംഗ് ഷെഡ്യൂൾ ക്രമപ്പെടുത്തുന്നതിന് വലത് അമർത്തുക.</item>
+ <item quantity="one">മറ്റൊരു ചാനൽ റെക്കോർഡ് ചെയ്തുകൊണ്ടിരിക്കുന്നതിനാൽ <xliff:g id="END_TIME_0">%1$s</xliff:g> വരെ ഈ ചാനൽ പ്ലേ ചെയ്യാൻ കഴിയില്ല. \n\nറെക്കോർഡിംഗ് ഷെഡ്യൂൾ ക്രമപ്പെടുത്തുന്നതിന് വലത് അമർത്തുക.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"ശീർഷകമൊന്നുമില്ല"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ചാനൽ തടഞ്ഞിരിക്കുന്നു"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"പുതിയത്"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"ഉറവിടങ്ങൾ"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d ചാനലുകൾ</item>
+ <item quantity="one">%1$d ചാനൽ</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"ചാനലുകളൊന്നും ലഭ്യമല്ല"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"പുതിയത്"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"സജ്ജീകരിച്ചിട്ടില്ല"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"കൂടുതൽ ഉറവിടങ്ങൾ സ്വീകരിക്കുക"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"തത്സമയ ചാനലുകൾ നൽകുന്ന ആപ്‌സ് ബ്രൗസുചെയ്യുക"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"ലഭ്യമായ പുതിയ ചാനൽ ഉറവിടങ്ങൾ"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"പുതിയ ചാനൽ ഉറവിടങ്ങളിൽ ആസ്വദിക്കുന്നതിന് കൂടുതൽ ചാനലുകളുണ്ട്.\nഅവയിപ്പോൾ സജ്ജീകരിക്കുകയോ ചാനൽ ഉറവിട ക്രമീകരണത്തിൽ പിന്നീട് സജ്ജീകരിക്കുകയോ ചെയ്യാം."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"ഇപ്പോൾ സജ്ജീകരിക്കുക"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"ശരി, മനസ്സിലായി"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"ടിവി മെനു ആക്‌സസ്സ് ചെയ്യാൻ "<b>"\'തിരഞ്ഞെടുക്കുക\' അമർത്തുക"</b>"."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"ടിവി ഇൻപുട്ടൊന്നും കണ്ടെത്തിയില്ല"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"ടിവി ഇൻപുട്ട് കണ്ടെത്താനാകില്ല"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ട്യൂണർ തരം അനുയോജ്യമല്ല. ട്യൂണർ തരം ടിവി ഇൻപുട്ടിനായി തത്സമയ ചാനലുകളുടെ അപ്ലിക്കേഷൻ സമാരംഭിക്കുക."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ട്യൂൺ ചെയ്യൽ പരാജയപ്പെട്ടു"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"ഈ പ്രവർത്തനം കൈകാര്യം ചെയ്യാൻ ആപ്പുകളൊന്നും കണ്ടെത്തിയില്ല."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"എല്ലാ ഉറവിട ചാനലുകളും മറച്ചിരിക്കുന്നു.\nകാണാനായി ഒരു ചാനലെങ്കിലും തിരഞ്ഞെടുക്കുക."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"അപ്രതീക്ഷിതമായി വീഡിയോ ലഭ്യമല്ല"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"കണക്‌റ്റു‌ചെയ്‌തിരിക്കുന്ന ഉപകരണത്തിനുള്ളതാണ് മടങ്ങുക എന്ന കീ. പുറത്തുകടക്കാൻ ഹോം ബട്ടൺ അമർത്തുക."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"TV ലിസ്റ്റിംഗുകൾ വായിക്കുന്നതിന് തത്സമയ ചാനലുകൾക്ക് അനുമതി ആവശ്യമാണ്."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"നിങ്ങളുടെ ഉറവിടങ്ങൾ സജ്ജമാക്കുക"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"പരമ്പരാഗത ടിവി ചാനലുകളുടെയും ആപ്‌സ് നൽകുന്ന സ്‌ട്രീമിംഗ് ചാനലുകളുടെയും അനുഭവമാണ് തത്സമയ ചാനലുകൾ ഒരുമിപ്പിക്കുന്നത്. \n\nഇതിനകം തന്നെ ഇൻസ്റ്റാൾ ചെയ്തിട്ടുള്ള ചാനൽ ഉറവിടങ്ങൾ സജ്ജമാക്കിക്കൊണ്ട് തുടങ്ങുക. അല്ലെങ്കിൽ Google Play സ്റ്റോറിൽ നിന്ന് തത്സമയ ചാനലുകൾ നൽകുന്ന കൂടുതൽ ആപ്‌സ് ബ്രൗസുചെയ്യുക."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"റെക്കോർഡിംഗുകളും ഷെഡ്യൂളുകളും"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 മിനിറ്റ്"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 മിനിറ്റ്"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 മണിക്കൂർ"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 മണിക്കൂർ"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"ഏറ്റവും പുതിയത്"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"ഷെഡ്യൂൾചെയ്‌തു"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"സീരീസ്"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"മറ്റുള്ളവ"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ചാനൽ റെക്കോർഡുചെയ്യാൻ കഴിയില്ല."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"പ്രോഗ്രാം റെക്കോർഡുചെയ്യാൻ കഴിയില്ല."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"റെക്കോർഡുചെയ്യുന്നതിന് <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ഷെഡ്യൂൾ ചെയ്തിരിക്കുന്നു"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ഇപ്പോൾ മുതൽ <xliff:g id="ENDTIME">%2$s</xliff:g> വരെ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> റെക്കോർഡുചെയ്യുന്നു"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"പൂർണ്ണമായ ഷെഡ്യൂൾ"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">അടുത്ത %1$d ദിവസം</item>
+ <item quantity="one">അടുത്ത %1$d ദിവസം</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d മിനിറ്റ്</item>
+ <item quantity="one">%1$d മിനിറ്റ്</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d പുതിയ റെക്കോർഡിംഗുകൾ</item>
+ <item quantity="one">%1$d പുതിയ റെക്കോർഡിംഗ്</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d റെക്കോർഡിംഗുകൾ</item>
+ <item quantity="one">%1$d റെക്കോർഡിംഗ്</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d റെക്കോർഡിംഗുകൾ ഷെഡ്യൂൾ ചെയ്തു</item>
+ <item quantity="one">%1$d റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്തു</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"റെക്കോർഡിംഗ് റദ്ദാക്കുക"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"റെക്കോർഡിംഗ് നിർത്തുക"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"കാ‍ണുക"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"തുടക്കം മുതൽ പ്ലേ ചെയ്യുക"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"പ്ലേ പുനരാരംഭിക്കുക"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"ഇല്ലാതാക്കുക"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"റെക്കോർഡിംഗ് ഇല്ലാതാക്കൂ"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"പുനരാരംഭിക്കുക"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"സീസൺ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"ഷെഡ്യൂൾ കാണുക"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"കൂടുതൽ വായിക്കുക"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"റെക്കോർഡിംഗ് ഇല്ലാതാക്കൂ"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"ഇല്ലാതാക്കാൻ ആഗ്രഹിക്കുന്ന എപ്പിസോഡുകൾ തിരഞ്ഞെടുക്കുക. ഇല്ലാതാക്കിക്കഴിഞ്ഞാൽ അവ വീണ്ടെടുക്കാനാവില്ല."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"ഇല്ലാതാക്കാൻ റെക്കോർഡിംഗുകൾ ഒന്നുമില്ല."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"കണ്ടവ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"എല്ലാം തിരഞ്ഞെടുക്കുക"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"എപ്പിസോഡ് തിരഞ്ഞെടുത്തത് മാറ്റൂ"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> / <xliff:g id="DURATION">%2$d</xliff:g> മിനിറ്റ് കണ്ടു"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> / <xliff:g id="DURATION">%2$d</xliff:g> സെക്കൻഡ് കണ്ടു"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"ഒരിക്കലും കണ്ടിട്ടില്ല"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%1$d / %2$d എപ്പിസോഡുകൾ ഇല്ലാതാക്കി</item>
+ <item quantity="one">%1$d / %2$d എപ്പിസോഡ് ഇല്ലാതാക്കി</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"മു‌ൻഗണന"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ഏറ്റവും ഉയർന്നത്"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ഏറ്റവും കുറഞ്ഞത്"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"നമ്പർ <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ചാനലുകൾ"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ഏതെങ്കിലും"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"മുൻഗണന തിരഞ്ഞെടുക്കുക"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"ഒരേ സമയം നിരവധി പരിപാടികൾ റെക്കോർഡുചെയ്യേണ്ടതുണ്ടെങ്കിൽ, ഉയർന്ന മുൻഗണനകളുള്ള പ്രോഗ്രാമുകൾ മാത്രം റെക്കോർഡുചെയ്യപ്പെടും."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"സംരക്ഷിക്കുക"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ഒറ്റത്തവണ റെക്കോർഡിംഗുകൾക്ക് ഏറ്റവും ഉയർന്ന മുൻഗണന"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"നിർത്തുക"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"റെക്കോർഡിംഗ് ഷെഡ്യൂൾ കാണുക"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"ഈ ഒരൊറ്റ പ്രോഗ്രാം"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ഇപ്പോൾ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"മൊത്തം സീരീസ്…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"എന്തായാലും ഷെഡ്യൂൾ ചെയ്യുക"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"പകരം, ഇത് റെക്കോർഡ് ചെയ്യുക"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ഈ റെക്കോർഡിംഗ് റദ്ദാക്കുക"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"ഇപ്പോൾ കാണുക"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"റെക്കോർഡിംഗുകൾ ഇല്ലാതാക്കുക…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"റെക്കോർഡുചെയ്യാവുന്നത്"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"റെക്കോർഡിംഗ് ഷെഡ്യൂൾചെയ്‌തു"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"റെക്കോർഡിംഗ് പൊരുത്തക്കേട്"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"റെക്കോർഡിംഗ്"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"റെക്കോർഡുചെയ്യൽ പരാജയപ്പെട്ടു"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"വായനാ പ്രോഗ്രാമുകൾ"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"സമീപകാല റെക്കോർഡിംഗുകൾ കാണുക"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> റെക്കോർഡുചെയ്യൽ പൂർണ്ണമായില്ല."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> എന്നിവയുടെ റെക്കോർഡുചെയ്യൽ പൂർണ്ണമായില്ല."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> എന്നിവയുടെ റെക്കോർഡുചെയ്യൽ പൂർണ്ണമായില്ല."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"വേണ്ടത്ര സ്റ്റോറേജ് ഇല്ലാത്തതിനാൽ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> റെക്കോർഡുചെയ്യൽ പൂർത്തിയായില്ല."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"വേണ്ടത്ര സ്റ്റോറേജ് ഇല്ലാത്തതിനാൽ <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> എന്നിവയുടെ റെക്കോർഡുചെയ്യൽ പൂർത്തിയായില്ല."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"വേണ്ടത്ര സ്റ്റോറേജ് ഇല്ലാത്തതിനാൽ <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> എന്നിവയുടെ റെക്കോർഡുചെയ്യൽ പൂർത്തിയായില്ല."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR-ന് കൂടുതൽ സ്റ്റോറേജ് ആവശ്യമാണ്"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR ഉപയോഗിച്ച് നിങ്ങൾക്ക് പ്രോഗ്രാമുകൾ റെക്കോർഡുചെയ്യാനാകും. എന്നിരുന്നാലും, DVR പ്രവർത്തിക്കുന്നതിന് നിങ്ങളുടെ ഉപകരണത്തിൽ ഇപ്പോൾ വേണ്ടത്ര സ്റ്റോറേജ് ഇല്ല. <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB-യോ കൂടുതലോ ഉള്ള ഒരു എക്സ്റ്റേണൽ ഡ്രൈവ് കണക്റ്റുചെയ്യുകയും ഉപകരണ സ്റ്റോറേജായി അത് ഫോർമാറ്റുചെയ്യുന്നതിന് നിർദ്ദേശങ്ങൾ പിന്തുടരുകയും ചെയ്യുക."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"മതിയായ സ്റ്റോറേജ് ഇല്ല"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"മതിയായ സ്റ്റോറേജ് ഇല്ലാത്തതിനാൽ ഈ പ്രോഗ്രാം റെക്കോർഡ് ചെയ്യപ്പെടില്ല. നിലവിലുള്ള റെക്കോർഡിംഗുകളിൽ ചിലത് ഇല്ലാതാക്കിക്കൊണ്ട് ശ്രമിച്ചുനോക്കുക."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"നഷ്ടമായ സ്റ്റോറേജ്"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"റെക്കോർഡിംഗ് നിർത്തണോ?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"റെക്കോർഡുചെയ്തിട്ടുള്ള ഉള്ളടക്കം സംരക്ഷിക്കപ്പെടും."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"ഈ പ്രോഗ്രാമുമായി പൊരുത്തക്കേട് ഉള്ളതിനാൽ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> എന്ന പ്രോഗ്രാമിന്റെ റെക്കോർഡിംഗ് അവസാനിപ്പിക്കും. റെക്കോർഡുചെയ്ത ഉള്ളടക്കം സംരക്ഷിക്കപ്പെടും."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്തിരിക്കുന്നു, എന്നാൽ പൊരുത്തക്കേടുകൾ ഉണ്ട്"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"റെക്കോർഡിംഗ് ആരംഭിച്ചിരിക്കുന്നു, എന്നാൽ പൊരുത്തക്കേടുകൾ ഉണ്ട്"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> റെക്കോർഡുചെയ്യപ്പെടും."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> റെക്കോർഡുചെയ്യുന്നു."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> പ്രോഗ്രാമിന്റെ ചില ഭാഗങ്ങൾ റെക്കോർഡുചെയ്യപ്പെടില്ല."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> എന്നീ പ്രോഗ്രാമുകളുടെ ചില ഭാഗങ്ങൾ റെക്കോർഡുചെയ്യപ്പെടില്ല."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> എന്നീ പ്രോഗ്രാമുകളുടെ ചില ഭാഗങ്ങളും ഒരു ഷെഡ്യൂളും റെക്കോർഡുചെയ്യപ്പെടില്ല."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> എന്നീ പ്രോഗ്രാമുകളുടെ ചില ഭാഗങ്ങളും %3$d ഷെഡ്യൂളുകളും റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> എന്നീ പ്രോഗ്രാമുകളുടെ ചില ഭാഗങ്ങളും %3$d ഷെഡ്യൂളും റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"എന്താണ് റെക്കോർഡുചെയ്യേണ്ടത്?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"എത്ര സമയം റെക്കോർഡ് ചെയ്യാനാണ് നിങ്ങൾ ആഗ്രഹിക്കുന്നത്?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ഇതിനകം തന്നെ ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"ഇതേ പ്രോഗ്രാം <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>-ന് റെക്കോർഡ് ചെയ്യുന്നതിനായി ഇതിനകം തന്നെ ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ഇതിനകം തന്നെ റെക്കോർഡ് ചെയ്തു"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ഈ പ്രോഗ്രാം ഇതിനകം തന്നെ റെക്കോർഡ് ചെയ്തിട്ടുണ്ട്. DVR ലൈഒബ്രറിയിൽ ഇത് ലഭ്യമാണ്."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"പരമ്പരയുടെ റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്‌തു"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> എന്ന പരമ്പരയുടെ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> റെക്കോർഡിംഗുകൾ ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> എന്ന പരമ്പരയുടെ <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> എന്ന പരമ്പരയുടെ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> റെക്കോർഡിംഗുകൾ ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്. പൊരുത്തക്കേടുകൾ ഉള്ളതിനാൽ അവയിലെ <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> എണ്ണം റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> എന്ന പരമ്പരയുടെ <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്. പൊരുത്തക്കേടുകൾ ഉള്ളതിനാൽ അത് റെക്കോർഡ് ചെയ്യപ്പെടില്ല.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> എന്ന പരമ്പരയുടെ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> റെക്കോർഡിംഗുകൾ ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്. പൊരുത്തക്കേടുകൾ ഉള്ളതിനാൽ ഈ പരമ്പരയുടെയും മറ്റ് പരമ്പരയുടെയും <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> എപ്പിസോഡുകൾ റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> എന്ന പരമ്പരയുടെ <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്. പൊരുത്തക്കേടുകൾ ഉള്ളതിനാൽ ഈ പരമ്പരയുടെയും മറ്റ് പരമ്പരയുടെയും <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> എപ്പിസോഡുകൾ റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> എന്ന പരമ്പരയുടെ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> റെക്കോർഡിംഗുകൾ ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്. പൊരുത്തക്കേടുകൾ ഉള്ളതിനാൽ മറ്റ് പരമ്പരയുടെ ഒരു എപ്പിസോഡ് റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> എന്ന പരമ്പരയുടെ <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്. പൊരുത്തക്കേടുകൾ ഉള്ളതിനാൽ മറ്റ് പരമ്പരയുടെ ഒരു എപ്പിസോഡ് റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> എന്ന പരമ്പരയുടെ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> റെക്കോർഡിംഗുകൾ ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്. പൊരുത്തക്കേടുകൾ ഉള്ളതിനാൽ മറ്റ് പരമ്പരകളുടെ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> എപ്പിസോഡുകൾ റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> എന്ന പരമ്പരയുടെ <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്. പൊരുത്തക്കേടുകൾ ഉള്ളതിനാൽ മറ്റ് പരമ്പരകളുടെ <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> എപ്പിസോഡുകൾ റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"റെക്കോർഡുചെയ്ത പ്രോഗ്രാം കണ്ടെത്തിയില്ല."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ബന്ധപ്പെട്ട റെക്കോർഡിംഗുകൾ"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d റെക്കോർഡിംഗുകൾ</item>
+ <item quantity="one">%1$d റെക്കോർഡിംഗ്</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"റെക്കോർഡിംഗ് ഷെഡ്യൂളിൽ നിന്ന് <xliff:g id="PROGRAMNAME">%1$s</xliff:g> നീക്കംചെയ്തു"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ട്യൂണർ പൊരുത്തക്കേടുള്ളതിനാൽ ഭാഗികമായി റെക്കോർഡ് ചെയ്യും."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ട്യൂണർ പൊരുത്തക്കേടുള്ളതിനാൽ റെക്കോർഡ് ചെയ്യില്ല."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ഷെഡ്യൂളിൽ ഇതുവരെയും റെക്കോർഡിംഗുകളൊന്നും ഇല്ല.\nപ്രോഗ്രാം ഗൈഡിൽ നിന്ന് നിങ്ങൾക്ക് റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്യാവുന്നതാണ്."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d റെക്കോർഡിംഗ് പൊരുത്തക്കേടുകൾ</item>
+ <item quantity="one">%1$d റെക്കോർഡിംഗ് പൊരുത്തക്കേട്</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"സീരീസ് ക്രമീകരണം"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"സീരീസ് റെക്കോർഡുചെയ്യുന്നത് ആരംഭിക്കുക"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"സീരീസ് റെക്കോർഡുചെയ്യുന്നത് നിർത്തുക"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"സീരീസ് റെക്കോർഡുചെയ്യുന്നത് നിർത്തണോ?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"റെക്കോർഡുചെയ്ത എപ്പിസോഡുകൾ DVR ലൈബ്രറിയിൽ ലഭ്യമാകുന്നത് തുടരും."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"നിർത്തുക"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"എപ്പിസോഡുകളൊന്നും ഇപ്പോൾ പ്രക്ഷേപണം ചെയ്യുന്നില്ല."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"എപ്പിസോഡുകളൊന്നും ലഭ്യമല്ല.\nലഭ്യമായിക്കഴിഞ്ഞാൽ അവ റെക്കോർഡ് ചെയ്യപ്പെടും."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d മിനിറ്റ്)</item>
+ <item quantity="one">(%1$d മിനിറ്റ്) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"ഇന്ന്"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"നാളെ"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"ഇന്നലെ"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ഇന്ന്"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> നാളെ"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"സ്കോർ"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"റെക്കോർഡുചെയ്ത പ്രോഗ്രാമുകൾ"</string>
+</resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
deleted file mode 100644
index e29a8755..00000000
--- a/res/values-ml/strings.xml
+++ /dev/null
@@ -1,348 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"മോണോ"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"സ്‌റ്റീരിയോ"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"പ്ലേ നിയന്ത്രണങ്ങൾ"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"ഏറ്റവും പുതിയ ചാനലുകൾ"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"ടിവി ഓപ്‌ഷനുകൾ"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP ഓ‌പ്‌ഷനുകൾ"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"ഈ ചാനലിന് പ്ലേ നിയന്ത്രണങ്ങൾ ലഭ്യമല്ല"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"പ്ലേ ചെയ്യുക അല്ലെങ്കിൽ താല്‍‌ക്കാലികമായി നിര്‍‌ത്തുക"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"വേഗത്തിലുള്ള കൈമാറൽ"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"റിവൈൻഡുചെയ്യുക"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"അടുത്തത്"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"മുമ്പത്തെ"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"പ്രോഗ്രാം സഹായി"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"പുതിയ ചാനലുകൾ ലഭ്യമാണ്"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> തുറക്കുക"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"അടച്ച അടിക്കുറിപ്പുകൾ"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"ഡിസ്‌പ്ലേ മോഡ്"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"ഓണാണ്"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"ഓഫാണ്"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"മൾട്ടി ഓഡിയോ"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"കൂടുതൽ ചാനൽ സ്വീകരിക്കൂ"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"ക്രമീകരണം"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"ഉറവിടം"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"സ്വാപ്പുചെയ്യുക"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"ഓണാണ്"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"ഓഫാണ്"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"ശബ്ദം"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"പ്രധാന വിൻഡോ"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP വിൻഡോ"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"ലേ‌ഔട്ട്"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"ചുവടെ വലതുഭാഗത്ത്"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"മുകളില്‍‌ വലതുഭാഗത്ത്"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"മുകളില്‍‌ ഇടതുഭാഗത്ത്"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"ചുവടെ ഇടതുഭാഗത്ത്"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"വശങ്ങളിലായി"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"വലുപ്പം"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"വലുത്"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"ചെറുത്"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"ഇൻപുട്ട് ഉറവിടം"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ടിവി (ആന്റിന/കേബിൾ)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"പ്രോഗ്രാം വിവരമൊന്നുമില്ല"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"വിവരമൊന്നുമില്ല"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"തടഞ്ഞ ചാനൽ"</string>
- <string name="default_language" msgid="4122326459624337928">"അറിയാത്ത ഭാഷ"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"അടച്ച അടിക്കുറിപ്പുകൾ"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ഓഫ്"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"ഫോർമാറ്റുചെയ്യൽ ഇഷ്‌ടാനുസൃതമാക്കുക"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"അടച്ച അടിക്കുറിപ്പുകൾക്കുള്ള സിസ്‌റ്റം വിസ്‌തൃത മുൻഗണനകൾ സജ്ജമാക്കുക"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ഡിസ്‌പ്ലേ മോഡ്"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"മൾട്ടി ഓഡിയോ"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"മോണോ"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"സ്‌റ്റീരിയോ"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 സറൗണ്ട്"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 സറൗണ്ട്"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ചാനലുകൾ"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ചാനൽ ലിസ്റ്റ് ഇഷ്‌ടാനുസൃതമാക്കുക"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ഗ്രൂപ്പ് തിരഞ്ഞെടുക്കുക"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"ഗ്രൂപ്പ് തിരഞ്ഞെടുത്തത് മാറ്റുക"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ഗ്രൂപ്പ് അനുസരിച്ച്"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ചാനൽ ഉറവിടം"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"ഗ്രൂപ്പ് അനുസരിച്ച്"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"ഈ പ്രോഗ്രാം തടഞ്ഞിരിക്കുന്നു"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"ഈ പ്രോഗ്രാമിനെ <xliff:g id="RATING">%1$s</xliff:g> എന്ന് റേറ്റുചെയ്‌തു"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"സ്വയമേവ സ്‌കാൻ ചെയ്യുന്നതിനെ ഇൻപുട്ട് പിന്തുണയ്‌ക്കുന്നില്ല"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' എന്നതിനായി യാന്ത്രിക സ്‌കാൻ ആരംഭിക്കാനായില്ല"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"അടച്ച അടിക്കുറിപ്പുകൾക്കായി സിസ്‌‌റ്റത്തിലെ മുൻഗണനകൾ ആരംഭിക്കാനാകില്ല."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for msg_channel_added (5301526166755938705) -->
- <string name="msg_no_channel_added" msgid="2882586037409921925">"ചാനലുകളൊന്നും ചേർത്തിട്ടില്ല"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ട്യൂണർ"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"രക്ഷാകർതൃ നിയന്ത്രണങ്ങൾ"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ഓൺ"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ഓഫ്"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"തടഞ്ഞ ചാനലുകൾ"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"എല്ലാം തടയുക"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"തടഞ്ഞതെല്ലാം മാറ്റുക"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"മറച്ച ചാനലുകൾ"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"പ്രോഗ്രാം നിയന്ത്രണങ്ങൾ"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"പിൻ മാറ്റുക"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"റേറ്റിംഗ് സംവിധാനങ്ങൾ"</string>
- <string name="option_ratings" msgid="4009116954188688616">"റേറ്റിംഗുകള്‍"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"എല്ലാ റേറ്റിംഗ് സംവിധാനങ്ങളും കാണുക"</string>
- <string name="other_countries" msgid="8342216398676184749">"മറ്റു രാജ്യങ്ങൾ"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"ഒന്നുമില്ല"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ഒന്നുമില്ല"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"ഒന്നുമില്ല"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"ഉയർന്ന നിയന്ത്രണങ്ങൾ"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"ഇടത്തരം നിയന്ത്രണങ്ങൾ"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"പരിമിതമായ നിയന്ത്രണങ്ങൾ"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"ഇഷ്‌ടാനുസൃതം"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"കുട്ടികൾക്ക് അനുയോജ്യമായ ഉള്ളടക്കം"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"മുതിർന്ന കുട്ടികൾക്ക് അനുയോജ്യമായ ഉള്ളടക്കം"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"കൗമാരക്കാർക്ക് അനുയോജ്യമായ ഉള്ളടക്കം"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"സ്വമേധയായുള്ള നിയന്ത്രണങ്ങൾ"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s എന്നതും ഉപറേറ്റിംഗുകളും"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"ഉപറേറ്റിംഗുകൾ"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ഈ ചാനൽ കാണാൻ നിങ്ങളുടെ പിൻ നൽകുക"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"ഈ പ്രോഗ്രാം കാണാൻ നിങ്ങളുടെ പിൻ നൽകുക"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ഈ പ്രോഗ്രാമിനെ <xliff:g id="RATING">%1$s</xliff:g> എന്ന് റേറ്റുചെയ്‌തു. ഈ പ്രോഗ്രാം കാണുന്നതിന് നിങ്ങളുടെ പിൻ നൽകുക."</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"നിങ്ങളുടെ പിൻ നൽകുക"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"രക്ഷാകർതൃ നിയന്ത്രണങ്ങൾ സജ്ജമാക്കാൻ, ഒരു പിൻ സൃഷ്‌ടിക്കുക"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"പുതിയ പിൻ നൽകുക"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"നിങ്ങളുടെ പിൻ സ്ഥിരീകരിക്കുക"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"നിങ്ങളുടെ നിലവിലെ പിൻ നൽകുക"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">നിങ്ങൾ 5 തവണ തെറ്റായ പിൻ നൽകി.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> സെക്കൻഡിൽ വീണ്ടും ശ്രമിക്കുക.</item>
- <item quantity="one">നിങ്ങൾ 5 തവണ തെറ്റായ പിൻ നൽകി.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> സെക്കൻഡിൽ വീണ്ടും ശ്രമിക്കുക.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"നൽകിയ പിൻ തെറ്റാണ്. വീണ്ടും ശ്രമിക്കുക."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"പിൻ യോജിക്കുന്നില്ല, വീണ്ടും ശ്രമിക്കുക"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"ക്രമീകരണം"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ചാനൽ ലിസ്റ്റ് ഇഷ്‌ടാനുസൃതമാക്കൂ"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"നിങ്ങളുടെ പ്രോഗ്രാം ഗൈഡിനായി ചാനലുകൾ തിരഞ്ഞെടുക്കുക"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ചാനൽ ഉറവിടങ്ങൾ"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"പുതിയ ചാനലുകൾ ലഭ്യമാണ്"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"രക്ഷാകർതൃ നിയന്ത്രണങ്ങൾ"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"ഓപ്പൺ സോഴ്‌സ് ലൈസൻസ്"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"ഓപ്പൺ സോഴ്‌സ് ലൈസൻസുകൾ"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"പതിപ്പ്"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"ഈ ചാനൽ കാണുന്നതിന് വലതുവശത്ത് അമർത്തിക്കൊണ്ട് നിങ്ങളുടെ പിൻ നൽകുക"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"ഈ പ്രോഗ്രാം കാണുന്നതിന് വലതുവശത്ത് അമർത്തിക്കൊണ്ട് നിങ്ങളുടെ പിൻ നൽകുക"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"ഈ പ്രോഗ്രാമിനെ <xliff:g id="RATING">%1$s</xliff:g> എന്ന് റേറ്റുചെയ്‌തു.\nഈ പ്രോഗ്രാം കാണുന്നതിന് വലതുവശത്ത് അമർത്തിക്കൊണ്ട് നിങ്ങളുടെ പിൻ നൽകുക."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ഈ ചാനൽ കാണുന്നതിന്, സ്ഥിര \'തത്സമയ ടിവി ആപ്പ്\' ഉപയോഗിക്കുക."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ഈ പ്രോഗ്രാം കാണുന്നതിന്, സ്ഥിര \'തത്സമയ ടിവി ആപ്പ്\' ഉപയോഗിക്കുക."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ഈ പ്രോഗ്രാമിനെ <xliff:g id="RATING">%1$s</xliff:g> എന്ന് റേറ്റുചെയ്‌തു.\nഈ പ്രോഗ്രാം കാണുന്നതിന് സ്ഥിര \'തത്സമയ ടിവി ആപ്പ്\' ഉപയോഗിക്കുക."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"പ്രോഗ്രാം തടഞ്ഞു"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ഈ പ്രോഗ്രാമിനെ <xliff:g id="RATING">%1$s</xliff:g> എന്ന് റേറ്റുചെയ്‌തു"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ഓഡിയോ മാത്രം"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"സിഗ്‌നൽ ദുർബലമാണ്"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ഇന്റർനെറ്റ് കണക്ഷനില്ല"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">മറ്റ് ചാനലുകൾ റെക്കോർഡ് ചെയ്തുകൊണ്ടിരിക്കുന്നതിനാൽ <xliff:g id="END_TIME_1">%1$s</xliff:g> വരെ ഈ ചാനൽ പ്ലേ ചെയ്യാൻ കഴിയില്ല. \n\nറെക്കോർഡിംഗ് ഷെഡ്യൂൾ ക്രമപ്പെടുത്തുന്നതിന് വലത് അമർത്തുക.</item>
- <item quantity="one">മറ്റൊരു ചാനൽ റെക്കോർഡ് ചെയ്തുകൊണ്ടിരിക്കുന്നതിനാൽ <xliff:g id="END_TIME_0">%1$s</xliff:g> വരെ ഈ ചാനൽ പ്ലേ ചെയ്യാൻ കഴിയില്ല. \n\nറെക്കോർഡിംഗ് ഷെഡ്യൂൾ ക്രമപ്പെടുത്തുന്നതിന് വലത് അമർത്തുക.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"ശീർഷകമൊന്നുമില്ല"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ചാനൽ തടഞ്ഞിരിക്കുന്നു"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"പുതിയത്"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"ഉറവിടങ്ങൾ"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d ചാനലുകൾ</item>
- <item quantity="one">%1$d ചാനൽ</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"ചാനലുകളൊന്നും ലഭ്യമല്ല"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"പുതിയത്"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"സജ്ജീകരിച്ചിട്ടില്ല"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"കൂടുതൽ ഉറവിടങ്ങൾ സ്വീകരിക്കുക"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"തത്സമയ ചാനലുകൾ നൽകുന്ന ആപ്‌സ് ബ്രൗസുചെയ്യുക"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"ലഭ്യമായ പുതിയ ചാനൽ ഉറവിടങ്ങൾ"</string>
- <string name="new_sources_description" msgid="749649005588426813">"പുതിയ ചാനൽ ഉറവിടങ്ങളിൽ ആസ്വദിക്കുന്നതിന് കൂടുതൽ ചാനലുകളുണ്ട്.\nഅവയിപ്പോൾ സജ്ജീകരിക്കുകയോ ചാനൽ ഉറവിട ക്രമീകരണത്തിൽ പിന്നീട് സജ്ജീകരിക്കുകയോ ചെയ്യാം."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"ഇപ്പോൾ സജ്ജീകരിക്കുക"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"ശരി, മനസ്സിലായി"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"ടിവി മെനു ആക്‌സസ്സ് ചെയ്യാൻ "<b>"\'തിരഞ്ഞെടുക്കുക\' അമർത്തുക"</b>"."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"ടിവി ഇൻപുട്ടൊന്നും കണ്ടെത്തിയില്ല"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"ടിവി ഇൻപുട്ട് കണ്ടെത്താനാകില്ല"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP പിന്തുണയ്‌ക്കുന്നില്ല"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP-യിൽ കാണിക്കാനാകുന്ന ഇൻപുട്ടൊന്നും ലഭ്യമല്ല"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ട്യൂണർ തരം അനുയോജ്യമല്ല. ട്യൂണർ തരം ടിവി ഇൻപുട്ടിനായി തത്സമയ ചാനലുകളുടെ അപ്ലിക്കേഷൻ സമാരംഭിക്കുക."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"ട്യൂൺ ചെയ്യൽ പരാജയപ്പെട്ടു"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"ഈ പ്രവർത്തനം കൈകാര്യം ചെയ്യാൻ ആപ്പുകളൊന്നും കണ്ടെത്തിയില്ല."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"എല്ലാ ഉറവിട ചാനലുകളും മറച്ചിരിക്കുന്നു.\nകാണാനായി ഒരു ചാനലെങ്കിലും തിരഞ്ഞെടുക്കുക."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"അപ്രതീക്ഷിതമായി വീഡിയോ ലഭ്യമല്ല"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"കണക്‌റ്റു‌ചെയ്‌തിരിക്കുന്ന ഉപകരണത്തിനുള്ളതാണ് മടങ്ങുക എന്ന കീ. പുറത്തുകടക്കാൻ ഹോം ബട്ടൺ അമർത്തുക."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"TV ലിസ്റ്റിംഗുകൾ വായിക്കുന്നതിന് തത്സമയ ചാനലുകൾക്ക് അനുമതി ആവശ്യമാണ്."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"നിങ്ങളുടെ ഉറവിടങ്ങൾ സജ്ജമാക്കുക"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"പരമ്പരാഗത ടിവി ചാനലുകളുടെയും ആപ്‌സ് നൽകുന്ന സ്‌ട്രീമിംഗ് ചാനലുകളുടെയും അനുഭവമാണ് തത്സമയ ചാനലുകൾ ഒരുമിപ്പിക്കുന്നത്. \n\nഇതിനകം തന്നെ ഇൻസ്റ്റാൾ ചെയ്തിട്ടുള്ള ചാനൽ ഉറവിടങ്ങൾ സജ്ജമാക്കിക്കൊണ്ട് തുടങ്ങുക. അല്ലെങ്കിൽ Google Play സ്റ്റോറിൽ നിന്ന് തത്സമയ ചാനലുകൾ നൽകുന്ന കൂടുതൽ ആപ്‌സ് ബ്രൗസുചെയ്യുക."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"റെക്കോർഡിംഗുകളും ഷെഡ്യൂളുകളും"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 മിനിറ്റ്"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 മിനിറ്റ്"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 മണിക്കൂർ"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 മണിക്കൂർ"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"ഏറ്റവും പുതിയത്"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"ഷെഡ്യൂൾചെയ്‌തു"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"സീരീസ്"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"മറ്റുള്ളവ"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ചാനൽ റെക്കോർഡുചെയ്യാൻ കഴിയില്ല."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"പ്രോഗ്രാം റെക്കോർഡുചെയ്യാൻ കഴിയില്ല."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"റെക്കോർഡുചെയ്യുന്നതിന് <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ഷെഡ്യൂൾ ചെയ്തിരിക്കുന്നു"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ഇപ്പോൾ മുതൽ <xliff:g id="ENDTIME">%2$s</xliff:g> വരെ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> റെക്കോർഡുചെയ്യുന്നു"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"പൂർണ്ണമായ ഷെഡ്യൂൾ"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">അടുത്ത %1$d ദിവസം</item>
- <item quantity="one">അടുത്ത %1$d ദിവസം</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d മിനിറ്റ്</item>
- <item quantity="one">%1$d മിനിറ്റ്</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d പുതിയ റെക്കോർഡിംഗുകൾ</item>
- <item quantity="one">%1$d പുതിയ റെക്കോർഡിംഗ്</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d റെക്കോർഡിംഗുകൾ</item>
- <item quantity="one">%1$d റെക്കോർഡിംഗ്</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d റെക്കോർഡിംഗുകൾ ഷെഡ്യൂൾ ചെയ്തു</item>
- <item quantity="one">%1$d റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്തു</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"കാ‍ണുക"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"തുടക്കം മുതൽ പ്ലേ ചെയ്യുക"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"പ്ലേ പുനരാരംഭിക്കുക"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"ഇല്ലാതാക്കുക"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"റെക്കോർഡിംഗ് ഇല്ലാതാക്കൂ"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"പുനരാരംഭിക്കുക"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"സീസൺ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"ഷെഡ്യൂൾ കാണുക"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"കൂടുതൽ വായിക്കുക"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"റെക്കോർഡിംഗ് ഇല്ലാതാക്കൂ"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"ഇല്ലാതാക്കാൻ ആഗ്രഹിക്കുന്ന എപ്പിസോഡുകൾ തിരഞ്ഞെടുക്കുക. ഇല്ലാതാക്കിക്കഴിഞ്ഞാൽ അവ വീണ്ടെടുക്കാനാവില്ല."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"ഇല്ലാതാക്കാൻ റെക്കോർഡിംഗുകൾ ഒന്നുമില്ല."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"കണ്ടവ തിരഞ്ഞെടുക്കുക"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"എല്ലാം തിരഞ്ഞെടുക്കുക"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"എപ്പിസോഡ് തിരഞ്ഞെടുത്തത് മാറ്റൂ"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> / <xliff:g id="DURATION">%2$d</xliff:g> മിനിറ്റ് കണ്ടു"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> / <xliff:g id="DURATION">%2$d</xliff:g> സെക്കൻഡ് കണ്ടു"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"ഒരിക്കലും കണ്ടിട്ടില്ല"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%1$d / %2$d എപ്പിസോഡുകൾ ഇല്ലാതാക്കി</item>
- <item quantity="one">%1$d / %2$d എപ്പിസോഡ് ഇല്ലാതാക്കി</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"മു‌ൻഗണന"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ഏറ്റവും ഉയർന്നത്"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ഏറ്റവും കുറഞ്ഞത്"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"നമ്പർ <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ചാനലുകൾ"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ഏതെങ്കിലും"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"മുൻഗണന തിരഞ്ഞെടുക്കുക"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"ഒരേ സമയം നിരവധി പരിപാടികൾ റെക്കോർഡുചെയ്യേണ്ടതുണ്ടെങ്കിൽ, ഉയർന്ന മുൻഗണനകളുള്ള പ്രോഗ്രാമുകൾ മാത്രം റെക്കോർഡുചെയ്യപ്പെടും."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"സംരക്ഷിക്കുക"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ഒറ്റത്തവണ റെക്കോർഡിംഗുകൾക്ക് ഏറ്റവും ഉയർന്ന മുൻഗണന"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"റദ്ദാക്കൂ"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"റദ്ദാക്കുക"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"മറക്കുക"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"നിർത്തുക"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"റെക്കോർഡിംഗ് ഷെഡ്യൂൾ കാണുക"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"ഈ ഒരൊറ്റ പ്രോഗ്രാം"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ഇപ്പോൾ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"മൊത്തം സീരീസ്…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"എന്തായാലും ഷെഡ്യൂൾ ചെയ്യുക"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"പകരം, ഇത് റെക്കോർഡ് ചെയ്യുക"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ഈ റെക്കോർഡിംഗ് റദ്ദാക്കുക"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"ഇപ്പോൾ കാണുക"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"റെക്കോർഡുചെയ്യാവുന്നത്"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"റെക്കോർഡിംഗ് ഷെഡ്യൂൾചെയ്‌തു"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"റെക്കോർഡിംഗ് പൊരുത്തക്കേട്"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"റെക്കോർഡിംഗ്"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"റെക്കോർഡുചെയ്യൽ പരാജയപ്പെട്ടു"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"റെക്കോർഡിംഗ് ഷെഡ്യൂളുകൾ സൃഷ്ടിക്കാൻ പ്രോഗ്രാമുകൾ വായിക്കുന്നു"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"വായനാ പ്രോഗ്രാമുകൾ"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR-ന് കൂടുതൽ സ്റ്റോറേജ് ആവശ്യമാണ്"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"DVR ഉപയോഗിച്ച് നിങ്ങൾക്ക് പ്രോഗ്രാമുകൾ റെക്കോർഡുചെയ്യാനാകും. എന്നിരുന്നാലും, DVR പ്രവർത്തിക്കുന്നതിന് നിങ്ങളുടെ ഉപകരണത്തിൽ ഇപ്പോൾ വേണ്ടത്ര സ്റ്റോറേജ് ഇല്ല. <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB-യോ കൂടുതലോ ഉള്ള ഒരു എക്സ്റ്റേണൽ ഡ്രൈവ് കണക്റ്റുചെയ്യുകയും ഉപകരണ സ്റ്റോറേജായി അത് ഫോർമാറ്റുചെയ്യുന്നതിന് നിർദ്ദേശങ്ങൾ പിന്തുടരുകയും ചെയ്യുക."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"നഷ്ടമായ സ്റ്റോറേജ്"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR ഉപയോഗിക്കുന്ന സ്റ്റോറേജിന്റെ ചിലത് നഷ്ടമായിരിക്കുന്നു. വീണ്ടും DVR പ്രവർത്തനക്ഷമമാക്കുന്നതിന്, നിങ്ങൾ മുമ്പ് ഉപയോഗിച്ച എക്സ്റ്റേണൽ ഡ്രൈവ് കണക്റ്റുചെയ്യുക. സ്റ്റോറേജ് തുടർന്നങ്ങോട്ട് ലഭ്യമല്ലെങ്കിൽ, ഇതരമാർഗ്ഗമെന്ന നിലയിൽ, നിങ്ങൾക്ക് മറക്കുന്നതിന് തിരഞ്ഞെടുക്കാവുന്നതാണ്."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"സ്റ്റോറേജ് മറക്കണോ?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"നിങ്ങളുടെ റെക്കോർഡ് ചെയ്തിട്ടുള്ള എല്ലാ ഉള്ളടക്കവും ഷെഡ്യൂളുകളും നഷ്ടപ്പെടും."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"റെക്കോർഡിംഗ് നിർത്തണോ?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"റെക്കോർഡുചെയ്തിട്ടുള്ള ഉള്ളടക്കം സംരക്ഷിക്കപ്പെടും."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്തിരിക്കുന്നു, എന്നാൽ പൊരുത്തക്കേടുകൾ ഉണ്ട്"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"റെക്കോർഡിംഗ് ആരംഭിച്ചിരിക്കുന്നു, എന്നാൽ പൊരുത്തക്കേടുകൾ ഉണ്ട്"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> റെക്കോർഡുചെയ്യപ്പെടും."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> റെക്കോർഡുചെയ്യുന്നു."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> പ്രോഗ്രാമിന്റെ ചില ഭാഗങ്ങൾ റെക്കോർഡുചെയ്യപ്പെടില്ല."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> എന്നീ പ്രോഗ്രാമുകളുടെ ചില ഭാഗങ്ങൾ റെക്കോർഡുചെയ്യപ്പെടില്ല."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> എന്നീ പ്രോഗ്രാമുകളുടെ ചില ഭാഗങ്ങളും ഒരു ഷെഡ്യൂളും റെക്കോർഡുചെയ്യപ്പെടില്ല."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> എന്നീ പ്രോഗ്രാമുകളുടെ ചില ഭാഗങ്ങളും %3$d ഷെഡ്യൂളുകളും റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> എന്നീ പ്രോഗ്രാമുകളുടെ ചില ഭാഗങ്ങളും %3$d ഷെഡ്യൂളും റെക്കോർഡുചെയ്യപ്പെടില്ല.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"എന്താണ് റെക്കോർഡുചെയ്യേണ്ടത്?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"എത്ര സമയം റെക്കോർഡ് ചെയ്യാനാണ് നിങ്ങൾ ആഗ്രഹിക്കുന്നത്?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ഇതിനകം തന്നെ ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"ഇതേ പ്രോഗ്രാം <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>-ന് റെക്കോർഡ് ചെയ്യുന്നതിനായി ഇതിനകം തന്നെ ഷെഡ്യൂൾ ചെയ്തിട്ടുണ്ട്."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ഇതിനകം തന്നെ റെക്കോർഡ് ചെയ്തു"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ഈ പ്രോഗ്രാം ഇതിനകം തന്നെ റെക്കോർഡ് ചെയ്തിട്ടുണ്ട്. DVR ലൈഒബ്രറിയിൽ ഇത് ലഭ്യമാണ്."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"റെക്കോർഡുചെയ്ത പ്രോഗ്രാം കണ്ടെത്തിയില്ല."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ബന്ധപ്പെട്ട റെക്കോർഡിംഗുകൾ"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(പ്രോഗ്രാം വിവരണമില്ല)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d റെക്കോർഡിംഗുകൾ</item>
- <item quantity="one">%1$d റെക്കോർഡിംഗ്</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"റെക്കോർഡിംഗ് ഷെഡ്യൂളിൽ നിന്ന് <xliff:g id="PROGRAMNAME">%1$s</xliff:g> നീക്കംചെയ്തു"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ട്യൂണർ പൊരുത്തക്കേടുള്ളതിനാൽ ഭാഗികമായി റെക്കോർഡ് ചെയ്യും."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ട്യൂണർ പൊരുത്തക്കേടുള്ളതിനാൽ റെക്കോർഡ് ചെയ്യില്ല."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ഷെഡ്യൂളിൽ ഇതുവരെയും റെക്കോർഡിംഗുകളൊന്നും ഇല്ല.\nപ്രോഗ്രാം ഗൈഡിൽ നിന്ന് നിങ്ങൾക്ക് റെക്കോർഡിംഗ് ഷെഡ്യൂൾ ചെയ്യാവുന്നതാണ്."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d റെക്കോർഡിംഗ് പൊരുത്തക്കേടുകൾ</item>
- <item quantity="one">%1$d റെക്കോർഡിംഗ് പൊരുത്തക്കേട്</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"സീരീസ് ക്രമീകരണം"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"സീരീസ് റെക്കോർഡുചെയ്യുന്നത് ആരംഭിക്കുക"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"സീരീസ് റെക്കോർഡുചെയ്യുന്നത് നിർത്തുക"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"സീരീസ് റെക്കോർഡുചെയ്യുന്നത് നിർത്തണോ?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"റെക്കോർഡുചെയ്ത എപ്പിസോഡുകൾ DVR ലൈബ്രറിയിൽ ലഭ്യമാകുന്നത് തുടരും."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"നിർത്തുക"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"എപ്പിസോഡുകളൊന്നും ലഭ്യമല്ല.\nലഭ്യമായിക്കഴിഞ്ഞാൽ അവ റെക്കോർഡ് ചെയ്യപ്പെടും."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d മിനിറ്റ്)</item>
- <item quantity="one">(%1$d മിനിറ്റ്) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"ഇന്ന്"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"നാളെ"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"ഇന്നലെ"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ഇന്ന്"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> നാളെ"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"സ്കോർ"</string>
-</resources>
diff --git a/res/values-mn-v23/strings.xml b/res/values-mn-rMN-v23/strings.xml
index 7da24abf..7da24abf 100644
--- a/res/values-mn-v23/strings.xml
+++ b/res/values-mn-rMN-v23/strings.xml
diff --git a/res/values-mn/arrays.xml b/res/values-mn-rMN/arrays.xml
index 3d0b16ba..3d0b16ba 100644
--- a/res/values-mn/arrays.xml
+++ b/res/values-mn-rMN/arrays.xml
diff --git a/res/values-mn/rating_system_strings.xml b/res/values-mn-rMN/rating_system_strings.xml
index 7c883a13..7c883a13 100644
--- a/res/values-mn/rating_system_strings.xml
+++ b/res/values-mn-rMN/rating_system_strings.xml
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
new file mode 100644
index 00000000..3416ea89
--- /dev/null
+++ b/res/values-mn-rMN/strings.xml
@@ -0,0 +1,355 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Play хяналт"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Сувгууд"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"ТВ-н сонголтууд"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Энэ сувагт тоглуулах хяналтыг ашиглах боломжгүй байна"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Тоглуулах эсвэл түр зогсоох"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Хурдан урагшлуулах"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Хураах"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Дараах"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Өмнөх"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Хөтөлбөр"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Шинэ суваг нээлттэй байна"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нээх"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Хаалттай капшн"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Дэлгэцийн горим"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Мульти-аудио"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Нэмж суваг авах"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Тохиргоо"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TВ (Антен /Кабел)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Хөтөлбөрийн мэдээлэл байхгүй"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Мэдээлэл байхгүй"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Хаагдсан суваг"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Үл мэдэгдэх хэл"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Хаалттай тайлбар %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Хаалттай тайлбар"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Идэвхгүй"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Форматыг тааруулах"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Системийн хэмжээнд тохируулга хийх"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Дэлгэцийн горим"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Мульти-аудио"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"моно"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"стерео"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 surround"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 Surround"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d суваг"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Сувгийг тохируулах"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Бүлэг сонгох"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Бүлгийн сонголтыг цуцлах"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Бүлэглэх"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Сувгийн эх сурвалж"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Бүлэглэх"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Энэ програмыг блоклосон байна."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Энэ хөтөлбөр үнэлгээгүй байна"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Энэ хөтөлбөрийг <xliff:g id="RATING">%1$s</xliff:g>-ээр үнэлэгдсэн байна"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Оролт нь автомат хайлтыг дэмждэггүй"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\'-н автомат хайлтыг эхлүүлэх боломжгүй"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Текстийн системийн түвшний тохируулгыг эхлүүлэх боломжгүй."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d суваг нэмсэн</item>
+ <item quantity="one">%1$d суваг нэмсэн</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Суваг нэмэгдээгүй"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Эцэг эхийн хяналт"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Идэвхтэй"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Идэвхгүй"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Суваг хориглогдсон"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Бүгдийг хориглох"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Бүх хоригийг авах"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Нууцалсан сувгууд"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Хөтөлбөрийн хязгаар"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN өөрчлөх"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Үнэлгээний систем"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Үнэлгээ"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Үнэлгээний систем"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Бусад улс орон"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Хоосон"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Хоосон"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Үнэлгээгүй"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Үнэлгээгүй хөтөлбөрийг блоклох"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Хоосон"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Хатуу хязгаарлалт"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Дунд хязгаарлалт"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Сул хязгаарлалт"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Тааруулсан"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Хүүхдэд зориулсан тохиромжтой контент"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Том хүүхдэд тохиромжтой контент"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Өсвөр насныханд тохиромжтой контент"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Гар хязгаарлалт"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s ба дэд-үнэлгээ"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Дэд-үнэлгээ"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Энэ сувгийг үзэхийн тулд PIN оруулна уу"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Энэ хөтөлбөрийг үзэхийн тулд PIN оруулна уу"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Энэ хөтөлбөр нь <xliff:g id="RATING">%1$s</xliff:g> үнэлгээтэй байна. Энэ хөтөлбөрийг үзэхийн тулд ПИН-ээ оруулна уу."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Энэ хөтөлбөр үнэлгээгүй байна. Энэ хөтөлбөрийг үзэхийн тулд ПИН-ээ оруулна уу"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"Өөрийн PIN оруулна уу"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Эцэг эхийн хяналт тохируулахын тулд PIN үүсгээрэй"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Шинэ PIN оруулна уу"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"Өөрийн PIN-г баталгаажуулна уу"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Одоогийн PIN оруулна уу"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Та PIN-г 5 удаа буруу оруулсан байна.\n <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секундын дараа дахин оролдоно уу.</item>
+ <item quantity="one">Та PIN-г 5 удаа буруу оруулсан байна.\n <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> секундын дараа оролдоно уу.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"Энэ PIN буруу байна. Дахин оролдоно уу."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Дахин оролдоно уу, PIN таарахгүй байна"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"ЗИП кодоо оруулна уу."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"ТВ сувагт хөтөлбөрийн хуваарийг бүрнээр нь олгохын тулд Шууд сувгийн апп ЗИП код ашиглах болно."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"ЗИП кодоо оруулна уу"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"ЗИП код буруу байна"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Тохиргоо"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Сувгийн жагсаалтыг тохируулах"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ТВ хөтөлбөрт оруулах сувгуудыг сонгоно уу"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Сувгийн эх сурвалж"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Шинэ суваг боломжтой байна"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Эцэг эхийн хяналт"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Нөхөж үзэх"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Шууд хөтөлбөрийг үзэж байх үедээ бичсэнээр түр зогсоох эсвэл ухрааж үзэх боломжтой.\nСануулга: Энэ нь санг эрчимтэй ашигладаг тул дотоод сангийн багтаамжийг бууруулна."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Нээлттэй эхийн лиценз"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Санал хүсэлт илгээх"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Хувилбар"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Энэ сувгийг үзэхийн тулд Баруун товчийг дараад өөрийн PIN-г оруулна уу"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Энэ хөтөлбөрийг үзэхийн тулд Баруун товчийг дараад өөрийн PIN-г оруулна уу"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Энэ хөтөлбөр үнэлгээгүй байна.\nЭнэ хөтөлбөрийг үзэхийн тулд Баруун товчийг дараад ПИН-ээ оруулна уу."</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Энэ хөтөлбөр <xliff:g id="RATING">%1$s</xliff:g> үнэлгээтэй байна.\nэнэ хөтөлбөрийг үзэхийн тулд Баруун товчийг дараад өөрийн PIN-г оруулна уу."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Энэ сувгийг үзэхийн тулд үндсэн шууд ТВ-н апп-г ашиглаарай,"</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Энэ хөтөлбөрийг үзэхийн тулд үндсэн шууд ТВ-н апп ашиглаарай."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Энэ хөтөлбөр үнэлгээгүй байна.\nЭнэ хөтөлбөрийг үзэхийн тулд өгөгдмөл Шууд ТВ аппыг ашиглана уу."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Энэ хөтөлбөр нь <xliff:g id="RATING">%1$s</xliff:g> үнэлгээтэй.\nЭнэ хөтөлбөрийг үзэхийн тулд үндсэн шууд ТВ-н апп-г ашиглаарай."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Хөтөлбөр хориглогдсон"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Энэ хөтөлбөр үнэлгээгүй байна"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Энэ хөтөлбөрийг <xliff:g id="RATING">%1$s</xliff:g>-ээр үнэлэгдсэн байна"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Зөвхөн аудио"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Дохио муу"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Интернэт холболт байхгүй"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">Бусад сувгийг бичиж байгаа тул энэ сувгийг <xliff:g id="END_TIME_1">%1$s</xliff:g> хүртэл тоглуулах боломжгүй. \n\nБичих хуваарийг тохируулахын тулд Баруун товчлуурыг дарна уу.</item>
+ <item quantity="one">Өөр сувгийг бичиж байгаа тул энэ сувгийг <xliff:g id="END_TIME_0">%1$s</xliff:g> хүртэл тоглуулах боломжгүй. \n\nБичих хуваарийг тохируулахын тулд Баруун товчлуурыг дарна уу.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Гарчиггүй"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Сувгийг хориглосон"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Шинэ"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Эх сурвалж"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d суваг</item>
+ <item quantity="one">%1$d суваг</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Ямар ч суваг байхгүй байна"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Шинэ"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Тохируулаагүй"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Бусад сурвалж авах"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Шууд сувгийн апп хайх"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Шинэ сувгийн эх сурвалж боломжтой байна"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Шинэ сувгийн эх сурвалжууд суваг санал болгож байна.\nТа эдгээрийг эх сурвалжийн тохиргоо хэсэгт одоо эсвэл дараа нь тохируулаарай."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Одоо тохируулах"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"За, ойлголоо"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"ТВ цэс рүү хандахын тулд "<b>"СОНГОХ гэснийг дарна уу"</b></string>
+ <string name="msg_no_input" msgid="3897674146985427865">"ТВ оролт олдсонгүй."</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"ТВ оролтыг олж чадахгүй байна."</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Дуу тохируулагчийн төрөл тохирохгүй байна. Зурагтын оролтын дуу тохируулагчийн төрөлд зориулан Шууд Сувгуудын апликейшнийг эхлүүл."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Дуу тааруулж чадсангүй."</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Энэ үйлдлийг гүйцэтгэх апп олдсонгүй."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Бүх эх сурвалж сувгуудыг нууцалсан.\nҮзэхийн тулд дор хаяж нэг суваг сонгоно уу."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Энэ видеог үзэх боломжгүй болсон."</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"Буцах товчийг холбогдсон төхөөрөмжүүдэд ашиглана. Гарахын тулд Нүүр товчийг дарна уу."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Шууд сувагт TВ-н жагсаалтыг унших зөвшөөрөл шаардлагатай."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Эх сурвалжаа тохируулах"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Шууд суваг нь апп-с хангадаг TV-н уламжлалт урсгал сувгийн хэрэглээтэй хосолдог. \n\nЭхлүүлэхийн тулд өмнө нь суулгасан сувгийн эх сурвалжийг тохируулаарай. Эсвэл Google Play Store-с шууд суваг дамжуулдаг бусад апп-г хайгаарай."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Бичлэг, хуваарь"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 минут"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 минут"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 цаг"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 цаг"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Сүүлийн"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Хуваарилсан"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Цуврал"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Бусад"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Сувгийг бичих боломжгүй."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Хөтөлбөрийг бичих боломжгүй."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>-г бичихээр товлосон"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>-г одооноос <xliff:g id="ENDTIME">%2$s</xliff:g> хүртэл бичиж байна"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Бүтэн цагийн хуваарь"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">Дараагийн %1$d хоног</item>
+ <item quantity="one">Дараагийн %1$d хоног</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d минут</item>
+ <item quantity="one">%1$d минут</item>
+ </plurals>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for dvr_count_new_recordings (3569310208305402815) -->
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d бичлэг</item>
+ <item quantity="one">%1$d бичлэг</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d бичлэгийг товлосон</item>
+ <item quantity="one">%1$d бичлэгийг товлосон</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Бичлэгийг цуцлах"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Дүрс бичихийг зогсоох"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Үзэх"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Эхнээс нь тоглуулах"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Үргэлжлүүлэн тоглуулах"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Устгах"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Бичлэгийг устгах"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Үргэлжлүүлэх"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-р цуврал"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Хуваарь харах"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Дэлгэрэнгүй унших"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Бичлэгийг устгах"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Устгах ангийг сонгоно уу. Устгасан тохиолдолд дахин сэргээх боломжгүй."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Устгах ямар ч бичлэг алга."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Үзсэн ангийг сонгох"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Бүх ангийг сонгох"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Бүх ангийн сонголтыг цуцлах"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g>-с <xliff:g id="WATCHED">%1$d</xliff:g> минут үзсэн"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g>-с <xliff:g id="WATCHED">%1$d</xliff:g> секунд үзсэн"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Огт үзээгүй"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%2$d-ийн %1$d ангийг устгасан</item>
+ <item quantity="one">%2$d-ийн %1$d ангийг устгасан</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Ач холбогдол"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Хамгийн өндөр"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Хамгийн бага"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Үгүй. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Суваг"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Дурын"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Ач холбогдол сонгох"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Олон хөтөлбөрийг зэрэг бичихээр сонгосон тохиолдолд зөвхөн өндөр ач холбогдолтой хөтөлбөрийг бичнэ."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Хадгалах"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Нэг удаагийн бичлэг өндөр ач холбогдолтой"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Зогсоох"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Бичих хуваарийг харах"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Зөвхөн энэ хөтөлбөр"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"одоо - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Бүтэн цуврал..."</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Ямартай ч товлох"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Оронд нь үүнийг бичих"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Энэ бичлэгийг цуцлах"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Одоо үзэх"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Бичлэгийг устгах..."</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Дүрс бичих боломжтой"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Дүрс бичихээр товлосон"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Дүрс бичих боломжгүй"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Бичиж байна"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Бичиж чадсангүй"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Хөтөлбөрийг уншиж байна"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Сүүлийн бичлэгийг харах"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>-г бичиж чадсангүй."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>-г бичиж чадсангүй."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>-г бичиж чадсангүй."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Багтаамж хангалтгүйн улмаас <xliff:g id="PROGRAMNAME">%1$s</xliff:g>-г бичиж чадсангүй."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Багтаамж хангалтгүйн улмаас <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>-г бичиж чадсангүй."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Багтаамж хангалтгүйн улмаас <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>-г бичиж чадсангүй."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR-д илүү багтаамж шаардлагатай"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Та DVR-р хөтөлбөр бичих боломжтой болно. Гэсэн хэдий ч таны төхөөрөмжид DVR ажиллуулах хангалттай багтаамж алга. <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>гигабайт, эсвэл үүнээс дээш багтаамжтай гадаад драйв холбож, үүнийг төхөөрөмжийн сан болгож хэлбэршүүлэхийн тулд зааврыг дагана уу."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Хангалттай сан алга"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Сангийн багтаамж хангалтгүй байгаа тул энэ хөтөлбөрийг бичихгүй. Зарим шаардлагагүй бичлэгийг устгана уу."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Сан алга"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Бичлэгийг зогсоох уу?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Бичсэн агуулгыг хадгална."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>-н бичлэгийг энэ хөтөлбөртэй зөрчилдөж байгаа тул зогсоох болно. Бичсэн агуулгыг хадгална."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Бичихээр товлосон ч зөрчилтэй байна"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Бичлэг эхлүүлсэн хэдий ч зөрчилтэй байна"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>-г бичих болно."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g>-г бичиж байна."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g>-н зарим хэсгийг бичихгүй."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> болон <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>-н зарим хэсгийг бичихгүй."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> -н зарим хэсэг болон өөр нэг хуваарийг бичихгүй."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g>-н зарим хэсэг болон %3$d бусад хуваарийг бичихгүй.</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g>-н зарим хэсэг болон %3$d бусад хуваарийг бичихгүй.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Та юу бичих вэ?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Та хэр удаан бичих вэ?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Аль хэдийн товлосон"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Үүнтэй ижил хөтөлбөрийг <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>-д бичихээр товлосон байна."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Аль хэдийн бичсэн"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Энэ хөтөлбөрийг аль хэдийн бичсэн байна. Энэ нь DVR санд боломжтой."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Цувралын бичлэгийг товлосон"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g>-н <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> бичлэг товлосон.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g>-н <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> бичлэг товлосон.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g>-н <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> бичлэг товлосон. Тэдгээрийн <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>-г зөрчлийн улмаас бичихгүй.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g>-н <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> бичлэг товлосон. Үүнийг зөрчлийн улмаас бичихгүй.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g>-н <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> бичлэг товлосон. Энэ болон бусад цувралын <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ангийг зөрчлийн улмаас бичихгүй.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g>-н <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> бичлэг товлосон. Энэ болон бусад цувралын <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ангийг зөрчлийн улмаас бичихгүй.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g>-н <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> бичлэг товлосон. Бусад цувралын 1 ангийг зөрчлийн улмаас бичихгүй.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g>-н <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> бичлэг товлосон. Бусад цувралын 1 ангийг зөрчлийн улмаас бичихгүй.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g>-н <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> бичлэг товлосон. Бусад цувралын <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ангийг зөрчлийн улмаас бичихгүй.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g>-н <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> бичлэг товлосон. Бусад цувралын <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ангийг зөрчлийн улмаас бичихгүй.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Бичсэн хөтөлбөр олдсонгүй."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Холбоотой бичлэг"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d бичлэг</item>
+ <item quantity="one">%1$d бичлэг</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>-г бичих хуваариас хассан"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Тааруулагчийн алдааны улмаас хэсэгчлэн бичих болно."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Тааруулагч алдаатай тул бичихгүй."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Одоогоор хуваарьт бичлэг байхгүй байна.\nТа ТВ хөтөлбөрөөс бичлэг товлох боломжтой."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d бичлэгийн зөрчил</item>
+ <item quantity="one">%1$d бичлэгийн зөрчил</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Цувралын тохиргоо"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Цувралыг бичиж эхлэх"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Цувралыг бичихээ зогсоох"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Цувралыг бичихээ зогсоох уу?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Бичсэн цувралыг DVR санд хадгална."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Зогсоох"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Одоо ямар ч ангийг бичээгүй байна."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Ямар ч анги алга.\nТэд боломжтой болсон үедээ бичих болно."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d минут)</item>
+ <item quantity="one">(%1$d минут) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Өнөөдөр"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Маргааш"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Өчигдөр"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"өнөөдрийн <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Маргаашийн <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Оноо"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Бичигдсэн хөтөлбөр"</string>
+</resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
deleted file mode 100644
index e99f8a0e..00000000
--- a/res/values-mn/strings.xml
+++ /dev/null
@@ -1,348 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Play хяналт"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Саяхны сувгууд"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"ТВ-н сонголтууд"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP Сонголтууд"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Энэ сувагт тоглуулах хяналтыг ашиглах боломжгүй байна"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Тоглуулах эсвэл түр зогсоох"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Хурдан урагшлуулах"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Хураах"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Дараах"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Өмнөх"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Хөтөлбөр"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Шинэ суваг нээлттэй байна"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нээх"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Хаалттай капшн"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Дэлгэцийн горим"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Идэвхтэй"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Идэвхгүй"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Мульти-аудио"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Нэмж суваг авах"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Тохиргоо"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Эх сурвалж"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Солих"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Идэвхтэй"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Идэвхгүй"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Дуу"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Үндсэн"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP цонх"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Байрлал"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Баруун доод"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Баруун дээд"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Зүүн дээд"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Зүүн доод"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Зэрэгцсэн"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Хэмжээ"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Том"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Жижиг"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Оролтын эх үүсвэр"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TВ (Антен /Кабел)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Хөтөлбөрийн мэдээлэл байхгүй"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Мэдээлэл байхгүй"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Хаагдсан суваг"</string>
- <string name="default_language" msgid="4122326459624337928">"Үл мэдэгдэх хэл"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Хаалттай тайлбар"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Идэвхгүй"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Форматыг тааруулах"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Системийн хэмжээнд тохируулга хийх"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Дэлгэцийн горим"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Мульти-аудио"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"моно"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"стерео"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 surround"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 Surround"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d суваг"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Сувгийг тохируулах"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Бүлэг сонгох"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Бүлгийн сонголтыг цуцлах"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Бүлэглэх"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Сувгийн эх сурвалж"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Бүлэглэх"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Энэ програмыг блоклосон байна."</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Энэ хөтөлбөрийг <xliff:g id="RATING">%1$s</xliff:g>-ээр үнэлэгдсэн байна"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Оролт нь автомат хайлтыг дэмждэггүй"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\'-н автомат хайлтыг эхлүүлэх боломжгүй"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Текстийн системийн түвшний тохируулгыг эхлүүлэх боломжгүй."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d суваг нэмсэн</item>
- <item quantity="one">%1$d суваг нэмсэн</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Суваг нэмэгдээгүй"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Тааруулагч"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Эцэг эхийн хяналт"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Идэвхтэй"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Идэвхгүй"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Суваг хориглогдсон"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Бүгдийг хориглох"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Бүх хоригийг авах"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Нууцалсан сувгууд"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Хөтөлбөрийн хязгаар"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN өөрчлөх"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Үнэлгээний систем"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Үнэлгээ"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Үнэлгээний систем"</string>
- <string name="other_countries" msgid="8342216398676184749">"Бусад улс орон"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Хоосон"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Хоосон"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Хоосон"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Хатуу хязгаарлалт"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Дунд хязгаарлалт"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Сул хязгаарлалт"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Тааруулсан"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Хүүхдэд зориулсан тохиромжтой контент"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Том хүүхдэд тохиромжтой контент"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Өсвөр насныханд тохиромжтой контент"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Гар хязгаарлалт"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s ба дэд-үнэлгээ"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Дэд-үнэлгээ"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Энэ сувгийг үзэхийн тулд PIN оруулна уу"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Энэ хөтөлбөрийг үзэхийн тулд PIN оруулна уу"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Энэ хөтөлбөр нь <xliff:g id="RATING">%1$s</xliff:g> үнэлгээтэй байна. Энэ хөтөлбөрийг үзэхийн тулд ПИН-ээ оруулна уу."</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"Өөрийн PIN оруулна уу"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Эцэг эхийн хяналт тохируулахын тулд PIN үүсгээрэй"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Шинэ PIN оруулна уу"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"Өөрийн PIN-г баталгаажуулна уу"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Одоогийн PIN оруулна уу"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">Та PIN-г 5 удаа буруу оруулсан байна.\n <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> секундын дараа дахин оролдоно уу.</item>
- <item quantity="one">Та PIN-г 5 удаа буруу оруулсан байна.\n <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> секундын дараа оролдоно уу.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"Энэ PIN буруу байна. Дахин оролдоно уу."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Дахин оролдоно уу, PIN таарахгүй байна"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Тохиргоо"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Сувгийн жагсаалтыг тохируулах"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ТВ хөтөлбөрт оруулах сувгуудыг сонгоно уу"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Сувгийн эх сурвалж"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Шинэ суваг боломжтой байна"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Эцэг эхийн хяналт"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Нээлттэй эхийн лиценз"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Нээлттэй эхийн лиценз"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Хувилбар"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Энэ сувгийг үзэхийн тулд Баруун товчийг дараад өөрийн PIN-г оруулна уу"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Энэ хөтөлбөрийг үзэхийн тулд Баруун товчийг дараад өөрийн PIN-г оруулна уу"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Энэ хөтөлбөр <xliff:g id="RATING">%1$s</xliff:g> үнэлгээтэй байна.\nэнэ хөтөлбөрийг үзэхийн тулд Баруун товчийг дараад өөрийн PIN-г оруулна уу."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Энэ сувгийг үзэхийн тулд үндсэн шууд ТВ-н апп-г ашиглаарай,"</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Энэ хөтөлбөрийг үзэхийн тулд үндсэн шууд ТВ-н апп ашиглаарай."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Энэ хөтөлбөр нь <xliff:g id="RATING">%1$s</xliff:g> үнэлгээтэй.\nЭнэ хөтөлбөрийг үзэхийн тулд үндсэн шууд ТВ-н апп-г ашиглаарай."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Хөтөлбөр хориглогдсон"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Энэ хөтөлбөрийг <xliff:g id="RATING">%1$s</xliff:g>-ээр үнэлэгдсэн байна"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Зөвхөн аудио"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Дохио муу"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Интернэт холболт байхгүй"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Бусад сувгийг бичиж байгаа тул энэ сувгийг <xliff:g id="END_TIME_1">%1$s</xliff:g> хүртэл тоглуулах боломжгүй. \n\nБичих хуваарийг тохируулахын тулд Баруун товчлуурыг дарна уу.</item>
- <item quantity="one">Өөр сувгийг бичиж байгаа тул энэ сувгийг <xliff:g id="END_TIME_0">%1$s</xliff:g> хүртэл тоглуулах боломжгүй. \n\nБичих хуваарийг тохируулахын тулд Баруун товчлуурыг дарна уу.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Гарчиггүй"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Сувгийг хориглосон"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Шинэ"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Эх сурвалж"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d суваг</item>
- <item quantity="one">%1$d суваг</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Ямар ч суваг байхгүй байна"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Шинэ"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Тохируулаагүй"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Бусад сурвалж авах"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Шууд сувгийн апп хайх"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Шинэ сувгийн эх сурвалж боломжтой байна"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Шинэ сувгийн эх сурвалжууд суваг санал болгож байна.\nТа эдгээрийг эх сурвалжийн тохиргоо хэсэгт одоо эсвэл дараа нь тохируулаарай."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Одоо тохируулах"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"За, ойлголоо"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"ТВ цэс рүү хандахын тулд "<b>"СОНГОХ гэснийг дарна уу"</b></string>
- <string name="msg_no_input" msgid="3897674146985427865">"ТВ оролт олдсонгүй."</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"ТВ оролтыг олж чадахгүй байна."</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP дэмжигдээгүй байна."</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP-тай харуулж болох бэлэн оролт байхгүй байна."</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Дуу тохируулагчийн төрөл тохирохгүй байна. Зурагтын оролтын дуу тохируулагчийн төрөлд зориулан Шууд Сувгуудын апликейшнийг эхлүүл."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Дуу тааруулж чадсангүй."</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Энэ үйлдлийг гүйцэтгэх апп олдсонгүй."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Бүх эх сурвалж сувгуудыг нууцалсан.\nҮзэхийн тулд дор хаяж нэг суваг сонгоно уу."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Энэ видеог үзэх боломжгүй болсон."</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"Буцах товчийг холбогдсон төхөөрөмжүүдэд ашиглана. Гарахын тулд Нүүр товчийг дарна уу."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Шууд сувагт TВ-н жагсаалтыг унших зөвшөөрөл шаардлагатай."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Эх сурвалжаа тохируулах"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Шууд суваг нь апп-с хангадаг TV-н уламжлалт урсгал сувгийн хэрэглээтэй хосолдог. \n\nЭхлүүлэхийн тулд өмнө нь суулгасан сувгийн эх сурвалжийг тохируулаарай. Эсвэл Google Play Store-с шууд суваг дамжуулдаг бусад апп-г хайгаарай."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Бичлэг, хуваарь"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 минут"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 минут"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 цаг"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 цаг"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Сүүлийн"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Хуваарилсан"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Цуврал"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Бусад"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Сувгийг бичих боломжгүй."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Хөтөлбөрийг бичих боломжгүй."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>-г бичихээр товлосон"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>-г одооноос <xliff:g id="ENDTIME">%2$s</xliff:g> хүртэл бичиж байна"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Бүтэн цагийн хуваарь"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">Дараагийн %1$d хоног</item>
- <item quantity="one">Дараагийн %1$d хоног</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d минут</item>
- <item quantity="one">%1$d минут</item>
- </plurals>
- <!-- String.format failed for translation -->
- <!-- no translation found for dvr_count_new_recordings (3569310208305402815) -->
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d бичлэг</item>
- <item quantity="one">%1$d бичлэг</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d бичлэгийг товлосон</item>
- <item quantity="one">%1$d бичлэгийг товлосон</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Үзэх"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Эхнээс нь тоглуулах"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Үргэлжлүүлэн тоглуулах"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Устгах"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Бичлэгийг устгах"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Үргэлжлүүлэх"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-р цуврал"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Хуваарь харах"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Дэлгэрэнгүй унших"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Бичлэгийг устгах"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Устгах ангийг сонгоно уу. Устгасан тохиолдолд дахин сэргээх боломжгүй."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Устгах ямар ч бичлэг алга."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Үзсэн ангийг сонгох"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Бүх ангийг сонгох"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Бүх ангийн сонголтыг цуцлах"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g>-с <xliff:g id="WATCHED">%1$d</xliff:g> минут үзсэн"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g>-с <xliff:g id="WATCHED">%1$d</xliff:g> секунд үзсэн"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Огт үзээгүй"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%2$d-ийн %1$d ангийг устгасан</item>
- <item quantity="one">%2$d-ийн %1$d ангийг устгасан</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Ач холбогдол"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Хамгийн өндөр"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Хамгийн бага"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Үгүй. <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Суваг"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Дурын"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Ач холбогдол сонгох"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Олон хөтөлбөрийг зэрэг бичихээр сонгосон тохиолдолд зөвхөн өндөр ач холбогдолтой хөтөлбөрийг бичнэ."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Хадгалах"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Нэг удаагийн бичлэг өндөр ач холбогдолтой"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Цуцлах"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Цуцлах"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Мартах"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Зогсоох"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Бичих хуваарийг харах"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Зөвхөн энэ хөтөлбөр"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"одоо - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Бүтэн цуврал..."</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Ямартай ч товлох"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Оронд нь үүнийг бичих"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Энэ бичлэгийг цуцлах"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Одоо үзэх"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Дүрс бичих боломжтой"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Дүрс бичихээр товлосон"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Дүрс бичих боломжгүй"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Бичиж байна"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Бичиж чадсангүй"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Бичлэгийн хуваарь үүсгэхийн тулд хөтөлбөрийг уншиж байна"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Хөтөлбөрийг уншиж байна"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR-д илүү багтаамж шаардлагатай"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Та DVR-р хөтөлбөр бичих боломжтой болно. Гэсэн хэдий ч таны төхөөрөмжид DVR ажиллуулах хангалттай багтаамж алга. <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>гигабайт, эсвэл үүнээс дээш багтаамжтай гадаад драйв холбож, үүнийг төхөөрөмжийн сан болгож хэлбэршүүлэхийн тулд зааврыг дагана уу."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Сан алга"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR-н ашигласан зарим сан алга. DVR-г дахин идэвхжүүлэхээс өмнө ашигласан гадаад драйвыг холбоно уу. Хэрэв сан байхгүй бол үүнийг мартах боломжтой."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Санг мартах уу?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Таны бичсэн агуулга, хуваарь устах болно."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Бичлэгийг зогсоох уу?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Бичсэн агуулгыг хадгална."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Бичихээр товлосон ч зөрчилтэй байна"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Бичлэг эхлүүлсэн хэдий ч зөрчилтэй байна"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>-г бичих болно."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g>-г бичиж байна."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g>-н зарим хэсгийг бичихгүй."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> болон <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>-н зарим хэсгийг бичихгүй."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> -н зарим хэсэг болон өөр нэг хуваарийг бичихгүй."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g>-н зарим хэсэг болон %3$d бусад хуваарийг бичихгүй.</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g>-н зарим хэсэг болон %3$d бусад хуваарийг бичихгүй.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Та юу бичих вэ?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Та хэр удаан бичих вэ?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Аль хэдийн товлосон"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Үүнтэй ижил хөтөлбөрийг <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>-д бичихээр товлосон байна."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Аль хэдийн бичсэн"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Энэ хөтөлбөрийг аль хэдийн бичсэн байна. Энэ нь DVR санд боломжтой."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Бичсэн хөтөлбөр олдсонгүй."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Холбоотой бичлэг"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Хөтөлбөрийн тодорхойлолт алга)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d бичлэг</item>
- <item quantity="one">%1$d бичлэг</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>-г бичих хуваариас хассан"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Тааруулагчийн алдааны улмаас хэсэгчлэн бичих болно."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Тааруулагч алдаатай тул бичихгүй."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Одоогоор хуваарьт бичлэг байхгүй байна.\nТа ТВ хөтөлбөрөөс бичлэг товлох боломжтой."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d бичлэгийн зөрчил</item>
- <item quantity="one">%1$d бичлэгийн зөрчил</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Цувралын тохиргоо"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Цувралыг бичиж эхлэх"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Цувралыг бичихээ зогсоох"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Цувралыг бичихээ зогсоох уу?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Бичсэн цувралыг DVR санд хадгална."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Зогсоох"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Ямар ч анги алга.\nТэд боломжтой болсон үедээ бичих болно."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d минут)</item>
- <item quantity="one">(%1$d минут) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Өнөөдөр"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Маргааш"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Өчигдөр"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"өнөөдрийн <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Маргаашийн <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Оноо"</string>
-</resources>
diff --git a/res/values-mr-v23/strings.xml b/res/values-mr-rIN-v23/strings.xml
index d7b703e6..d7b703e6 100644
--- a/res/values-mr-v23/strings.xml
+++ b/res/values-mr-rIN-v23/strings.xml
diff --git a/res/values-mr/arrays.xml b/res/values-mr-rIN/arrays.xml
index a91434f4..a91434f4 100644
--- a/res/values-mr/arrays.xml
+++ b/res/values-mr-rIN/arrays.xml
diff --git a/res/values-mr/rating_system_strings.xml b/res/values-mr-rIN/rating_system_strings.xml
index d192c799..d192c799 100644
--- a/res/values-mr/rating_system_strings.xml
+++ b/res/values-mr-rIN/rating_system_strings.xml
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
new file mode 100644
index 00000000..83d8dd42
--- /dev/null
+++ b/res/values-mr-rIN/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"एक"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"स्टिरिओ"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"प्ले नियंत्रणे"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"चॅनेल"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"टीव्‍ही पर्याय"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"या चॅनेलसाठी अनुपलब्ध असलेली नियंत्रणे प्ले करा"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"प्ले करा किंवा विराम द्या"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"फास्ट फॉरवर्ड करा"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"रिवाईँड करा"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"पुढील"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"मागील"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"कार्यक्रम मार्गदर्शक"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"उपलब्ध नवीन चॅनेल"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> उघडा"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"उपशीर्षक"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"प्रदर्शन मोड"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"मल्टी-ऑडिओ"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"अधिक चॅनेल मिळवा"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"सेटिंग्ज"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"टीव्ही (अँटेना/केबल)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"कोणतीही कार्यक्रम माहिती नाही"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"कोणतीही माहिती नाही"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"अवरोधित चॅनेल"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"अज्ञात भाषा"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"बंद मथळा %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"बंद मथळा"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"बंद"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"स्वरुपन सानुकूलित करा"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"उपशीर्षकांसाठी सिस्‍टीम-विस्तृत प्राधान्ये सेट करा"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"प्रदर्शन मोड"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"मल्टी-ऑडिओ"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"एक"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"स्टिरिओ"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 सराउंड"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 सराउंड"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d चॅनेल"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"चॅनेल सूची सानुकूल करा"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"गट निवडा"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"गट निवड रद्द करा"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"नुसार गट करा"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"चॅनेल स्त्रोत"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"नुसार गट करा"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"हा कार्यक्रम अवरोधित केला आहे"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"या प्रोग्रामला रेट केलेले नाही"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"हा कार्यक्रम <xliff:g id="RATING">%1$s</xliff:g> रेट केला आहे"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"इनपुट स्वयं-स्‍कॅनला समर्थन देत नाही"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' साठी स्वयं-स्कॅन प्रारंभ करण्‍यात अक्षम"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"उपशीर्षकांसाठी सिस्‍टीम-विस्तृत प्राधान्ये प्रारंभ करण्‍यात अक्षम."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d चॅनेल जोडले</item>
+ <item quantity="other">%1$d चॅनेल जोडले</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"कोणतेही चॅनेल जोडले नाही"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"पालक नियंत्रणे"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"चालू"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"बंद"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"चॅनेल अवरोधित केले"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"सर्व अवरोधित करा"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"सर्व अनावरोधित करा"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"लपविलेले चॅनेल"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"कार्यक्रम निर्बंध"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"पिन बदला"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"रेटिंग सिस्‍टीम"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"रेटिंग"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"सर्व रेटिंग सिस्‍टीम पहा"</string>
+ <string name="other_countries" msgid="8342216398676184749">"इतर देश"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"कोणतेही नाही"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"काहीही नाही"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"रेट न केलेले"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"रेट न केलेले प्रोग्राम ब्लॉक करा"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"काहीही नाही"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"उच्च निर्बंंध"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"मध्यम निर्बंध"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"कमी निर्बंध"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"सानुकूल"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"मुलांसाठी योग्य असलेली सामग्री"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"मोठ्या मुलांसाठी योग्य असलेली सामग्री"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"किशोरवयीन मुलांसाठी योग्य असलेली सामग्री"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"व्यक्तीचलित निर्बंध"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s आणि उप रेटिंग"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"उप रेटिंग"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"हे चॅनेल पाहण्‍यासाठी आपला पिन प्रविष्‍ट करा"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"हा कार्यक्रम पाहण्‍यासाठी आपला पिन प्रविष्‍ट करा"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"हा प्रोग्राम <xliff:g id="RATING">%1$s</xliff:g> रेट केलेला आहे. हा प्रोग्राम पाहण्यासाठी आपला पिन प्रविष्ट करा"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"या प्रोग्रामला रेट केलेले नाही. हा प्रोग्राम पाहण्यासाठी तुमचा पिन टाका"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"आपला पिन प्रविष्‍ट करा"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"पालक नियंत्रणे सेट करण्यासाठी, एक पिन तयार करा"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"नवीन पिन प्रविष्ट करा"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"आपल्या पिन ची पुष्टी करा"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"आपला वर्तमान पिन प्रविष्ट करा"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">आपण चुकीचा पिन 5 वेळा प्रविष्‍ट केला.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> सेकंदामध्‍ये पुन्हा प्रयत्न करा.</item>
+ <item quantity="other">आपण चुकीचा पिन 5 वेळा प्रविष्‍ट केला.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> सेकंदांमध्‍ये पुन्हा प्रयत्न करा.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"तो पिन चुकीचा होता. पुन्हा प्रयत्न करा."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"पुन्हा प्रयत्न करा, पिन जुळत नाही"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"आपला पिन कोड प्रविष्ट करा."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"टीव्ही चॅनेलसाठी संपूर्ण कार्यक्रम मार्गदर्शक प्रदान करण्यासाठी थेट चॅनेल अॅप पिन कोड वापरेल."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"आपला पिन कोड प्रविष्ट करा"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"अवैध पिन कोड"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"सेटिंग्ज"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"चॅनेल सूची सानुकूल करा"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"आपल्या कार्यक्रम मार्गदर्शकासाठी चॅनेल निवडा"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"चॅनेल स्त्रोत"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"नवीन चॅनेल उपलब्ध आहेत"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"पालक नियंत्रणे"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"पहात असताना रेकॉर्ड करा ज्यामुळे आपण थेट प्रोग्रामांना विराम देऊ किंवा ते रिवाइंड करू शकता.\nचेतावणी: हे संचयाचा अत्याधिक वापर करून कदाचित अंतर्गत संचयाचे आयुष्य कमी करू शकते."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"मुक्त स्त्रोत परवाने"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"अभिप्राय पाठवा"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"आवृत्ती"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"हे चॅनेल पाहण्यासाठी, उजवे दाबा आणि आपला पिन प्रविष्‍ट करा"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"हा कार्यक्रम पाहण्‍यासाठी, उजवे दाबा आणि आपला पिन प्रविष्‍ट करा"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"या प्रोग्रामला रेट केलेले नाही.\nहा प्रोग्राम पाहण्यासाठी उजवीकडे दाबा आणि तुमचा पिन टाका"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"हा कार्यक्रम <xliff:g id="RATING">%1$s</xliff:g> रेट केला आहे.\n हा कार्यक्रम पाहण्‍यासाठी, उजवे दाबा आणि आपला पिन प्रविष्‍ट करा."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"हे चॅनेल पाहण्यासाठी, डीफॉल्ट थेट टीव्ही अॅप वापरा."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"हा प्रोग्राम पाहण्यासाठी, डीफॉल्ट थेट टीव्ही अॅप वापरा."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"या प्रोग्रामला रेट केलेले नाही.\nहा प्रोग्राम पाहण्यासाठी डीफॉल्ट लाइव्ह टीव्ही अ‍ॅप वापरा."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"हा प्रोग्राम <xliff:g id="RATING">%1$s</xliff:g> रेट केलेला आहे.\nहा प्रोग्राम पाहण्यासाठी, डीफॉल्ट थेट टीव्ही अॅप वापरा."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"कार्यक्रम अवरोधित केला आहे"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"या प्रोग्रामला रेट केलेले नाही"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"हा कार्यक्रम <xliff:g id="RATING">%1$s</xliff:g> रेट केला आहे"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"फक्त ऑडिओ"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"खराब सिग्नल"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"कोणतेही इंटरनेट कनेक्शन नाही"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="one">दुसरे चॅनेल रेकॉर्ड केले जात असल्याने <xliff:g id="END_TIME_1">%1$s</xliff:g> पर्यंत हे चॅनेल प्ले केले जाऊ शकत नाही. \n\nरेकॉर्डिंग अनुसूची समायोजित करण्यासाठी उजवीकडे दाबा.</item>
+ <item quantity="other">दुसरे चॅनेल रेकॉर्ड केले जात असल्याने <xliff:g id="END_TIME_1">%1$s</xliff:g> पर्यंत हे चॅनेल प्ले केले जाऊ शकत नाही. \n\nरेकॉर्डिंग अनुसूची समायोजित करण्यासाठी उजवीकडे दाबा.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"शीर्षक नाही"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"चॅनेल अवरोधित केले"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"नवीन"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"स्त्रोत"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d चॅनेल</item>
+ <item quantity="other">%1$d चॅनेल</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"कोणतेही चॅनेल उपलब्ध नाही"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"नवीन"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"सेट केलेले नाही"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"अधिक स्रोत मिळवा"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"थेट चॅनेल प्रदान करणारे अॅप्स ब्राउझ करा"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"नवीन चॅनेल स्रोत उपलब्ध आहेत"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"प्रदान करण्‍यासाठी नवीन चॅनेल स्रोतांमध्‍ये चॅनेल आहेत. \n आता ते सेट करा किंवा चॅनेल स्रोत सेटिंगमध्ये हे नंतर करा."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"आता सेट करा"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"ठीक आहे, समजले"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"टीव्ही मेनूवर प्रवेश करण्यासाठी "<b>"निवडा दाबा"</b>"."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"कोणतेही टीव्ही इनपुट आढळले नाही"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"टीव्ही इनपुट शोधू शकत नाही"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ट्यूनर प्रकार अनुकूल नाही. कृपया ट्यूनर प्रकार टीव्ही इनपुटसाठी थेट चॅनेल अॅप लाँच करा."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ट्यून अयशस्वी झाले"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"ही क्रिया हाताळण्यासाठी कोणताही अ‍ॅप आढळला नाही."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"सर्व स्त्रोत चॅनेल लपविले आहेत.\nपाहण्‍यासाठी कमीतकमी एक चॅनेल निवडा."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"व्‍हिडिओ अनपेक्षितपणे अनुपलब्ध आहे"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"बॅक की कनेक्ट केलेल्या डिव्हाइससाठी आहे. बाहेर पडण्यासाठी मुख्यपृष्ठ बटण दाबा."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"थेट चॅनेलना टीव्ही सूचींचे वाचन करण्यासाठी परवानगीची आवश्यकता आहे."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"आपले स्रोत सेट करा"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"थेट चॅनेल पारंपारिक TV चॅनेलच्या अनुभवास अॅप्सने प्रदान केलेल्या प्रवाहित केलेल्या चॅनेलसह एकत्रित करतात. \n\nआधीपासून इंस्टॉल केलेले चॅनेल स्रोत सेट करून प्रारंभ करा किंवा थेट चॅनेल प्रदान करणार्‍या आणखी अॅप्ससाठी Google Play स्टोअर ब्राउझ करा."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"रेकॉर्डिंग आणि अनुसूची"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 मिनिटे"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 मिनिटे"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 तास"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 तास"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"अलीकडील"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"अनुसूचित"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"मालिका"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"इतर"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"चॅनेल रेकॉर्ड केले जाऊ शकत नाही."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"प्रोग्राम रेकॉर्ड केला जाऊ शकतो."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"रेकॉर्ड करण्‍यासाठी <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ची अनुसूची केली गेली"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> चे रेकॉर्डिंग आतापासून <xliff:g id="ENDTIME">%2$s</xliff:g> पर्यंत"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"पूर्ण अनुसूची"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="one">पुढील %1$d दिवस</item>
+ <item quantity="other">पुढील %1$d दिवस</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="one">%1$d मिनिट</item>
+ <item quantity="other">%1$d मिनिटे</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="one">%1$d नवीन रेकॉर्डिंग</item>
+ <item quantity="other">%1$d नवीन रेकॉर्डिंग</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="one">%1$d रेकॉर्डिंग</item>
+ <item quantity="other">%1$d रेकॉर्डिंग</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="one">%1$d रेकॉर्डिंगची अनुसूची केली</item>
+ <item quantity="other">%1$d रेकॉर्डिंगची अनुसूची केली</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"रेकॉर्डिंग रद्द करा"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"रेकॉर्डिंग थांबवा"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"पहा"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"सुरूवातीपासून प्ले करा"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"प्ले करणे पुनः सुरु करा"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"हटवा"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"रेकॉर्डिंग हटवा"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"पुनः सुरु करा"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"हंगाम <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"अनुसूची पहा"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"आणखी वाचा"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"रेकॉर्डिंग हटवा"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"आपण हटवू इच्छिता ते भाग निवडा. एकदा हटविले की ते पुनर्प्राप्त केले जाऊ शकत नाहीत."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"हटविण्यासाठी कोणतेही रेकॉर्डिंग नाहीत."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"पाहिलेले भाग निवडा"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"सर्व भाग निवडा"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"सर्व भागांची निवड रद्द करा"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> पैकी <xliff:g id="WATCHED">%1$d</xliff:g> मिनिटांची रेकॉर्डिंग पाहिली"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> पैकी <xliff:g id="WATCHED">%1$d</xliff:g> सेकंदांची रेकॉर्डिंग पाहिली"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"कधीही पाहिली नाहीत"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="one">%2$d पैकी %1$d भाग हटविला आहे</item>
+ <item quantity="other">%2$d पैकी %1$d भाग हटविले आहेत</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"प्राधान्य"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"सर्वोच्च"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"सर्वात निम्न"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"<xliff:g id="RANK">%1$d</xliff:g> क्र."</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"चॅनेल"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"कोणतेही"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"प्राधान्य निवडा"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"एकाच वेळी रेकॉर्ड करण्यासाठी खूप जास्त प्रोग्राम असतात तेव्हा, केवळ अधिक प्राधान्ये असलेले प्रोग्राम रेकॉर्ड केले जातील."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"जतन करा"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"एक-वेळ रेकॉर्डिंगला सर्वोच्च प्राधान्य आहे"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"थांबा"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"रेकॉर्डिंग अनुसूची पहा"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"हा एक कार्यक्रम"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"आता - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"संपूर्ण मालिका…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"तरीही शेड्यूल करा"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"त्याऐवजी हे रेकॉर्ड करा"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"हे रेकॉर्डिंग रद्द करा"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"आता पहा"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"रेकॉर्डिंग हटवा..."</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"रेकॉर्ड करण्यायोग्य"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"रेकॉर्डिंग अनुसूचित केले"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"रेकॉर्डिंग संबंधी विरोध"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"रेकॉर्डिंग"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"रेकॉर्डिंग अयशस्वी झाले"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"वाचन कार्यक्रम"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"अलीकडील रेकॉर्डिंग पहा"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> चे रेकॉर्डिंग अपूर्ण आहे."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> आणि <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> चे रेकॉर्डिंग अपूर्ण आहे."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> आणि <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> चे रेकॉर्डिंग अपूर्ण आहे."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"अपुर्‍या संचयामुळे <xliff:g id="PROGRAMNAME">%1$s</xliff:g> चे रेकॉर्डिंग पूर्ण झाले नाही."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"अपुर्‍या संचयामुळे <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> आणि <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> चे रेकॉर्डिंग पूर्ण झाले नाही."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"अपुर्‍या संचयामुळे <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> चे रेकॉर्डिंग पूर्ण झाले नाही."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR साठी आणखी संचय आवश्यक आहे"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"आपण DVR ने प्रोग्राम रेकॉर्ड करण्यात सक्षम असाल. तथापि DVR ने कार्य करण्यासाठी आपल्या डीव्हाइसवर आता पुरेसा संचय नाही. कृपया <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB किंवा त्यापेक्षा मोठ्या बाह्य ड्राइव्हशी कनेक्ट करा आणि त्यास डीव्हाइस संचय म्हणून स्वरूपित करण्‍यासाठी चरणांचे अनुसरण करा."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"पुरेसा संचय नाही"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"पुरेसा संचय नसल्याने हा कार्यक्रम रेकॉर्ड केला जाणार नाही. काही विद्यमान रेकॉर्डिंग हटवून पहा."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"संचय गहाळ आहे"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"रेकॉर्डिंग थांबवायचे?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"रेकॉर्ड केलेली सामग्री जतन केली जाईल."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> चे रेकॉर्डिंग थांबवले जाईल कारण ते या कार्यक्रमासह संघर्ष करते. रेकॉर्ड केलेली सामग्री जतन केली जाईल."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"रेकॉर्डिंगची अनुसूची केली परंतु त्यासंबंधी विरोध आहेत"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"रेकॉर्डिंग सुरू झाली परंतु त्यासंबंधी विरोध आहेत"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> रेकॉर्ड केला जाईल."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> रेकॉर्ड केला जात आहे."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> चे काही भाग रेकॉर्ड केले जाणार नाहीत."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> आणि <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> चे काही भाग रेकॉर्ड केले जाणार नाहीत."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> चे काही भाग आणि आणखी एक अनुसूची रेकॉर्ड केली जाणार नाही."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> आणि आणखी %3$d अनुसूची रेकॉर्ड केली जाणार नाही.</item>
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> आणि आणखी %3$d अनुसूची रेकॉर्ड केली जाणार नाही.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"आपल्याला काय रेकॉर्ड करायला आवडेल?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"आपल्याला किती वेळ रेकॉर्ड करायला आवडेल?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"आधीच शेड्यूल केला आहे"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> रोजी रेकॉर्ड करण्यासाठी तोच कार्यक्रम आधीच शेड्यूल केला आहे."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"आधीच रेकॉर्ड केला आहे"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"हा कार्यक्रम आधीच रेकॉर्ड केला गेला आहे. तो DVR लायब्ररीमध्ये उपलब्ध आहे."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"मालिका रेकॉर्डिंग अनुसूचित केले"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> साठी <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रेकॉर्डिंगची अनुसूची केली गेली.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> साठी <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रेकॉर्डिंगची अनुसूची केली गेली.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> साठी <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रेकॉर्डिंगची अनुसूची केली गेली. त्यांंच्यापैकी <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> विरोधांमुळे रेकॉर्ड केले जाणार नाहीत.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> साठी <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रेकॉर्डिंगची अनुसूची केली गेली. त्यांंच्यापैकी <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> विरोधांमुळे रेकॉर्ड केले जाणार नाहीत.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> साठी <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> रेकॉर्डिंगची अनुसूची केली गेली. या मालिकेचे आणि अन्य मालिकांचे <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> भाग विरोधांमुळे रेकॉर्ड केले जाणार नाहीत.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> साठी <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> रेकॉर्डिंगची अनुसूची केली गेली. या मालिकेचे आणि अन्य मालिकांचे <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> भाग विरोधांमुळे रेकॉर्ड केले जाणार नाहीत.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> साठी <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रेकॉर्डिंगची अनुसूची केली गेली. अन्य मालिकांचा 1 भाग विरोधांमुळे रेकॉर्ड केला जाणार नाही.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> साठी <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रेकॉर्डिंगची अनुसूची केली गेली. अन्य मालिकांचा 1 भाग विरोधांमुळे रेकॉर्ड केला जाणार नाही.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> साठी <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> रेकॉर्डिंगची अनुसूची केली गेली. अन्य मालिकेचे <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> भाग विरोधांंमुळे रेकॉर्ड केले जाणार नाहीत.</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> साठी <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> रेकॉर्डिंगची अनुसूची केली गेली. अन्य मालिकेचे <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> भाग विरोधांंमुळे रेकॉर्ड केले जाणार नाहीत.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"रेकॉर्ड केलेला प्रोग्राम सापडला नाही."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"संबंधित रेकॉर्डिंग"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="one">%1$d रेकॉर्डिंग</item>
+ <item quantity="other">%1$d रेकॉर्डिंग</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> रेकॉर्डिंग अनुसूची मधून काढला"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ट्यूनर विरोधामुळे अंशतः रेकॉर्ड केले जाईल."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ट्यूनर विरोधामुळे रेकॉर्ड केले जाणार नाही."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"अद्याप कोणतेही रेकॉर्डिंग शेड्यूल केलेले नाही\nआपण कार्यक्रम मार्गदर्शकामधून रेकॉर्डिंग शेड्यूल करू शकता."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="one">%1$d रेकॉर्डिंग संबंधी विरोध</item>
+ <item quantity="other">%1$d रेकॉर्डिंग संबंधी विरोध</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"मालिका सेटिंग्ज"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"मालिका रेकॉर्ड करणे प्रारंभ करा"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"मालिका रेकॉर्ड करणे थांबवा"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"मालिका रेकॉर्ड करणे थांबवायचे?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"रेकॉर्ड केलेले भाग DVR लायब्ररी मध्ये उपलब्ध राहतील."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"थांबा"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"आता कोणत्याही भागांचे प्रसारण होत नाही."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"कोणतेही भाग उपलब्ध नाहीत.\nते उपलब्ध झाल्यावर रेकॉर्ड केले जातील."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="one">(%1$d मिनिट)</item>
+ <item quantity="other">(%1$d मिनिटे)</item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"आज"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"उद्या"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"काल"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"आज <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"उद्या <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"गुणसंख्‍या"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"रेकॉर्ड केलेले प्रोग्राम"</string>
+</resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
deleted file mode 100644
index 1888e9de..00000000
--- a/res/values-mr/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"एक"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"स्टिरिओ"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"प्ले नियंत्रणे"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"अलीकडील चॅनेल"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"टीव्‍ही पर्याय"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP पर्याय"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"या चॅनेलसाठी अनुपलब्ध असलेली नियंत्रणे प्ले करा"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"प्ले करा किंवा विराम द्या"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"फास्ट फॉरवर्ड करा"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"रिवाईँड करा"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"पुढील"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"मागील"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"कार्यक्रम मार्गदर्शक"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"उपलब्ध नवीन चॅनेल"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> उघडा"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"उपशीर्षक"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"प्रदर्शन मोड"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"चालू"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"बंद"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"मल्टी-ऑडिओ"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"अधिक चॅनेल मिळवा"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"सेटिंग्ज"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"स्त्रोत"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"अदलाबदल करा"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"चालू"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"बंद"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"ध्वनी"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"मुख्य"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP विंडो"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"लेआउट"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"तळाशी उजवीकडे"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"शीर्षस्थानी उजवीकडे"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"शीर्षस्थानी डावीकडे"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"तळाशी डावीकडे"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"शेजारी शेजारी"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"आकार"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"मोठा"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"लहान"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"इनपुट स्त्रोत"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"टीव्ही (अँटेना/केबल)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"कोणतीही कार्यक्रम माहिती नाही"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"कोणतीही माहिती नाही"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"अवरोधित चॅनेल"</string>
- <string name="default_language" msgid="4122326459624337928">"अज्ञात भाषा"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"बंद मथळा"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"बंद"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"स्वरुपन सानुकूलित करा"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"उपशीर्षकांसाठी सिस्‍टीम-विस्तृत प्राधान्ये सेट करा"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"प्रदर्शन मोड"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"मल्टी-ऑडिओ"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"एक"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"स्टिरिओ"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 सराउंड"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 सराउंड"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d चॅनेल"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"चॅनेल सूची सानुकूल करा"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"गट निवडा"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"गट निवड रद्द करा"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"नुसार गट करा"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"चॅनेल स्त्रोत"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"नुसार गट करा"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"हा कार्यक्रम अवरोधित केला आहे"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"हा कार्यक्रम <xliff:g id="RATING">%1$s</xliff:g> रेट केला आहे"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"इनपुट स्वयं-स्‍कॅनला समर्थन देत नाही"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' साठी स्वयं-स्कॅन प्रारंभ करण्‍यात अक्षम"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"उपशीर्षकांसाठी सिस्‍टीम-विस्तृत प्राधान्ये प्रारंभ करण्‍यात अक्षम."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="one">%1$d चॅनेल जोडले</item>
- <item quantity="other">%1$d चॅनेल जोडले</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"कोणतेही चॅनेल जोडले नाही"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ट्यूनर"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"पालक नियंत्रणे"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"चालू"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"बंद"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"चॅनेल अवरोधित केले"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"सर्व अवरोधित करा"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"सर्व अनावरोधित करा"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"लपविलेले चॅनेल"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"कार्यक्रम निर्बंध"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"पिन बदला"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"रेटिंग सिस्‍टीम"</string>
- <string name="option_ratings" msgid="4009116954188688616">"रेटिंग"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"सर्व रेटिंग सिस्‍टीम पहा"</string>
- <string name="other_countries" msgid="8342216398676184749">"इतर देश"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"कोणतेही नाही"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"काहीही नाही"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"काहीही नाही"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"उच्च निर्बंंध"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"मध्यम निर्बंध"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"कमी निर्बंध"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"सानुकूल"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"मुलांसाठी योग्य असलेली सामग्री"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"मोठ्या मुलांसाठी योग्य असलेली सामग्री"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"किशोरवयीन मुलांसाठी योग्य असलेली सामग्री"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"व्यक्तीचलित निर्बंध"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s आणि उप रेटिंग"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"उप रेटिंग"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"हे चॅनेल पाहण्‍यासाठी आपला पिन प्रविष्‍ट करा"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"हा कार्यक्रम पाहण्‍यासाठी आपला पिन प्रविष्‍ट करा"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"हा प्रोग्राम <xliff:g id="RATING">%1$s</xliff:g> रेट केलेला आहे. हा प्रोग्राम पाहण्यासाठी आपला PIN प्रविष्ट करा"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"आपला पिन प्रविष्‍ट करा"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"पालक नियंत्रणे सेट करण्यासाठी, एक पिन तयार करा"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"नवीन पिन प्रविष्ट करा"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"आपल्या पिन ची पुष्टी करा"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"आपला वर्तमान पिन प्रविष्ट करा"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="one">आपण चुकीचा पिन 5 वेळा प्रविष्‍ट केला.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> सेकंदामध्‍ये पुन्हा प्रयत्न करा.</item>
- <item quantity="other">आपण चुकीचा पिन 5 वेळा प्रविष्‍ट केला.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> सेकंदांमध्‍ये पुन्हा प्रयत्न करा.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"तो पिन चुकीचा होता. पुन्हा प्रयत्न करा."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"पुन्हा प्रयत्न करा, पिन जुळत नाही"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"सेटिंग्ज"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"चॅनेल सूची सानुकूल करा"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"आपल्या कार्यक्रम मार्गदर्शकासाठी चॅनेल निवडा"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"चॅनेल स्त्रोत"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"नवीन चॅनेल उपलब्ध आहेत"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"पालक नियंत्रणे"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"मुक्त स्त्रोत परवाने"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"मुक्त स्त्रोत परवाने"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"आवृत्ती"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"हे चॅनेल पाहण्यासाठी, उजवे दाबा आणि आपला पिन प्रविष्‍ट करा"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"हा कार्यक्रम पाहण्‍यासाठी, उजवे दाबा आणि आपला पिन प्रविष्‍ट करा"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"हा कार्यक्रम <xliff:g id="RATING">%1$s</xliff:g> रेट केला आहे.\n हा कार्यक्रम पाहण्‍यासाठी, उजवे दाबा आणि आपला पिन प्रविष्‍ट करा."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"हे चॅनेल पाहण्यासाठी, डीफॉल्ट थेट टीव्ही अॅप वापरा."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"हा प्रोग्राम पाहण्यासाठी, डीफॉल्ट थेट टीव्ही अॅप वापरा."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"हा प्रोग्राम <xliff:g id="RATING">%1$s</xliff:g> रेट केलेला आहे.\nहा प्रोग्राम पाहण्यासाठी, डीफॉल्ट थेट टीव्ही अॅप वापरा."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"कार्यक्रम अवरोधित केला आहे"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"हा कार्यक्रम <xliff:g id="RATING">%1$s</xliff:g> रेट केला आहे"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"फक्त ऑडिओ"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"खराब सिग्नल"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"कोणतेही इंटरनेट कनेक्शन नाही"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="one">दुसरे चॅनेल रेकॉर्ड केले जात असल्याने <xliff:g id="END_TIME_1">%1$s</xliff:g> पर्यंत हे चॅनेल प्ले केले जाऊ शकत नाही. \n\nरेकॉर्डिंग अनुसूची समायोजित करण्यासाठी उजवीकडे दाबा.</item>
- <item quantity="other">दुसरे चॅनेल रेकॉर्ड केले जात असल्याने <xliff:g id="END_TIME_1">%1$s</xliff:g> पर्यंत हे चॅनेल प्ले केले जाऊ शकत नाही. \n\nरेकॉर्डिंग अनुसूची समायोजित करण्यासाठी उजवीकडे दाबा.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"शीर्षक नाही"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"चॅनेल अवरोधित केले"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"नवीन"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"स्त्रोत"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="one">%1$d चॅनेल</item>
- <item quantity="other">%1$d चॅनेल</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"कोणतेही चॅनेल उपलब्ध नाही"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"नवीन"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"सेट केलेले नाही"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"अधिक स्रोत मिळवा"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"थेट चॅनेल प्रदान करणारे अॅप्स ब्राउझ करा"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"नवीन चॅनेल स्रोत उपलब्ध आहेत"</string>
- <string name="new_sources_description" msgid="749649005588426813">"प्रदान करण्‍यासाठी नवीन चॅनेल स्रोतांमध्‍ये चॅनेल आहेत. \n आता ते सेट करा किंवा चॅनेल स्रोत सेटिंगमध्ये हे नंतर करा."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"आता सेट करा"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"ठीक आहे, समजले"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"टीव्ही मेनूवर प्रवेश करण्यासाठी "<b>"निवडा दाबा"</b>"."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"कोणतेही टीव्ही इनपुट आढळले नाही"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"टीव्ही इनपुट शोधू शकत नाही"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP समर्थित नाही"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP सह दर्शविले जाऊ शकते असे कोणतेही उपलब्ध इनपुट नाही"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ट्यूनर प्रकार अनुकूल नाही. कृपया ट्यूनर प्रकार टीव्ही इनपुटसाठी थेट चॅनेल अॅप लाँच करा."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"ट्यून अयशस्वी झाले"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"ही क्रिया हाताळण्यासाठी कोणताही अ‍ॅप आढळला नाही."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"सर्व स्त्रोत चॅनेल लपविले आहेत.\nपाहण्‍यासाठी कमीतकमी एक चॅनेल निवडा."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"व्‍हिडिओ अनपेक्षितपणे अनुपलब्ध आहे"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"बॅक की कनेक्ट केलेल्या डिव्हाइससाठी आहे. बाहेर पडण्यासाठी मुख्यपृष्ठ बटण दाबा."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"थेट चॅनेलना टीव्ही सूचींचे वाचन करण्यासाठी परवानगीची आवश्यकता आहे."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"आपले स्रोत सेट करा"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"थेट चॅनेल पारंपारिक TV चॅनेलच्या अनुभवास अॅप्सने प्रदान केलेल्या प्रवाहित केलेल्या चॅनेलसह एकत्रित करतात. \n\nआधीपासून स्थापित केलेले चॅनेल स्रोत सेट करून प्रारंभ करा किंवा थेट चॅनेल प्रदान करणार्‍या आणखी अॅप्ससाठी Google Play स्टोअर ब्राउझ करा."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"रेकॉर्डिंग आणि अनुसूची"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 मिनिटे"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 मिनिटे"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 तास"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 तास"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"अलीकडील"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"अनुसूचित"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"मालिका"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"इतर"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"चॅनेल रेकॉर्ड केले जाऊ शकत नाही."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"प्रोग्राम रेकॉर्ड केला जाऊ शकतो."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"रेकॉर्ड करण्‍यासाठी <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ची अनुसूची केली गेली"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> चे रेकॉर्डिंग आतापासून <xliff:g id="ENDTIME">%2$s</xliff:g> पर्यंत"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"पूर्ण अनुसूची"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="one">पुढील %1$d दिवस</item>
- <item quantity="other">पुढील %1$d दिवस</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="one">%1$d मिनिट</item>
- <item quantity="other">%1$d मिनिटे</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="one">%1$d नवीन रेकॉर्डिंग</item>
- <item quantity="other">%1$d नवीन रेकॉर्डिंग</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="one">%1$d रेकॉर्डिंग</item>
- <item quantity="other">%1$d रेकॉर्डिंग</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="one">%1$d रेकॉर्डिंगची अनुसूची केली</item>
- <item quantity="other">%1$d रेकॉर्डिंगची अनुसूची केली</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"पहा"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"सुरूवातीपासून प्ले करा"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"प्ले करणे पुनः सुरु करा"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"हटवा"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"रेकॉर्डिंग हटवा"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"पुनः सुरु करा"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"हंगाम <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"अनुसूची पहा"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"आणखी वाचा"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"रेकॉर्डिंग हटवा"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"आपण हटवू इच्छिता ते भाग निवडा. एकदा हटविले की ते पुनर्प्राप्त केले जाऊ शकत नाहीत."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"हटविण्यासाठी कोणतेही रेकॉर्डिंग नाहीत."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"पाहिलेले भाग निवडा"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"सर्व भाग निवडा"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"सर्व भागांची निवड रद्द करा"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> पैकी <xliff:g id="WATCHED">%1$d</xliff:g> मिनिटांची रेकॉर्डिंग पाहिली"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> पैकी <xliff:g id="WATCHED">%1$d</xliff:g> सेकंदांची रेकॉर्डिंग पाहिली"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"कधीही पाहिली नाहीत"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="one">%2$d पैकी %1$d भाग हटविला आहे</item>
- <item quantity="other">%2$d पैकी %1$d भाग हटविले आहेत</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"प्राधान्य"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"सर्वोच्च"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"सर्वात निम्न"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"<xliff:g id="RANK">%1$d</xliff:g> क्र."</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"चॅनेल"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"कोणतेही"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"प्राधान्य निवडा"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"एकाच वेळी रेकॉर्ड करण्यासाठी खूप जास्त प्रोग्राम असतात तेव्हा, केवळ अधिक प्राधान्ये असलेले प्रोग्राम रेकॉर्ड केले जातील."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"जतन करा"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"एक-वेळ रेकॉर्डिंगला सर्वोच्च प्राधान्य आहे"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"रद्द करा"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"रद्द करा"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"विसरा"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"थांबा"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"रेकॉर्डिंग अनुसूची पहा"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"हा एक कार्यक्रम"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"आता - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"संपूर्ण मालिका…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"तरीही शेड्यूल करा"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"त्याऐवजी हे रेकॉर्ड करा"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"हे रेकॉर्डिंग रद्द करा"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"आता पहा"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"रेकॉर्ड करण्यायोग्य"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"रेकॉर्डिंग अनुसूचित केले"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"रेकॉर्डिंग संबंधी विरोध"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"रेकॉर्डिंग"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"रेकॉर्डिंग अयशस्वी झाले"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"रेकॉर्डिंग अनुसूची तयार करण्यासाठी प्रोग्राम वाचत आहे"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"वाचन कार्यक्रम"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR साठी आणखी संचय आवश्यक आहे"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"आपण DVR ने प्रोग्राम रेकॉर्ड करण्यात सक्षम असाल. तथापि DVR ने कार्य करण्यासाठी आपल्या डिव्हाइसवर आता पुरेसा संचय नाही. कृपया <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB किंवा त्यापेक्षा मोठ्या बाह्य ड्राइव्हशी कनेक्ट करा आणि त्यास डिव्हाइस संचय म्हणून स्वरूपित करण्‍यासाठी चरणांचे अनुसरण करा."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"संचय गहाळ आहे"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR ने वापरलेला काही संचय गहाळ आहे. कृपया DVR पुन्हा सक्षम करण्‍यासाठी आपण पूर्वी वापरलेला बाह्य ड्राइव्ह कनेक्ट करा. वैकल्पिकपणे, यापुढे संचय उपलब्ध नसल्यास आपण तो विसरणे निवडू शकता."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"संचय विसरलात?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"आपली सर्व रेकॉर्ड केलेली सामग्री आणि अनुसूची गमावल्या जातील."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"रेकॉर्डिंग थांबवायचे?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"रेकॉर्ड केलेली सामग्री जतन केली जाईल."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"रेकॉर्डिंगची अनुसूची केली परंतु त्यासंबंधी विरोध आहेत"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"रेकॉर्डिंग सुरू झाली परंतु त्यासंबंधी विरोध आहेत"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> रेकॉर्ड केला जाईल."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> रेकॉर्ड केला जात आहे."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> चे काही भाग रेकॉर्ड केले जाणार नाहीत."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> आणि <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> चे काही भाग रेकॉर्ड केले जाणार नाहीत."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> चे काही भाग आणि आणखी एक अनुसूची रेकॉर्ड केली जाणार नाही."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> आणि आणखी %3$d अनुसूची रेकॉर्ड केली जाणार नाही.</item>
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> आणि आणखी %3$d अनुसूची रेकॉर्ड केली जाणार नाही.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"आपल्याला काय रेकॉर्ड करायला आवडेल?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"आपल्याला किती वेळ रेकॉर्ड करायला आवडेल?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"आधीच शेड्यूल केला आहे"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> रोजी रेकॉर्ड करण्यासाठी तोच कार्यक्रम आधीच शेड्यूल केला आहे."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"आधीच रेकॉर्ड केला आहे"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"हा कार्यक्रम आधीच रेकॉर्ड केला गेला आहे. तो DVR लायब्ररीमध्ये उपलब्ध आहे."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"रेकॉर्ड केलेला प्रोग्राम सापडला नाही."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"संबंधित रेकॉर्डिंग"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(कोणत्याही प्रोग्रामचे वर्णन नाही)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="one">%1$d रेकॉर्डिंग</item>
- <item quantity="other">%1$d रेकॉर्डिंग</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> रेकॉर्डिंग अनुसूची मधून काढला"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ट्यूनर विरोधामुळे अंशतः रेकॉर्ड केले जाईल."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ट्यूनर विरोधामुळे रेकॉर्ड केले जाणार नाही."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"अद्याप कोणतेही रेकॉर्डिंग शेड्यूल केलेले नाही\nआपण कार्यक्रम मार्गदर्शकामधून रेकॉर्डिंग शेड्यूल करू शकता."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="one">%1$d रेकॉर्डिंग संबंधी विरोध</item>
- <item quantity="other">%1$d रेकॉर्डिंग संबंधी विरोध</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"मालिका सेटिंग्ज"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"मालिका रेकॉर्ड करणे प्रारंभ करा"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"मालिका रेकॉर्ड करणे थांबवा"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"मालिका रेकॉर्ड करणे थांबवायचे?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"रेकॉर्ड केलेले भाग DVR लायब्ररी मध्ये उपलब्ध राहतील."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"थांबा"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"कोणतेही भाग उपलब्ध नाहीत.\nते उपलब्ध झाल्यावर रेकॉर्ड केले जातील."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="one">(%1$d मिनिट)</item>
- <item quantity="other">(%1$d मिनिटे)</item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"आज"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"उद्या"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"काल"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"आज <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"उद्या <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"गुणसंख्‍या"</string>
-</resources>
diff --git a/res/values-ms-v23/strings.xml b/res/values-ms-rMY-v23/strings.xml
index ba29d7b7..ba29d7b7 100644
--- a/res/values-ms-v23/strings.xml
+++ b/res/values-ms-rMY-v23/strings.xml
diff --git a/res/values-ms/arrays.xml b/res/values-ms-rMY/arrays.xml
index 16ccce64..16ccce64 100644
--- a/res/values-ms/arrays.xml
+++ b/res/values-ms-rMY/arrays.xml
diff --git a/res/values-ms/rating_system_strings.xml b/res/values-ms-rMY/rating_system_strings.xml
index a5f781fe..a5f781fe 100644
--- a/res/values-ms/rating_system_strings.xml
+++ b/res/values-ms-rMY/rating_system_strings.xml
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
new file mode 100644
index 00000000..91716d81
--- /dev/null
+++ b/res/values-ms-rMY/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Kawalan main"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Saluran"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"Pilihan TV"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Kawalan main tidak tersedia untuk saluran ini"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Main atau jeda"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Mara laju"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Gulung semula"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Seterusnya"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Sebelumnya"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Panduan program"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Saluran baharu tersedia"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Buka <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Sari kata"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Mod paparan"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Berbilang audio"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Dptkn lg saluran"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Tetapan"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/kabel)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Maklumat program tiada"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Tiada maklumat"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Saluran disekat"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Bahasa tidak diketahui"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Sari kata %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Sari kata"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Dimatikan"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Sesuaikan format"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Tetapkan pilihan sari kata seluruh sistem"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Mod paparan"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Berbilang audio"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"stereo"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 keliling"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 keliling"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d saluran"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Sesuaikan saluran"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Pilih kumpulan"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Nyahpilih kumpulan"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Kumpulkan mengikut"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Sumber saluran"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Kumpulkan mengikut"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Rancangan ini disekat"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Rancangan ini tidak dinilai"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Rancangan ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Input tidak menyokong autoimbas"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Tidak dapat memulakan autoimbas untuk \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Tidak dapat memulakan pilihan sari kata untuk seluruh sistem."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d saluran ditambahkan</item>
+ <item quantity="one">%1$d saluran ditambahkan</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Tiada saluran ditambahkan"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Kawalan ibu bapa"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Hidup"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Dimatikan"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Saluran disekat"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Sekat semua"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Nyahsekat semua"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Saluran tersembunyi"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Sekatan program"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"Tukar PIN"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Sistem penilaian"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Penilaian"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Lihat sistem penilaian"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Negara lain"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Tiada"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Tiada"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Tidak dinilai"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Sekat rancangan yg tdk dinilai"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Tiada"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Sekatan ketat"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Sekatan sederhana"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Sekatan longgar"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Tersuai"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Kandungan sesuai untuk kanak-kanak"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Kandungan sesuai utk kanak-kanak berusia"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Kandungan yang sesuai untuk remaja"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Sekatan manual"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s &amp; subpenilaian"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Subpenilaian"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Masukkan PIN anda untuk menonton saluran ini"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Masukkan PIN anda untuk menonton rancangan ini"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Rancangan ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>. Masukkan PIN anda untuk menonton rancangan ini"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Rancangan ini tidak dinilai. Masukkan PIN anda untuk menonton rancangan ini"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"Masukkan PIN anda"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Untuk menetapkan kawalan ibu bapa, buat PIN"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Masukkan PIN baharu"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"Sahkan PIN anda"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Masukkan PIN semasa anda"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Anda telah memasukkan PIN yang salah sebanyak 5 kali.\nCuba lagi dalam masa <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> saat.</item>
+ <item quantity="one">Anda telah memasukkan PIN yang salah sebanyak 5 kali.\nCuba lagi dalam masa <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> saat.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN itu salah. Cuba lagi."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Cuba lagi, PIN tidak sepadan"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Masukkan Poskod anda."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Apl Saluran Langsung akan menggunakan Poskod untuk menyediakan panduan lengkap rancangan saluran TV."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Masukkan Poskod anda"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Poskod tidak sah"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Tetapan"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Sesuaikan senarai saluran"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Pilih saluran untuk panduan rancangan anda"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Sumber saluran"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Saluran baharu tersedia"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Kawalan ibu bapa"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Anjakan masa"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Rakam semasa menonton supaya anda boleh menjeda atau mandir rancangan langsung.\nAmaran: Tindakan ini boleh mengurangkan hayat storan dalaman melalui penggunaan intensif storan itu."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Lesen sumber terbuka"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Hantar maklum balas"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versi"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Untuk menonton saluran ini, tekan Kanan dan masukkan PIN anda"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Untuk menonton rancangan ini, tekan Kanan dan masukkan PIN anda"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Rancangan ini tidak dinilai.\nUntuk menonton rancangan ini, tekan Kanan kemudian masukkan PIN anda"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Rancangan ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>.\nUntuk menonton rancangan ini, tekan Kanan, kemudian masukkan PIN anda."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Untuk menonton saluran ini, gunakan apl lalai TV Langsung."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Untuk menonton program ini, gunakan apl lalai TV Langsung."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Rancangan ini tidak dinilai.\nUntuk menonton rancangan ini, gunakan apl lalai TV Langsung."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Atur cara ini telah dinilai <xliff:g id="RATING">%1$s</xliff:g>.\nUntuk menonton program ini, gunakan apl lalai TV Langsung."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Rancangan disekat"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Rancangan ini tidak dinilai"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Rancangan ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audio sahaja"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Isyarat lemah"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Tiada sambungan Internet"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">Saluran ini tidak dapat dimainkan hingga <xliff:g id="END_TIME_1">%1$s</xliff:g> kerana saluran lain sedang dirakamkan. \n\nTekan Kanan untuk melaraskan jadual rakaman.</item>
+ <item quantity="one">Saluran ini tidak dapat dimainkan hingga <xliff:g id="END_TIME_0">%1$s</xliff:g> kerana saluran lain sedang dirakamkan. \n\nTekan Kanan untuk melaraskan jadual rakaman.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Tiada tajuk"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Saluran disekat"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Baharu"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Sumber"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d saluran</item>
+ <item quantity="one">1$d saluran</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Tiada saluran yang tersedia"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Baharu"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Tidak disediakan"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Dapatkan lebih banyak sumber"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Semak imbas apl yang menawarkan saluran langsung"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Sumber saluran yang baharu tersedia"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Sumber saluran baharu mempunyai saluran untuk ditawarkan.\nSediakan saluran sekarang atau lakukannya kemudian dalam tetapan sumber saluran."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Sediakan sekarang"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>"Tekan PILIH"</b>" untuk mengakses menu TV."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"Input TV tidak ditemui"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"Tidak menemui input TV"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Jenis penala tidak sesuai; Sila lancarkan apl Saluran Langsung untuk input TV jenis penala."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Penalaan gagal"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Tiada apl ditemui untuk mengendalikan tindakan ini."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Semua saluran sumber disembunyikan.\nPilih sekurang-kurangnya satu saluran untuk ditonton."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Video ini tidak tersedia tanpa dijangka"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"Kekunci BACK adalah untuk peranti yang tersambung. Tekan butang HOME untuk keluar."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Saluran Langsung memerlukan kebenaran untuk membaca penyenaraian TV."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Sediakan sumber anda"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Saluran langsung menggabungkan pengalaman saluran TV tradisional dengan saluran penstriman yang disediakan oleh apl. \n\nMulakan dengan menyediakan sumber saluran yang sudah dipasang. Selain itu, semak imbas Gedung Google Play untuk mendapatkan lebih banyak apl yang menawarkan saluran langsung."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Rakaman &amp; jadual"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minit"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minit"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 jam"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 jam"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Terbaharu"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Dijadualkan"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Siri"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Lain-lain"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Saluran ini tidak boleh dirakam."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Rancangan ini tidak boleh dirakam."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> telah dijadualkan untuk dirakamkan"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Merakam <xliff:g id="PROGRAMNAME">%1$s</xliff:g> mulai sekarang hingga <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Jadual penuh"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">%1$d hari seterusnya</item>
+ <item quantity="one">%1$d hari seterusnya</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d minit</item>
+ <item quantity="one">%1$d minit</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d rakaman baharu</item>
+ <item quantity="one">%1$d rakaman baharu</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d rakaman</item>
+ <item quantity="one">%1$d rakaman</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d rakaman dijadualkan</item>
+ <item quantity="one">%1$d rakaman dijadualkan</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Batalkan rakaman"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Hentikan rakaman"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Tonton"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Mainkan dari mula"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Sbg smula prses main"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Padam"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Padam rakaman"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Sambung semula"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Musim <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Lihat jadual"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Baca lagi"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Padam rakaman"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Pilih episod yang anda ingin padamkan. Episod ini tidak boleh dipulihkan setelah dipadamkan."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Tiada rakaman untuk dipadamkan."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Pilih episod yg sudah ditonton"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Pilih semua episod"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Nyahpilih semua episod"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> daripada <xliff:g id="DURATION">%2$d</xliff:g> minit tontonan"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> daripada <xliff:g id="DURATION">%2$d</xliff:g> saat tontonan"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Belum pernah ditonton"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%1$d daripada %2$d episod dipadamkan</item>
+ <item quantity="one">%1$d daripada %2$d episod dipadamkan</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Keutamaan"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Tertinggi"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Terendah"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Nombor <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Saluran"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Sebarang"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Pilih keutamaan"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Apabila ada terlalu banyak rancangan yang ingin dirakamkan secara serentak, rancangan yang berkeutamaan lebih tinggi sahaja yang akan dirakamkan."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Simpan"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Rakaman bersifat sekali sahaja mendapat keutamaan tertinggi"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Berhenti"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Lihat jadual rakaman"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Program ini sahaja"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"sekarang - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Keseluruhan siri..."</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Jadualkan juga"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Sebaliknya rakamkan yang ini"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Batalkan rakaman ini"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Tonton sekarang"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Padam rakaman..."</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Boleh rakam"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Rakaman dijadualkan"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Konflik rakaman"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Merakam"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Perakaman gagal"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Membaca rancangan"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Lihat rakaman terbaharu"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Rakaman <xliff:g id="PROGRAMNAME">%1$s</xliff:g> tidak lengkap."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Rakaman <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> dan <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> tidak lengkap."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Rakaman <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> dan <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> tidak lengkap."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Rakaman <xliff:g id="PROGRAMNAME">%1$s</xliff:g> tidak lengkap kerana storan tidak mencukupi."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Rakaman <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> dan <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> tidak lengkap kerana storan tidak mencukupi."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Rakaman <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> dan <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> tidak lengkap kerana storan tidak mencukupi."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR memerlukan storan yang lebih besar"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Anda boleh merakam rancangan menggunakan DVR. Walau bagaimanapun storan pada peranti anda kini tidak mencukupi untuk DVR berfungsi. Sila sambungkan pemacu luaran <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB atau lebih besar dan ikut langkah untuk memformat pemacu itu sebagai storan peranti."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Storan tidak mencukupi"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Rancangan ini tidak akan dirakamkan kerana storan tidak mencukupi. Cuba padamkan beberapa rakaman sedia ada."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Storan hilang"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Berhenti merakam?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Kandungan yang dirakamkan akan disimpan."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Rakaman <xliff:g id="PROGRAMNAME">%1$s</xliff:g> akan dihentikan kerana wujud konflik dengan rancangan ini. Kandungan yang dirakamkan akan disimpan."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Rakaman dijadualkan tetapi wujud konflik"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Rakaman telah bermula tetapi wujud konflik"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> akan dirakamkan."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> sedang dirakamkan."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Sebahagian <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> tidak akan dirakamkan."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Sebahagian <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> dan <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> tidak akan dirakamkan."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Sebahagian <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> dan satu lagi jadual tidak akan dirakamkan."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other">Sebahagian <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> dan %3$d lagi jadual tidak akan dirakamkan.</item>
+ <item quantity="one">Sebahagian <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> dan %3$d lagi jadual tidak akan dirakamkan.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Apakah jenis rakaman yg anda ingin buat?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Berapa lama anda ingin merakam?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Sudah dijadualkan"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Rancangan yang sama telah dijadualkan akan dirakamkan pada <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Sudah dirakamkan"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Rancangan ini telah dirakamkan dan tersedia di pustaka DVR."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Rakaman siri telah dijadualkan"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> rakaman telah dijadualkan untuk <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> rakaman telah dijadualkan untuk <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> rakaman telah dijadualkan untuk <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> daripadanya tidak akan dirakamkan kerana berlaku konflik.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> rakaman telah dijadualkan untuk <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Rakaman ini tidak akan dijalankan kerana berlaku konflik.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> rakaman telah dijadualkan untuk <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episod siri ini dan siri yang lain tidak akan dirakamkan kerana berlaku konflik.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> rakaman telah dijadualkan untuk <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episod siri ini dan siri yang lain tidak akan dirakamkan kerana berlaku konflik.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> rakaman telah dijadualkan untuk <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 episod siri yang lain tidak akan dirakamkan kerana berlaku konflik.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> rakaman telah dijadualkan untuk <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 episod siri yang lain tidak akan dirakamkan kerana berlaku konflik.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> rakaman telah dijadualkan untuk <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episod siri yang lain tidak akan dirakamkan kerana berlaku konflik.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> rakaman telah dijadualkan untuk <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episod siri yang lain tidak akan dirakamkan kerana berlaku konflik.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Program yang dirakam tidak ditemui."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Rakaman yang berkaitan"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d rakaman</item>
+ <item quantity="one">%1$d rakaman</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> dialih keluar daripada jadual rakaman"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Sebahagian sahaja yang akan dirakamkan kerana konflik penala."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Tidak akan dirakamkan kerana konflik penala."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Belum ada lagi rakaman yang dijadualkan.\nAnda boleh menjadualkan rakaman daripada panduan rancangan."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d konflik rakaman</item>
+ <item quantity="one">%1$d konflik rakaman</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Tetapan siri"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Mulakan rakaman siri"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Hentikan rakaman siri"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Berhenti merakam siri?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Episod yang dirakamkan akan kekal tersedia dalam pustaka DVR."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Berhenti"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Tiada episod sedang dalam siaran."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Tiada episod yang tersedia.\nEpisod ini akan dirakamkan apabila sudah tersedia."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d minit)</item>
+ <item quantity="one">(%1$d minit) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Hari ini"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Esok"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Semalam"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> hari ini"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> esok"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Markah"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Rancangan yang Dirakamkan"</string>
+</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
deleted file mode 100644
index 816dee35..00000000
--- a/res/values-ms/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Kawalan main"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Saluran terbaru"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"Pilihan TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Pilihan PIP"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Kawalan main tidak tersedia untuk saluran ini"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Main atau jeda"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Mara laju"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Gulung semula"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Seterusnya"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Sebelumnya"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Panduan program"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Saluran baharu tersedia"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Buka <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Sari kata"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Mod paparan"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Hidupkan"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Matikan"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Berbilang audio"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Dptkn lg saluran"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Tetapan"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Sumber"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Silih"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Hidupkan"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Matikan"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Bunyi"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Utama"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Tetingkap PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Reka Letak"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Kanan bawah"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Kanan atas"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Kiri atas"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Kiri bawah"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Bersebelahan"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Saiz"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Besar"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Kecil"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Sumber input"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/kabel)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Maklumat program tiada"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Tiada maklumat"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Saluran disekat"</string>
- <string name="default_language" msgid="4122326459624337928">"Bahasa tidak diketahui"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Sari kata"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Dimatikan"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Sesuaikan format"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Tetapkan pilihan sari kata seluruh sistem"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Mod paparan"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Berbilang audio"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"stereo"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 keliling"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 keliling"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d saluran"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Sesuaikan saluran"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Pilih kumpulan"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Nyahpilih kumpulan"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Kumpulkan mengikut"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Sumber saluran"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Kumpulkan mengikut"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Rancangan ini disekat"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Rancangan ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Input tidak menyokong autoimbas"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Tidak dapat memulakan autoimbas untuk \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Tidak dapat memulakan pilihan sari kata untuk seluruh sistem."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d saluran ditambahkan</item>
- <item quantity="one">%1$d saluran ditambahkan</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Tiada saluran ditambahkan"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Penala"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Kawalan ibu bapa"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Hidup"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Dimatikan"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Saluran disekat"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Sekat semua"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Nyahsekat semua"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Saluran tersembunyi"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Sekatan program"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"Tukar PIN"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Sistem penilaian"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Penilaian"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Lihat sistem penilaian"</string>
- <string name="other_countries" msgid="8342216398676184749">"Negara lain"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Tiada"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Tiada"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Tiada"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Sekatan ketat"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"Sekatan sederhana"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Sekatan longgar"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Tersuai"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Kandungan sesuai untuk kanak-kanak"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Kandungan sesuai utk kanak-kanak berusia"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Kandungan yang sesuai untuk remaja"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Sekatan manual"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s &amp; subpenilaian"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Subpenilaian"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Masukkan PIN anda untuk menonton saluran ini"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Masukkan PIN anda untuk menonton rancangan ini"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Rancangan ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>. Masukkan PIN anda untuk menonton rancangan ini"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"Masukkan PIN anda"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Untuk menetapkan kawalan ibu bapa, buat PIN"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Masukkan PIN baharu"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"Sahkan PIN anda"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Masukkan PIN semasa anda"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">Anda telah memasukkan PIN yang salah sebanyak 5 kali.\nCuba lagi dalam masa <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> saat.</item>
- <item quantity="one">Anda telah memasukkan PIN yang salah sebanyak 5 kali.\nCuba lagi dalam masa <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> saat.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN itu salah. Cuba lagi."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Cuba lagi, PIN tidak sepadan"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Tetapan"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Sesuaikan senarai saluran"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Pilih saluran untuk panduan rancangan anda"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Sumber saluran"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Saluran baharu tersedia"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Kawalan ibu bapa"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Lesen sumber terbuka"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Lesen sumber terbuka"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Versi"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Untuk menonton saluran ini, tekan Kanan dan masukkan PIN anda"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Untuk menonton rancangan ini, tekan Kanan dan masukkan PIN anda"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Rancangan ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>.\nUntuk menonton rancangan ini, tekan Kanan, kemudian masukkan PIN anda."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Untuk menonton saluran ini, gunakan apl lalai TV Langsung."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Untuk menonton program ini, gunakan apl lalai TV Langsung."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Atur cara ini telah dinilai <xliff:g id="RATING">%1$s</xliff:g>.\nUntuk menonton program ini, gunakan apl lalai TV Langsung."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Rancangan disekat"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Rancangan ini diberi rating <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audio sahaja"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Isyarat lemah"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Tiada sambungan Internet"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Saluran ini tidak dapat dimainkan hingga <xliff:g id="END_TIME_1">%1$s</xliff:g> kerana saluran lain sedang dirakamkan. \n\nTekan Kanan untuk melaraskan jadual rakaman.</item>
- <item quantity="one">Saluran ini tidak dapat dimainkan hingga <xliff:g id="END_TIME_0">%1$s</xliff:g> kerana saluran lain sedang dirakamkan. \n\nTekan Kanan untuk melaraskan jadual rakaman.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Tiada tajuk"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Saluran disekat"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Baharu"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Sumber"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d saluran</item>
- <item quantity="one">1$d saluran</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Tiada saluran yang tersedia"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Baharu"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Tidak disediakan"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Dapatkan lebih banyak sumber"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Semak imbas apl yang menawarkan saluran langsung"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Sumber saluran yang baharu tersedia"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Sumber saluran baharu mempunyai saluran untuk ditawarkan.\nSediakan saluran sekarang atau lakukannya kemudian dalam tetapan sumber saluran."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Sediakan sekarang"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"OK"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307"><b>"Tekan PILIH"</b>" untuk mengakses menu TV."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"Input TV tidak ditemui"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"Tidak menemui input TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP tidak disokong"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Tiada input tersedia yang boleh ditunjukkan dengan PIP"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Jenis penala tidak sesuai; Sila lancarkan apl Saluran Langsung untuk input TV jenis penala."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Penalaan gagal"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Tiada apl ditemui untuk mengendalikan tindakan ini."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Semua saluran sumber disembunyikan.\nPilih sekurang-kurangnya satu saluran untuk ditonton."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Video ini tidak tersedia tanpa dijangka"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"Kekunci BACK adalah untuk peranti yang tersambung. Tekan butang HOME untuk keluar."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Saluran Langsung memerlukan kebenaran untuk membaca penyenaraian TV."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Sediakan sumber anda"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Saluran langsung menggabungkan pengalaman saluran TV tradisional dengan saluran penstriman yang disediakan oleh apl. \n\nMulakan dengan menyediakan sumber saluran yang sudah dipasang. Selain itu, semak imbas Gedung Google Play untuk mendapatkan lebih banyak apl yang menawarkan saluran langsung."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Rakaman &amp; jadual"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minit"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minit"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 jam"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 jam"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Terbaharu"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Dijadualkan"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Siri"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Lain-lain"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Saluran ini tidak boleh dirakam."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Rancangan ini tidak boleh dirakam."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> telah dijadualkan untuk dirakamkan"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Merakam <xliff:g id="PROGRAMNAME">%1$s</xliff:g> mulai sekarang hingga <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Jadual penuh"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">%1$d hari seterusnya</item>
- <item quantity="one">%1$d hari seterusnya</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d minit</item>
- <item quantity="one">%1$d minit</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d rakaman baharu</item>
- <item quantity="one">%1$d rakaman baharu</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d rakaman</item>
- <item quantity="one">%1$d rakaman</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d rakaman dijadualkan</item>
- <item quantity="one">%1$d rakaman dijadualkan</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Tonton"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Mainkan dari mula"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Sbg smula prses main"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"Padam"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Padam rakaman"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Sambung semula"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Musim <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Lihat jadual"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Baca lagi"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Padam rakaman"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"Pilih episod yang anda ingin padamkan. Episod ini tidak boleh dipulihkan setelah dipadamkan."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Tiada rakaman untuk dipadamkan."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Pilih episod yg sudah ditonton"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Pilih semua episod"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Nyahpilih semua episod"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> daripada <xliff:g id="DURATION">%2$d</xliff:g> minit tontonan"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> daripada <xliff:g id="DURATION">%2$d</xliff:g> saat tontonan"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Belum pernah ditonton"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%1$d daripada %2$d episod dipadamkan</item>
- <item quantity="one">%1$d daripada %2$d episod dipadamkan</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Keutamaan"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Tertinggi"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Terendah"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Nombor <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Saluran"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Sebarang"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Pilih keutamaan"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Apabila ada terlalu banyak rancangan yang ingin dirakamkan secara serentak, rancangan yang berkeutamaan lebih tinggi sahaja yang akan dirakamkan."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Simpan"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Rakaman bersifat sekali sahaja mendapat keutamaan tertinggi"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Batal"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Batal"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Lupakan"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"Berhenti"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Lihat jadual rakaman"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Program ini sahaja"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"sekarang - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"Keseluruhan siri..."</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Jadualkan juga"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Sebaliknya rakamkan yang ini"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Batalkan rakaman ini"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Tonton sekarang"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Boleh rakam"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Rakaman dijadualkan"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Konflik rakaman"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Merakam"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Perakaman gagal"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Membaca rancangan untuk membuat jadual rakaman"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Membaca rancangan"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR memerlukan storan yang lebih besar"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Anda boleh merakam rancangan menggunakan DVR. Walau bagaimanapun storan pada peranti anda kini tidak mencukupi untuk DVR berfungsi. Sila sambungkan pemacu luaran <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB atau lebih besar dan ikut langkah untuk memformat pemacu itu sebagai storan peranti."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Storan hilang"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Beberapa storan yang digunakan oleh DVR telah hilang. Sila sambungkan pemacu luaran yang anda gunakan sebelum ini untuk mendayakan semula DVR. Secara alternatif, anda boleh memilih untuk melupakan storan jika storan itu tidak lagi tersedia."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Lupakan storan?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Semua kandungan dan jadual anda yang dirakamkan akan hilang."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Berhenti merakam?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Kandungan yang dirakamkan akan disimpan."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Rakaman dijadualkan tetapi wujud konflik"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Rakaman telah bermula tetapi wujud konflik"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> akan dirakamkan."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> sedang dirakamkan."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Sebahagian <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> tidak akan dirakamkan."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Sebahagian <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> dan <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> tidak akan dirakamkan."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Sebahagian <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> dan satu lagi jadual tidak akan dirakamkan."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other">Sebahagian <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> dan %3$d lagi jadual tidak akan dirakamkan.</item>
- <item quantity="one">Sebahagian <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> dan %3$d lagi jadual tidak akan dirakamkan.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Apakah jenis rakaman yg anda ingin buat?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Berapa lama anda ingin merakam?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Sudah dijadualkan"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Rancangan yang sama telah dijadualkan akan dirakamkan pada <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Sudah dirakamkan"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Rancangan ini telah dirakamkan dan tersedia di pustaka DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Program yang dirakam tidak ditemui."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Rakaman yang berkaitan"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Tiada perihalan program)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d rakaman</item>
- <item quantity="one">%1$d rakaman</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> dialih keluar daripada jadual rakaman"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Sebahagian sahaja yang akan dirakamkan kerana konflik penala."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Tidak akan dirakamkan kerana konflik penala."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Belum ada lagi rakaman yang dijadualkan.\nAnda boleh menjadualkan rakaman daripada panduan rancangan."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d konflik rakaman</item>
- <item quantity="one">%1$d konflik rakaman</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Tetapan siri"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Mulakan rakaman siri"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Hentikan rakaman siri"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Berhenti merakam siri?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Episod yang dirakamkan akan kekal tersedia dalam pustaka DVR."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Berhenti"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Tiada episod yang tersedia.\nEpisod ini akan dirakamkan apabila sudah tersedia."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d minit)</item>
- <item quantity="one">(%1$d minit) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Hari ini"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Esok"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Semalam"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> hari ini"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> esok"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Markah"</string>
-</resources>
diff --git a/res/values-my-v23/strings.xml b/res/values-my-rMM-v23/strings.xml
index 015247d8..015247d8 100644
--- a/res/values-my-v23/strings.xml
+++ b/res/values-my-rMM-v23/strings.xml
diff --git a/res/values-my/arrays.xml b/res/values-my-rMM/arrays.xml
index e302ceac..e302ceac 100644
--- a/res/values-my/arrays.xml
+++ b/res/values-my-rMM/arrays.xml
diff --git a/res/values-my/rating_system_strings.xml b/res/values-my-rMM/rating_system_strings.xml
index 153ad407..153ad407 100644
--- a/res/values-my/rating_system_strings.xml
+++ b/res/values-my-rMM/rating_system_strings.xml
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
new file mode 100644
index 00000000..c6475401
--- /dev/null
+++ b/res/values-my-rMM/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"မိုနို"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"စတီရီယို"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Play ထိန်းချုပ်မှုများ"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"ချာနယ်များ"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"TV ရွေးစရာများ"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"ဤလိုင်းအတွက် အဖွင့်ထိန်းချုပ်ခြင်းများ မရနိုင်ပါ"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ဖွင့်ပါ သို့မဟုတ် ခဏရပ်ပါ"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ရှေ့သို့ အမြန်သွားရန်"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"ပြန်ရစ်ရန်"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"ရှေ့သို့"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"ယခင်"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"အစီအစဉ် လမ်းညွှန်"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"ရရှိနိုင်သည့် ချန်နယ်အသစ်များ"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ဖွင့်ရန်"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"စာတမ်းထိုးများ"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"မြင်ကွင်း မုဒ်"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"အသံစုံ"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"နောက်ထပ်ချန်နယ်များ ရယူရန်"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"ဆက်တင်များ"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"တီဗီ (ဧရီယာတိုင်/ကြိုး)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"အစီအစဉ် အချက်အလက်များ မရှိ"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"သတင်းအချက်အလက် မရှိပါ"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"ပိတ်ဆို့ ချာနယ်"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"အမည်မသိဘာသာစကား"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"စာတန်းထိုး %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"စာတမ်းထိုးများ"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ပိတ်ထား"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"စိတ်ကြိုက်ပုံစံချရန်"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"စာတမ်းထိုးအတွက် ရွေးစရာများ သတ်မှတ်ရန်"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"မြင်ကွင်း မုဒ်"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"အသံစုံ"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"မိုနို"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"စတီရီယို"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"၅.၁ ပတ်လည်"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"၇.၁ ပတ်လည်"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ချာနယ်"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ချာနယ်စာရင်း စိတ်တိုင်းကျ"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"အုပ်စု ရွေးရန်"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"အုပ်စု ရွေးမှု ဖျက်ရန်"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"အုပ်စုဖွဲ့မှု"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ချာနယ် ရင်းမြစ်များ"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"အုပ်စုဖွဲ့မှု"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"ဤအစီအစဉ်အား ပိတ်ဆို့ထားသည်။"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"ဤအစီအစဉ်ကို အဆင့်မသတ်မှတ်ရသေးပါ"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"ဤအစီအစဉ်သည် အဆင့် <xliff:g id="RATING">%1$s</xliff:g> ရှိ၏"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"ထည့်သွင်းမှုက အော်တို-စကင် ပံ့ပိုးမပေး"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' အတွက် အော်တို−စကင် မစနိုင်ပါ"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"ပိတ်ထားသည့် စာတန်းများ အတွက် စနစ်ဆိုင်ရာ ဦးစားပေးမှုများကို စတင်မရပါ။"</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">ချန်နယ် %1$d ခုပေါင်းထည့်ပြီးပါပြီ</item>
+ <item quantity="one">ချန်နယ် %1$d ခုပေါင်းထည့်ပြီးပါပြီ</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"ချာနယ်များ ထည့်မထား"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"မိဘ ထိန်းချုပ်မှု"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ဖွင့်ရန်"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ပိတ်ရန်"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"ချာနယ်များ ပိတ်ရန်"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"အားလုံး ပိတ်ဆို့ရန်"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"အားလုံး ပြန်ဖွင့်ရန်"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"ဝှက်ထားသည့် ချာနယ်များ"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"အစီအစဉ်ကန့်သတ်ချက်"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN ပြောင်းရန်"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"အဆင့်ပေး စနစ်များ"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"အမှတ်ပေးမှုများ"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"အဆင့်ပေးစနစ်များပြပါ"</string>
+ <string name="other_countries" msgid="8342216398676184749">"အခြားနိုင်ငံများ"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"မရှိ"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"မရှိ"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"အဆင့် သတ်မှတ်မထားပါ"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"မစိစစ်သောအစီအစဉ်များ ပိတ်ရန်"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"မရှိ"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"ကန့်သတ်ချက်မြှင့်ရန်"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"ကန့်သတ်ချက်များ အလတ်"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"ကန့်သတ်ချက်များ နိမ့်"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"စိတ်တိုင်းကျ"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"ကလေးများအတွက် သင့်တော်သည့် အကြောင်းအရာ"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"ကလေးကြီးများ အတွက် သင့်သော အကြောင်းအရာ"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"ဆယ်ကျော်သက်များ အတွက် ဆီလျော်သည့် အကြောင်းအရာ"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"လက်ဖြင့် သတ်မှတ်ခဲ့သည့် ကန့်သတ်ချက်များ"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s နှင့် ထပ်ဆင့်မှတ်"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"ထပ်ဆင့်-အမှတ်ပေးမှု"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ဒီချာနယ်ကို ကြည့်ရန် သင့် PIN ရိုက်ထည့်ပါ"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"ဒီအစီအစဉ်ကို ကြည့်ရန် သင့် PIN ရိုက်ထည့်ပါ"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ဤပရိုဂရမ်ကို <xliff:g id="RATING">%1$s</xliff:g> အဆင့်သတ်မှတ်ထားပါသည်။ ဤပရိုဂရမ်ကို ကြည့်ရှုရန် သင့်ပင်နံပါတ်ကို ထည့်ပါ"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"ဤအစီအစဉ်ကို အဆင့်မသတ်မှတ်ရသေးပါ။ ဤအစီအစဉ်ကိုကြည့်ရန် သင်၏ ပင်နံပါတ် ထည့်ပါ။"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"သင့် PIN ရိုက်ထည့်ပါ"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"မိဘ ထိန်းချုပ်မှုကို သတ်မှတ်ရန်၊ PIN ကို ဖန်တီးပါ"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"PIN အသစ်ကို ထည့်သွင်းရန်"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"သင့် PIN ကို အတည်ပြုပါ"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"သင့် လက်ရှိ PIN ရိုက်ထည့်ပါ"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">မှားယွင်းသည့်ပင်နံပါတ် ၅ ကြိမ်သင်ထည့်သွင်းခဲ့သည်။\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်လုပ်ကြည့်ပါ။</item>
+ <item quantity="one">မှားယွင်းသည့်ပင်နံပါတ် ၅ ကြိမ်သင်ထည့်သွင်းခဲ့သည်။\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်လုပ်ကြည့်ပါ။</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"ထို PIN မှာ မှားနေသည်။ ထပ်ကြိုးစားပါ။"</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"PIN မှာ မတိုက်ဆိုင်ပါ၊ ထပ်ပြီး စမ်းပါ။"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"စာတိုက်ကုဒ်ကို ထည့်ပါ။"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"TV ချန်နယ်များအတွက် ပြီးပြည့်စုံသည့် အစီအစဉ်များကို ပံ့ပိုးပေးရန် Live TV က စာတိုက်ကုဒ်ကိုသုံးပါမည်။"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"စာတိုက်ကုဒ်ကို ထည့်ပါ"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"စာတိုက်သင်္က​ေတ မမှန်ပါ"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"ဆက်တင်များ"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ချန်နယ်စာရင်းကို စိတ်တိုင်းကျပြုပြင်ရန်"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"သင့်ပရိုဂရမ်လမ်းညွှန်အတွက် ချန်နယ်များရွေးချယ်ပါ"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ချန်နယ် အရင်းအမြစ်များ"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"ချန်နယ်အသစ်များ ရနိုင်ပါသည်"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"မိဘ ထိန်းချုပ်မှု"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"အချိန်ရွှေ့ဆိုင်းခြင်း"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"ကြည့်နေရင်း မှတ်တမ်းတင်ထားပါက တိုက်ရိုက်အစီအစဉ်များကို ခေတ္တရပ်နားနိုင်သလို ပြန်ရစ်ကြည့်နိုင်ပါသည်။\nသတိ− ဤသို့ပြုလုပ်လျှင် သိမ်းဆည်းမှုများစွာ အသုံးပြုခြင်းကြောင့် စက်အတွင်း သိမ်းဆည်းရန်နေရာ၏ သက်တမ်းကို လျော့ကျစေနိုင်ပါသည်။"</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"အခမဲ့အရင်းအမြစ်လိုင်စင်များ"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"အကြံပြုချက် ပေးပို့ပါ"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ဗားရှင်း"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"ဤချာနယ်ကို ကြည့်ရန်၊ ညာဘက် နှိပ်ပြီး PIN ရိုက်ထည့်ပါ"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"ဤအစီအစဉ်ကို ကြည့်ရန်၊ ညာဘက် နှိပ်ပြီး PIN ရိုက်ထည့်ပါ"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"ဤအစီအစဉ်ကို အဆင့်မသတ်မှတ်ရသေးပါ။\nဤအစီအစဉ်ကို ကြည့်ရန် ညာဘက်သို့ ဖိပြီး ပင်နံပါတ် ထည့်ပါ"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"ဤအစီအစဉ်သည် အဆင့် <xliff:g id="RATING">%1$s</xliff:g> ရှိ၏။ \nဤအစီအစဉ်အား ကြည့်ရန်၊ ညာဘက် နှိပ်ပြီး PIN ရိုက်ထည့်ပါ။"</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ဤချန်နယ်ကိုကြည့်ရန်၊ မူလတိုက်ရိုက်လွှင့်သည့်တီဗွီအပ်ဖ်ကို အသုံးပြုပါ။"</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"အစီအစဉ်ကိုကြည့်ရန်၊ မူလတိုက်ရိုက်လွှင့်သည့် တီဗွီအပ်ဖ်ကိုအသုံးပြုပါ။"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"ဤအစီအစဉ်ကို အဆင့်မသတ်မှတ်ရသေးပါ။\nဤအစီအစဉ်ကို ကြည့်ရန် မူလ တိုက်ရိုက်လွှင့်နေသော TV အက်ပ်ကို အသုံးပြုပါ။"</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ဤအစီအစဉ်ကို <xliff:g id="RATING">%1$s</xliff:g> သတ်မှတ်ထားသည်။ \nဤအစီအစဉ်ကိုကြည့်ရန်၊ မူလတိုက်ရိုက်လွှင့်သည့် တီဗွီအပ်ဖ်ကိုအသုံးပြုပါ။"</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"အစီအစဉ်ကို ပိတ်ဆို့ထား"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"ဤအစီအစဉ်ကို အဆင့်မသတ်မှတ်ရသေးပါ"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ဤအစီအစဉ်သည် အဆင့် <xliff:g id="RATING">%1$s</xliff:g> ရှိ၏"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"အသံ သီးသန့်"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"လှိုင်းဆွဲအားနည်းသည်"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"အင်တာနက်ချိတ်ဆက်မှု မရှိပါ"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">အခြားချန်နယ်လိုင်းများကို ဖမ်းယူနေသောကြောင့် ဤချန်နယ်လိုင်းကို <xliff:g id="END_TIME_1">%1$s</xliff:g> အထိ ဖွင့်၍ရမည်မဟုတ်ပါ။ \n\nဖမ်းယူခြင်းအချိန်ဇယားကို ချိန်ညှိရန် ညာဘက်ကိုနှိပ်ပါ။</item>
+ <item quantity="one">အခြားချန်နယ်လိုင်းကို ဖမ်းယူနေသောကြောင့် ဤချန်နယ်လိုင်းကို <xliff:g id="END_TIME_0">%1$s</xliff:g> အထိ ဖွင့်၍ရမည်မဟုတ်ပါ။ \n\nဖမ်းယူခြင်းအချိန်ဇယားကို ချိန်ညှိရန် ညာဘက်ကိုနှိပ်ပါ။</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"ခေါင်းစဉ် မပါ"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ချာနယ် ပိတ်ဆို့ထား"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"အသစ်"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"အရင်းအမြစ်များ"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d ချန်နယ်များ</item>
+ <item quantity="one">%1$d ချန်နယ်</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"လိုင်းမရှိပါ"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"အသစ်"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"စဖွင့်မသတ်မှတ်ရသေးပါ"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"နောက်ထပ် အရင်းအမြစ်များ ရယူပါ"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"တိုက်ရိုက်လွှင့်ချန်နယ်များရှိသည့် အက်ပ်များကို ရှာပါ"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"ချန်နယ် အရင်းအမြစ် အသစ်များ ရှိပါသည်"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"ချန်နယ် အရင်းအမြစ် အသစ်များမှ ကမ်းလှမ်းလိုသည့် ချန်နယ်များ ရှိပါသည်။ \n၎င်းတို့ကို ယခု စဖွင့်သတ်မှတ်ပါ၊ သို့မဟုတ် နောက်ပိုင်းတွင် ချန်နယ် အရင်းအမြစ်များ ဆက်တင်ထဲတွင် သတ်မှတ်ပါ။"</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"ယခု စဖွင့်သတ်မှတ်ပါ"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"အိုကေ၊ ရပါပြီ"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>" ရွေးချယ်ပါအားနှိပ်ပြီး"</b>" တီဗီမန်နယူးကိုဝင်ရောက်ကြည့်ရှုပါ။"</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"တီဗီ ထည့်သွင်းမှု ရှာမတွေ့ပါ။"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"တီဗီ ထည့်သွင်းမှု ရှာမတွေ့နိုင်ပါ။"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"သင့်တော်သည့် တျူနာ အမျိုးအစား မဟုတ်ပါ။ တီဗွီ အဝင်ပေါက်အတွက် တိုက်ရိုက်လွှင့် ချန်နယ်များ အက်ပ်အား ဖွင့်ပါ။"</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ညှိမှု မအောင်မြင်ပါ"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"ဤလုပ်ဆောင်ချက်ကို ကိုင်တွယ်နိုင်သည့် အက်ပ်မရှိပါ။"</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"ရင်းမြစ် ချာနယ် အားလုံးကို ဝှက်ထားသည်။ \n ကြည့်ရန် အနည်းဆုံး ချာနယ် တစ်ခုကို ရွေးပါ။"</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ဗီဒီယို မမျှော်လင့်ဘဲ မရရှိနိုင်ပါ။"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"BACK ကီးသည် ချိတ်ဆက် စက်ကိရိယာ အတွက်ဖြစ်၏။ ထွက်ရန် HOME ခလုတ်ကို နှိပ်ပါ။"</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"တီဗီစာရင်းများကို ဖတ်ရှုရန် တိုက်ရိုက်ထုတ်လွှင့်သောချန်နယ်လိုင်းများတွင် ခွင့်ပြူချက်လိုအပ်သည်။"</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"သင့်သတင်းအရင်းအမြစ်များကို တပ်ဆင်ပါ"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"တိုက်ရိုက်လွှင့်သည့် ချန်နယ်များသည် သမားရိုးကျ TV ချန်နယ်များနှင့် အက်ပ်မှလွှင့်ပေးသည့် ချန်နယ်များကို ပူးပေါင်းထားသည့်ခံစားမှုပင်ဖြစ်သည်။ \n\nထည့်သွင်းပြီးသား ချန်နယ်အရင်းမြစ်များကို တပ်ဆင်ခြင်းဖြင့် စတင်လိုက်ပါ။ သို့မဟုတ် တိုက်ရိုက်လွှင့်သည့် ချန်နယ်များပါဝင်သည့် နောက်ထပ်အက်ပ်များအတွက် Google Play Store တွင်ရှာပါ။"</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"ဖမ်းယူခြင်းနှင့် အချိန်ဇယားမျာ"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"၁၀ မိနစ်"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"၃၀ မိနစ်"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"၁ နာရီ"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"၃ နာရီ"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"မကြာမီက"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"စီစဉ်ထားသော"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"စီးရီး"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"အခြား"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ချန်နယ်ကို မှတ်တမ်းတင်၍မရပါ။"</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"ပရိုဂရမ်ကို မှတ်တမ်းတင်၍ မရပါ။"</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ဖမ်းယူရန် စီစဉ်ထားပါသည်"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ယခုချိန်မှ <xliff:g id="ENDTIME">%2$s</xliff:g> အထိ ရိုက်ကူးမည်"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"အချိန်ဇယားအပြည့်အစုံ"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">နောက်ထပ် %1$d ရက်</item>
+ <item quantity="one">နောက်ထပ် %1$d ရက်</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d မိနစ်</item>
+ <item quantity="one">%1$d မိနစ်</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">ရိုက်ကူးမှုအသစ် %1$d ခု</item>
+ <item quantity="one">ရိုက်ကူးမှုအသစ် %1$d ခု</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">ရိုက်ကူးမှု %1$d ခု</item>
+ <item quantity="one">ရိုက်ကူးမှု %1$d ခု</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">ရိုက်ကူးရန် အစီအစဉ်%1$dခု</item>
+ <item quantity="one">ရိုက်ကူးရန် အစီအစဉ်%1$dခု</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"ကူးယူမှု ပယ်ဖျက်မည်"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"ကူးယူမှု ရပ်မည်"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"ကြည့်ရန်"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"အစမှနေ၍ ဖွင့်ရန်"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"ဆက်ဖွင့်ရန်"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"ဖျက်ရန်"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"မှတ်တမ်းတင်ထားသည်ကို ဖျက်ရန်"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"ဆက်ဖွင့်ရန်"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"အတွဲ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"အချိန်ဇယားကိုကြည့်ရန်"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"နောက်ထပ် ဖတ်ရန်"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ရုပ်သံကူးယူမှုဖျက်ပါ"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"သင်ဖျက်ပစ်လိုသော အခန်းဆက်များကို ရွေးပါ။ ဖျက်လိုက်သည်နှင့် ၎င်းတို့ကို ပြန်ဆည်ယူ၍ မရတော့ပါ။"</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"ဖျက်ရန် ရုပ်သံဖမ်းယူမှုများ မရှိတော့ပါ။"</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"ကြည့်ပြီးသောအခန်းဆက်များရွေးပါ"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"အခန်းဆက်များအားလုံးကို ရွေးပါ"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"အခန်းဆက်များအားလုံးကို ဖျက်ပါ"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> မိနစ်ရှိသည့်အနက် <xliff:g id="WATCHED">%1$d</xliff:g> မိနစ် ကြည့်ပြီးသွားပြီ"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> စက္ကန့်ရှိသည့်အနက် <xliff:g id="WATCHED">%1$d</xliff:g> စက္ကန့် ကြည့်ပြီးသွားပြီ"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"လုံးဝမကြည့်ရသေးပါ"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">အခန်းဆက် %2$d ခုအနက် %1$d ခုကို ဖျက်လိုက်သည်</item>
+ <item quantity="one">အခန်းဆက် %2$d ခုအနက် %1$d ခုကို ဖျက်လိုက်သည်</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ဦးစားပေးမှု"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"အမြင့်ဆုံး"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"အနိမ့်ဆုံး"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"နံပါတ် <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ချန်နယ်များ"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"မည်သည့်အရာမဆို"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"ဦးစားပေးမှုကို ရွေးရန်"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"တစ်ချိန်တည်းတွင် ဖမ်းယူရမည့်အစီအစဉ် များပြားလွန်းသည့်အခါ ဦးစားပေးမှု ပိုမိုမြင့်မားသည့် အစီအစဉ်များကိုသာ ဖမ်းယူသွားပါမည်။"</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"သိမ်းရန်"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"တစ်ကြိမ်တစ်ခါတည်း ဖမ်းယူခြင်းသည် ဦးစားပေးမှုအမြင့်ဆုံးဖြစ်သည်"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"ရပ်ရန်"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ဖမ်းယူခြင်းအချိန်ဇယားကို ကြည့်ရန်"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"ဤအစီအစဉ် တစ်ခုတည်း"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ယခု - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"အခန်းဆက်များ တစ်တွဲလုံး…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"မည်သို့ပင်ဖြစ်စေ စီစဉ်ရန်"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"၎င်းအစား ဤတစ်ခုကို ဖမ်းယူပါ"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ဤဖမ်းယူမှုကို ပယ်ဖျက်ရန်"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"ယခုကြည့်ရန်"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"ရုပ်သံရိုက်ကူးမှုများ ဖျက်ပါ..."</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"ရိုက်ကူးနိုင်သည်"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ရိုက်ကူးရေးအတွက် စီစဉ်ထားပါသည်"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ရိုက်ကူးရေးအစီအစဉ်တိုက်နေပါသည်"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ဖမ်းယူနေသည်"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ဖမ်းယူခြင်း မအောင်မြင်ပါ"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"ပရိုဂရမ်များကို ဖတ်နေသည်"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"မကြာသေးမီက ရိုက်ကူးမှုများကို ကြည့်ပါ"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ကူးယူမှု မပြီးဆုံးခဲ့ပါ။"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> နှင့် <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> တို့ကို ကူးယူမှု မပြီးဆုံးခဲ့ပါ။"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>၊ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> နှင့် <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> တို့ကို ကူးယူမှု မပြီးဆုံးခဲ့ပါ။"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"သိုလှောင်ခန်း လုံလောက်မှု မရှိသည့်အတွက် <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ပြီးဆုံးအောင် မကူးယူနိုင်ခဲ့ပါ။"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"သိုလှောင်ခန်း လုံလောက်မှု မရှိသည့်အတွက် <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> နှင့် <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> တို့ကို ပြီးစီးအောင် မကူးယူနိုင်ခဲ့ပါ။"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"သိုလှောင်ခန်း လုံလောက်မှု မရှိသည့်အတွက် <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>၊ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> နှင့် <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> တို့ကို ပြီးစီးအောင် မကူးယူနိုင်ခဲ့ပါ။"</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR သည် နောက်ထပ်သိုလှောင်ရန်နေရာလွတ် လိုအပ်နေသည်"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"အစီအစဉ်များကို DVR နှင့် ဖမ်းယူသိမ်းဆည်းထားနိုင်ပါသည်။ သို့သော် DVR ကို အသုံးပြုနိုင်ရန် သင့်စက်ပစ္စည်းတွင် လုံလောက်သော နေရာလွတ် လောလောဆယ်မရှိပါ။ <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>ဂစ်ဂါဘိုက် သို့မဟုတ် ၎င်းနှင့်အထက်ရှိသော ပြင်ပသိုလှောင်ကိရိယာနှင့် ချိတ်ဆက်ပြီး ၎င်းကို သိုလှောင်ခန်းစက်ပစ္စည်းအဖြစ် ပြင်ဆင်သတ်မှတ်ရန် ညွှန်ကြားချက်များအတိုင်း လိုက်နာပါ။"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"သိုလှောင်ခန်း မလုံလောက်ပါ"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"သိုလှောင်ခန်း လုံလောက်မှုမရှိသည့်အတွက် ဤအစီအစဉ်ကို ရိုက်ကူးမည်မဟုတ်ပါ။ လက်ရှိရိုက်ကူးချက်အချို့ကို ဖျက်ကြည့်ပါ။"</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"သိုလှောင်မှုများ ပျောက်ဆုံးနေခြင်း"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ရိုက်ကူးခြင်းကို ရပ်လိုပါသလား။"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ဖမ်းယူထားသည့် အကြောင်းအရာကို သိမ်းဆည်းထားပါမည်။"</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ဖမ်းယူခြင်းသည် ဤပရိုဂရမ်နှင့် ပဋိပက္ခများ ဖြစ်နေသောကြောင့် ၎င်းသည် ရပ်တန့်သွားပါမည်။ ဖမ်းယူထားသည့် အကြောင်းအရာကို သိမ်းဆည်းသွားပါမည်။"</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ဖမ်းယူရန် စီစဉ်ထားသော်လည်း အချိန်ဇယားတိုက်နေပါသည်"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ဖမ်းယူမှုကို စတင်လိုက်ပါပြီ။ သို့သော် အချိန်ဇယားတိုက်နေပါသည်"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ဖမ်းယူသွားပါမည်။"</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ကို ဖမ်းယူနေပါသည်။"</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ၏ အချို့အစိတ်အပိုင်းများကို ဖမ်းယူသွားမည် မဟုတ်ပါ။"</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> နှင့် <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> တို့၏ အချို့အစိတ်အပိုင်းများကို ဖမ်းယူသွားမည် မဟုတ်ပါ။"</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>၊ <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> တို့၏ အချို့အစိတ်အပိုင်းများနှင့် နောက်ထပ်အစီအစဉ် တစ်ခုကို ဖမ်းယူသွားမည် မဟုတ်ပါ။"</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>၊ <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> တို့၏ အချို့အစိတ်အပိုင်းများနှင့် နောက်ထပ်အစီအစဉ် %3$d ခုတို့ကို ဖမ်းယူသွားမည် မဟုတ်ပါ။</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>၊ <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> တို့၏ အချို့အစိတ်အပိုင်းများနှင့် နောက်ထပ်အစီအစဉ် %3$d ခုတို့ကို ဖမ်းယူသွားမည် မဟုတ်ပါ။</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"သင်ဘယ်ရုပ်/သံကို ဖမ်းယူလိုပါသလဲ။"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"ဘယ်လောက်ကြာကြာ ဖမ်းယူလိုပါသနည်း။"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"စီစဉ်ပြီးပါပြီ"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"တူညီသည့် ပရိုဂရမ်ကို <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> ၌ ဖမ်းယူရန် စီစဉ်ထားပြီး ဖြစ်ပါသည်။"</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ဖမ်းယူပြီးပါပြီ"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ဤပရိုဂရမ်ကို ဖမ်းယူပြီးပါပြီ။ ၎င်းကို DVR စာကြည့်တိုက်တွင် ကြည့်ရှုနိုင်ပါသည်။"</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"စီးရီးများကို ဖမ်းယူခြင်းကို စီစဉ်ထားပါသည်"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">ရိုက်ကူးမှု <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ခုကို <xliff:g id="SERIESNAME_3">%2$s</xliff:g> အတွက် စီစဉ်ထားပါသည်။</item>
+ <item quantity="one">ရိုက်ကူးမှု <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ခုကို <xliff:g id="SERIESNAME_1">%2$s</xliff:g> အတွက် စီစဉ်ထားပါသည်။</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">ရိုက်ကူးမှု <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ခုကို <xliff:g id="SERIESNAME_3">%2$s</xliff:g> အတွက် စီစဉ်ထားပါသည်။ ပဋိပက္ခများ ရှိနေသဖြင့် ၎င်းတို့အနက်မှ <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> ခုကို ကူးယူသွားမည် မဟုတ်ပါ။</item>
+ <item quantity="one">ရိုက်ကူးမှု <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ခုကို <xliff:g id="SERIESNAME_1">%2$s</xliff:g> အတွက် စီစဉ်ထားပါသည်။ ပဋိပက္ခများ ရှိနေသဖြင့် ၎င်းကို ကူးယူသွားမည် မဟုတ်ပါ။</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">ရိုက်ကူးမှု <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ခုကို <xliff:g id="SERIESNAME_4">%2$s</xliff:g> အတွက် စီစဉ်ထားပါသည်။ ပဋိပက္ခများ ရှိနေသဖြင့် ဤစီးရီးနှင့် အခြားစီးရီးများ၏ ဇာတ်လမ်းပိုင်း <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ပိုင်းကို ကူးယူသွားမည်မဟုတ်ပါ။</item>
+ <item quantity="one">ရိုက်ကူးမှု <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ခုကို <xliff:g id="SERIESNAME_1">%2$s</xliff:g> အတွက် စီစဉ်ထားပါသည်။ ပဋိပက္ခများ ရှိနေသဖြင့် ဤစီးရီးနှင့် အခြားစီးရီးများ၏ ဇာတ်လမ်းပိုင်း <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ပိုင်းကို ကူးယူသွားမည်မဟုတ်ပါ။</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">ရိုက်ကူးမှု <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ခုကို <xliff:g id="SERIESNAME_3">%2$s</xliff:g> အတွက် စီစဉ်ထားပါသည်။ ပဋိပက္ခများ ရှိနေသဖြင့် အခြားစီးရီးများ၏ ဇာတ်လမ်းပိုင်း ၁ ပိုင်းကို ကူးယူသွားမည်မဟုတ်ပါ။</item>
+ <item quantity="one">ရိုက်ကူးမှု <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ခုကို <xliff:g id="SERIESNAME_1">%2$s</xliff:g> အတွက် စီစဉ်ထားပါသည်။ ပဋိပက္ခများ ရှိနေသဖြင့် အခြားစီးရီးများ၏ ဇာတ်လမ်းပိုင်း ၁ ပိုင်းကို ကူးယူသွားမည်မဟုတ်ပါ။</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">ရိုက်ကူးမှု <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ခုကို <xliff:g id="SERIESNAME_4">%2$s</xliff:g> အတွက် စီစဉ်ထားပါသည်။ ပဋိပက္ခများ ရှိနေသဖြင့် အခြားစီးရီးများ၏ ဇာတ်လမ်းပိုင်း <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ပိုင်းကို ကူးယူသွားမည်မဟုတ်ပါ။</item>
+ <item quantity="one">ရိုက်ကူးမှု <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ခုကို <xliff:g id="SERIESNAME_1">%2$s</xliff:g> အတွက် စီစဉ်ထားပါသည်။ ပဋိပက္ခများ ရှိနေသဖြင့် အခြားစီးရီးများ၏ ဇာတ်လမ်းပိုင်း <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ပိုင်းကို ကူးယူသွားမည်မဟုတ်ပါ။</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"ရိုက်ကူးထားသည့်ပရိုဂရမ်ကို မတွေ့ပါ။"</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ဆက်စပ်နေသည့် ရိုက်ကူးမှုများ"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">ရိုက်ပြီးသား %1$d ခု</item>
+ <item quantity="one">ရိုက်ပြီးသား %1$d ခု</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ဖမ်းယူခြင်းအစီအစဉ်မှ ဖယ်ရှားလိုက်ပါပြီ"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ချန်နယ်ချိန်ကိရိယာလိုင်းပူးနေ၍ တစ်ချို့ကိုသာ ဖမ်းယူနိုင်မည်။"</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ချန်နယ်ချိန်ကိရိယာ လိုင်းပူးနေ၍ ဖမ်းယူနိုင်မည်မဟုတ်ပါ။"</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"စီစဉ်ထားသည့် ဖမ်းယူမှုများ မရှိသေးပါ။\nဖမ်းယူမှုကို ပရိုဂရမ်လမ်းညွှန်အား ကြည့်ရှု၍ စီစဉ်နိုင်ပါသည်။"</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">ရိုက်ကူးမှု %1$d ခု ပဋိပက္ခဖြစ်နေပါသည်</item>
+ <item quantity="one">ရိုက်ကူးမှု %1$d ခု ပဋိပက္ခဖြစ်နေပါသည်</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"ဇာတ်လမ်းတွဲဆက်တင်များ"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"ဇာတ်လမ်းတွဲ စတင်ဖမ်းယူရန်"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"ဇာတ်လမ်းတွဲဖမ်းယူခြင်း ရပ်ရန်"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"ဇာတ်လမ်းတွဲဖမ်းယူခြင်းကို ရပ်မလား။"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ဖမ်းယူထားသည့် အပိုင်းများသည် DVR စာကြည့်တိုက်တွင် ရှိနေဦးမည်ဖြစ်သည်။"</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"ရပ်ရန်"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ယခု မည်သည့် ဇာတ်လမ်းပိုင်းကိုမျှ လွှင့်နေခြင်း မရှိပါ။"</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"အပိုင်းငယ်များ မရနိုင်သေးပါ။\nရနိုင်သည်နှင့် ၎င်းတို့ကို ဖမ်းယူသွားပါမည်။"</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d မိနစ်)</item>
+ <item quantity="one">(%1$d မိနစ်) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"ဒီနေ့"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"မနက်ဖြန်"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"မနေ့က"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"ဒီနေ့ <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"မနက်ဖြန် <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"ရမှတ်"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"ကူးယူထားသော အစီအစဉ်များ"</string>
+</resources>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
deleted file mode 100644
index 1ab6baf7..00000000
--- a/res/values-my/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"မိုနို"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"စတီရီယို"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Play ထိန်းချုပ်မှုများ"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"မကြာမီက ချာနယ်"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"TV ရွေးစရာများ"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP ရွေးချယ်စရာများ"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"ဤလိုင်းအတွက် အဖွင့်ထိန်းချုပ်ခြင်းများ မရနိုင်ပါ"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ဖွင့်ပါ သို့မဟုတ် ခဏရပ်ပါ"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ရှေ့သို့ အမြန်သွားရန်"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"ပြန်ရစ်ရန်"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"ရှေ့သို့"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"ယခင်"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"အစီအစဉ် လမ်းညွှန်"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"ရရှိနိုင်သည့် ချန်နယ်အသစ်များ"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ဖွင့်ရန်"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"စာတမ်းထိုးများ"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"မြင်ကွင်း မုဒ်"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"ဖွင့်ထား"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"ပိတ်ထား"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"အသံစုံ"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"နောက်ထပ်ချန်နယ်များ ရယူရန်"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"ဆက်တင်များ"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"ရင်းမြစ်"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"လဲပြောင်းသည်"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"ဖွင့်ထား"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"ပိတ်ထား"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"အသံ"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"အဓိက"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP ဝင်းဒိုး"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"အဆင်အပြင်"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"အောက်ညာ"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"အပေါ်ညာ"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"အပေါ်ဘယ်"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"အောက်ဘယ်"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"ကပ်လျက်"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"ဆိုက်"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"ကြီး"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"သေး"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"ထည့်သွင်းမှု ရင်းမြစ်"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"တီဗီ (ဧရီယာတိုင်/ကြိုး)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"အစီအစဉ် အချက်အလက်များ မရှိ"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"သတင်းအချက်အလက် မရှိပါ"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"ပိတ်ဆို့ ချာနယ်"</string>
- <string name="default_language" msgid="4122326459624337928">"အမည်မသိဘာသာစကား"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"စာတမ်းထိုးများ"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ပိတ်ထား"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"စိတ်ကြိုက်ပုံစံချရန်"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"စာတမ်းထိုးအတွက် ရွေးစရာများ သတ်မှတ်ရန်"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"မြင်ကွင်း မုဒ်"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"အသံစုံ"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"မိုနို"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"စတီရီယို"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"၅.၁ ပတ်လည်"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"၇.၁ ပတ်လည်"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ချာနယ်"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ချာနယ်စာရင်း စိတ်တိုင်းကျ"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"အုပ်စု ရွေးရန်"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"အုပ်စု ရွေးမှု ဖျက်ရန်"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"အုပ်စုဖွဲ့မှု"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ချာနယ် ရင်းမြစ်များ"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"အုပ်စုဖွဲ့မှု"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"ဤအစီအစဉ်အား ပိတ်ဆို့ထားသည်။"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"ဤအစီအစဉ်သည် အဆင့် <xliff:g id="RATING">%1$s</xliff:g> ရှိ၏"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"ထည့်သွင်းမှုက အော်တို-စကင် ပံ့ပိုးမပေး"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' အတွက် အော်တို−စကင် မစနိုင်ပါ"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"ပိတ်ထားသည့် စာတန်းများ အတွက် စနစ်ဆိုင်ရာ ဦးစားပေးမှုများကို စတင်မရပါ။"</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">ချန်နယ် %1$d ခုပေါင်းထည့်ပြီးပါပြီ</item>
- <item quantity="one">ချန်နယ် %1$d ခုပေါင်းထည့်ပြီးပါပြီ</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"ချာနယ်များ ထည့်မထား"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"တျူနား"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"မိဘ ထိန်းချုပ်မှု"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ဖွင့်ရန်"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ပိတ်ရန်"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"ချာနယ်များ ပိတ်ရန်"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"အားလုံး ပိတ်ဆို့ရန်"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"အားလုံး ပြန်ဖွင့်ရန်"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"ဝှက်ထားသည့် ချာနယ်များ"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"အစီအစဉ်ကန့်သတ်ချက်"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN ပြောင်းရန်"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"အဆင့်ပေး စနစ်များ"</string>
- <string name="option_ratings" msgid="4009116954188688616">"အမှတ်ပေးမှုများ"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"အဆင့်ပေးစနစ်များပြပါ"</string>
- <string name="other_countries" msgid="8342216398676184749">"အခြားနိုင်ငံများ"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"မရှိ"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"မရှိ"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"မရှိ"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"ကန့်သတ်ချက်မြှင့်ရန်"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"ကန့်သတ်ချက်များ အလတ်"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"ကန့်သတ်ချက်များ နိမ့်"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"စိတ်တိုင်းကျ"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"ကလေးများအတွက် သင့်တော်သည့် အကြောင်းအရာ"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"ကလေးကြီးများ အတွက် သင့်သော အကြောင်းအရာ"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"ဆယ်ကျော်သက်များ အတွက် ဆီလျော်သည့် အကြောင်းအရာ"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"လက်ဖြင့် သတ်မှတ်ခဲ့သည့် ကန့်သတ်ချက်များ"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s နှင့် ထပ်ဆင့်မှတ်"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"ထပ်ဆင့်-အမှတ်ပေးမှု"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ဒီချာနယ်ကို ကြည့်ရန် သင့် PIN ရိုက်ထည့်ပါ"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"ဒီအစီအစဉ်ကို ကြည့်ရန် သင့် PIN ရိုက်ထည့်ပါ"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ဤပရိုဂရမ်ကို <xliff:g id="RATING">%1$s</xliff:g> အဆင့်သတ်မှတ်ထားပါသည်။ ဤပရိုဂရမ်ကို ကြည့်ရှုရန် သင့်ပင်နံပါတ်ကို ထည့်ပါ"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"သင့် PIN ရိုက်ထည့်ပါ"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"မိဘ ထိန်းချုပ်မှုကို သတ်မှတ်ရန်၊ PIN ကို ဖန်တီးပါ"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"PIN အသစ်ကို ထည့်သွင်းရန်"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"သင့် PIN ကို အတည်ပြုပါ"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"သင့် လက်ရှိ PIN ရိုက်ထည့်ပါ"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">မှားယွင်းသည့်ပင်နံပါတ် ၅ ကြိမ်သင်ထည့်သွင်းခဲ့သည်။\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်လုပ်ကြည့်ပါ။</item>
- <item quantity="one">မှားယွင်းသည့်ပင်နံပါတ် ၅ ကြိမ်သင်ထည့်သွင်းခဲ့သည်။\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်လုပ်ကြည့်ပါ။</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"ထို PIN မှာ မှားနေသည်။ ထပ်ကြိုးစားပါ။"</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"PIN မှာ မတိုက်ဆိုင်ပါ၊ ထပ်ပြီး စမ်းပါ။"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"ဆက်တင်များ"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ချန်နယ်စာရင်းကို စိတ်တိုင်းကျပြုပြင်ရန်"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"သင့်ပရိုဂရမ်လမ်းညွှန်အတွက် ချန်နယ်များရွေးချယ်ပါ"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ချန်နယ် အရင်းအမြစ်များ"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"ချန်နယ်အသစ်များ ရနိုင်ပါသည်"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"မိဘ ထိန်းချုပ်မှု"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"အခမဲ့အရင်းအမြစ်လိုင်စင်များ"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"အခမဲ့ ရင်းမြစ် လိုင်စင်များ"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"ဗားရှင်း"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"ဤချာနယ်ကို ကြည့်ရန်၊ ညာဘက် နှိပ်ပြီး PIN ရိုက်ထည့်ပါ"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"ဤအစီအစဉ်ကို ကြည့်ရန်၊ ညာဘက် နှိပ်ပြီး PIN ရိုက်ထည့်ပါ"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"ဤအစီအစဉ်သည် အဆင့် <xliff:g id="RATING">%1$s</xliff:g> ရှိ၏။ \nဤအစီအစဉ်အား ကြည့်ရန်၊ ညာဘက် နှိပ်ပြီး PIN ရိုက်ထည့်ပါ။"</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ဤချန်နယ်ကိုကြည့်ရန်၊ မူလတိုက်ရိုက်လွှင့်သည့်တီဗွီအပ်ဖ်ကို အသုံးပြုပါ။"</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"အစီအစဉ်ကိုကြည့်ရန်၊ မူလတိုက်ရိုက်လွှင့်သည့် တီဗွီအပ်ဖ်ကိုအသုံးပြုပါ။"</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ဤအစီအစဉ်ကို <xliff:g id="RATING">%1$s</xliff:g> သတ်မှတ်ထားသည်။ \nဤအစီအစဉ်ကိုကြည့်ရန်၊ မူလတိုက်ရိုက်လွှင့်သည့် တီဗွီအပ်ဖ်ကိုအသုံးပြုပါ။"</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"အစီအစဉ်ကို ပိတ်ဆို့ထား"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ဤအစီအစဉ်သည် အဆင့် <xliff:g id="RATING">%1$s</xliff:g> ရှိ၏"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"အသံ သီးသန့်"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"လှိုင်းဆွဲအားနည်းသည်"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"အင်တာနက်ချိတ်ဆက်မှု မရှိပါ"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">အခြားချန်နယ်လိုင်းများကို ဖမ်းယူနေသောကြောင့် ဤချန်နယ်လိုင်းကို <xliff:g id="END_TIME_1">%1$s</xliff:g> အထိ ဖွင့်၍ရမည်မဟုတ်ပါ။ \n\nဖမ်းယူခြင်းအချိန်ဇယားကို ချိန်ညှိရန် ညာဘက်ကိုနှိပ်ပါ။</item>
- <item quantity="one">အခြားချန်နယ်လိုင်းကို ဖမ်းယူနေသောကြောင့် ဤချန်နယ်လိုင်းကို <xliff:g id="END_TIME_0">%1$s</xliff:g> အထိ ဖွင့်၍ရမည်မဟုတ်ပါ။ \n\nဖမ်းယူခြင်းအချိန်ဇယားကို ချိန်ညှိရန် ညာဘက်ကိုနှိပ်ပါ။</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"ခေါင်းစဉ် မပါ"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ချာနယ် ပိတ်ဆို့ထား"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"အသစ်"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"အရင်းအမြစ်များ"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d ချန်နယ်များ</item>
- <item quantity="one">%1$d ချန်နယ်</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"လိုင်းမရှိပါ"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"အသစ်"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"စဖွင့်မသတ်မှတ်ရသေးပါ"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"နောက်ထပ် အရင်းအမြစ်များ ရယူပါ"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"တိုက်ရိုက်လွှင့်ချန်နယ်များရှိသည့် အက်ပ်များကို ရှာပါ"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"ချန်နယ် အရင်းအမြစ် အသစ်များ ရှိပါသည်"</string>
- <string name="new_sources_description" msgid="749649005588426813">"ချန်နယ် အရင်းအမြစ် အသစ်များမှ ကမ်းလှမ်းလိုသည့် ချန်နယ်များ ရှိပါသည်။ \n၎င်းတို့ကို ယခု စဖွင့်သတ်မှတ်ပါ၊ သို့မဟုတ် နောက်ပိုင်းတွင် ချန်နယ် အရင်းအမြစ်များ ဆက်တင်ထဲတွင် သတ်မှတ်ပါ။"</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"ယခု စဖွင့်သတ်မှတ်ပါ"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"အိုကေ၊ ရပါပြီ"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307"><b>" ရွေးချယ်ပါအားနှိပ်ပြီး"</b>" တီဗီမန်နယူးကိုဝင်ရောက်ကြည့်ရှုပါ။"</string>
- <string name="msg_no_input" msgid="3897674146985427865">"တီဗီ ထည့်သွင်းမှု ရှာမတွေ့ပါ။"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"တီဗီ ထည့်သွင်းမှု ရှာမတွေ့နိုင်ပါ။"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP ကို ပံ့ပိုးမထားပါ။"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP နှင့် ပြနိုင်သည့် ထည့်သွင်းစရာ မရှိပါ။"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"သင့်တော်သည့် တျူနာ အမျိုးအစား မဟုတ်ပါ။ တီဗွီ အဝင်ပေါက်အတွက် တိုက်ရိုက်လွှင့် ချန်နယ်များ အက်ပ်အား ဖွင့်ပါ။"</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"ညှိမှု မအောင်မြင်ပါ"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"ဤလုပ်ဆောင်ချက်ကို ကိုင်တွယ်နိုင်သည့် အက်ပ်မရှိပါ။"</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"ရင်းမြစ် ချာနယ် အားလုံးကို ဝှက်ထားသည်။ \n ကြည့်ရန် အနည်းဆုံး ချာနယ် တစ်ခုကို ရွေးပါ။"</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ဗီဒီယို မမျှော်လင့်ဘဲ မရရှိနိုင်ပါ။"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"BACK ကီးသည် ချိတ်ဆက် စက်ကိရိယာ အတွက်ဖြစ်၏။ ထွက်ရန် HOME ခလုတ်ကို နှိပ်ပါ။"</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"တီဗီစာရင်းများကို ဖတ်ရှုရန် တိုက်ရိုက်ထုတ်လွှင့်သောချန်နယ်လိုင်းများတွင် ခွင့်ပြူချက်လိုအပ်သည်။"</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"သင့်သတင်းအရင်းအမြစ်များကို တပ်ဆင်ပါ"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"တိုက်ရိုက်လွှင့်သည့် ချန်နယ်များသည် သမားရိုးကျ TV ချန်နယ်များနှင့် အက်ပ်မှလွှင့်ပေးသည့် ချန်နယ်များကို ပူးပေါင်းထားသည့်ခံစားမှုပင်ဖြစ်သည်။ \n\nထည့်သွင်းပြီးသား ချန်နယ်အရင်းမြစ်များကို တပ်ဆင်ခြင်းဖြင့် စတင်လိုက်ပါ။ သို့မဟုတ် တိုက်ရိုက်လွှင့်သည့် ချန်နယ်များပါဝင်သည့် နောက်ထပ်အက်ပ်များအတွက် Google Play Store တွင်ရှာပါ။"</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"ဖမ်းယူခြင်းနှင့် အချိန်ဇယားမျာ"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"၁၀ မိနစ်"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"၃၀ မိနစ်"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"၁ နာရီ"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"၃ နာရီ"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"မကြာမီက"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"စီစဉ်ထားသော"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"စီးရီး"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"အခြား"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ချန်နယ်ကို မှတ်တမ်းတင်၍မရပါ။"</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"ပရိုဂရမ်ကို မှတ်တမ်းတင်၍ မရပါ။"</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ဖမ်းယူရန် စီစဉ်ထားပါသည်"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ယခုချိန်မှ <xliff:g id="ENDTIME">%2$s</xliff:g> အထိ ရိုက်ကူးမည်"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"အချိန်ဇယားအပြည့်အစုံ"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">နောက်ထပ် %1$d ရက်</item>
- <item quantity="one">နောက်ထပ် %1$d ရက်</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d မိနစ်</item>
- <item quantity="one">%1$d မိနစ်</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">ရိုက်ကူးမှုအသစ် %1$d ခု</item>
- <item quantity="one">ရိုက်ကူးမှုအသစ် %1$d ခု</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">ရိုက်ကူးမှု %1$d ခု</item>
- <item quantity="one">ရိုက်ကူးမှု %1$d ခု</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">ရိုက်ကူးရန် အစီအစဉ်%1$dခု</item>
- <item quantity="one">ရိုက်ကူးရန် အစီအစဉ်%1$dခု</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"ကြည့်ရန်"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"အစမှနေ၍ ဖွင့်ရန်"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"ဆက်ဖွင့်ရန်"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"ဖျက်ရန်"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"မှတ်တမ်းတင်ထားသည်ကို ဖျက်ရန်"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"ဆက်ဖွင့်ရန်"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"အတွဲ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"အချိန်ဇယားကိုကြည့်ရန်"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"နောက်ထပ် ဖတ်ရန်"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ရုပ်သံကူးယူမှုဖျက်ပါ"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"သင်ဖျက်ပစ်လိုသော အခန်းဆက်များကို ရွေးပါ။ ဖျက်လိုက်သည်နှင့် ၎င်းတို့ကို ပြန်ဆည်ယူ၍ မရတော့ပါ။"</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"ဖျက်ရန် ရုပ်သံဖမ်းယူမှုများ မရှိတော့ပါ။"</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"ကြည့်ပြီးသောအခန်းဆက်များရွေးပါ"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"အခန်းဆက်များအားလုံးကို ရွေးပါ"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"အခန်းဆက်များအားလုံးကို ဖျက်ပါ"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> မိနစ်ရှိသည့်အနက် <xliff:g id="WATCHED">%1$d</xliff:g> မိနစ် ကြည့်ပြီးသွားပြီ"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> စက္ကန့်ရှိသည့်အနက် <xliff:g id="WATCHED">%1$d</xliff:g> စက္ကန့် ကြည့်ပြီးသွားပြီ"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"လုံးဝမကြည့်ရသေးပါ"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">အခန်းဆက် %2$d ခုအနက် %1$d ခုကို ဖျက်လိုက်သည်</item>
- <item quantity="one">အခန်းဆက် %2$d ခုအနက် %1$d ခုကို ဖျက်လိုက်သည်</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ဦးစားပေးမှု"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"အမြင့်ဆုံး"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"အနိမ့်ဆုံး"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"နံပါတ် <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ချန်နယ်များ"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"မည်သည့်အရာမဆို"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"ဦးစားပေးမှုကို ရွေးရန်"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"တစ်ချိန်တည်းတွင် ဖမ်းယူရမည့်အစီအစဉ် များပြားလွန်းသည့်အခါ ဦးစားပေးမှု ပိုမိုမြင့်မားသည့် အစီအစဉ်များကိုသာ ဖမ်းယူသွားပါမည်။"</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"သိမ်းရန်"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"တစ်ကြိမ်တစ်ခါတည်း ဖမ်းယူခြင်းသည် ဦးစားပေးမှုအမြင့်ဆုံးဖြစ်သည်"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"မလုပ်တော့"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"မလုပ်တော့"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"မေ့ပစ်ရန်"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"ရပ်ရန်"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ဖမ်းယူခြင်းအချိန်ဇယားကို ကြည့်ရန်"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"ဤအစီအစဉ် တစ်ခုတည်း"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ယခု - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"အခန်းဆက်များ တစ်တွဲလုံး…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"မည်သို့ပင်ဖြစ်စေ စီစဉ်ရန်"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"၎င်းအစား ဤတစ်ခုကို ဖမ်းယူပါ"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ဤဖမ်းယူမှုကို ပယ်ဖျက်ရန်"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"ယခုကြည့်ရန်"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"ရိုက်ကူးနိုင်သည်"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ရိုက်ကူးရေးအတွက် စီစဉ်ထားပါသည်"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ရိုက်ကူးရေးအစီအစဉ်တိုက်နေပါသည်"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ဖမ်းယူနေသည်"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ဖမ်းယူခြင်း မအောင်မြင်ပါ"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"ရိုက်ကူးရေး အချိန်ဇယားများ သတ်မှတ်ရန် အစီအစဉ်များကို ဖတ်နေသည်"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"ပရိုဂရမ်များကို ဖတ်နေသည်"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR သည် နောက်ထပ်သိုလှောင်ရန်နေရာလွတ် လိုအပ်နေသည်"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"အစီအစဉ်များကို DVR နှင့် ဖမ်းယူသိမ်းဆည်းထားနိုင်ပါသည်။ သို့သော် DVR ကို အသုံးပြုနိုင်ရန် သင့်စက်ပစ္စည်းတွင် လုံလောက်သော နေရာလွတ် လောလောဆယ်မရှိပါ။ <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>ဂစ်ဂါဘိုက် သို့မဟုတ် ၎င်းနှင့်အထက်ရှိသော ပြင်ပသိုလှောင်ကိရိယာနှင့် ချိတ်ဆက်ပြီး ၎င်းကို သိုလှောင်ခန်းစက်ပစ္စည်းအဖြစ် ပြင်ဆင်သတ်မှတ်ရန် ညွှန်ကြားချက်များအတိုင်း လိုက်နာပါ။"</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"သိုလှောင်မှုများ ပျောက်ဆုံးနေခြင်း"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR က အသုံးပြုသော သိုလှောင်ခန်းအချို့မှာ ပျောက်ဆုံးနေသည်။ DVR ကို ပြန်ဖွင့်ရန်အတွက် ယခင်က အသုံးပြုခဲ့သော ပြင်ပသုံးအခွေဖွင့်စက်နှင့် ချိတ်ဆက်ပါ။ နောက်တစ်နည်းအနေဖြင့် ၎င်းကို အသုံးပြု၍ မရတော့လျှင် မေ့ပစ်ရန် ရွေးချယ်နိုင်ပါသည်။"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"သိုလှောင်ခန်းကို မေ့ပစ်မလား။"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"သင်မှတ်တမ်းတင်ထားသော အကြောင်းအရာနှင့် အချိန်ဇယားများအားလုံး ဆုံးရှုံးသွားလိမ့်မည်။"</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ရိုက်ကူးခြင်းကို ရပ်လိုပါသလား။"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ဖမ်းယူထားသည့် အကြောင်းအရာကို သိမ်းဆည်းထားပါမည်။"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ဖမ်းယူရန် စီစဉ်ထားသော်လည်း အချိန်ဇယားတိုက်နေပါသည်"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ဖမ်းယူမှုကို စတင်လိုက်ပါပြီ။ သို့သော် အချိန်ဇယားတိုက်နေပါသည်"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ဖမ်းယူသွားပါမည်။"</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ကို ဖမ်းယူနေပါသည်။"</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ၏ အချို့အစိတ်အပိုင်းများကို ဖမ်းယူသွားမည် မဟုတ်ပါ။"</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> နှင့် <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> တို့၏ အချို့အစိတ်အပိုင်းများကို ဖမ်းယူသွားမည် မဟုတ်ပါ။"</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>၊ <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> တို့၏ အချို့အစိတ်အပိုင်းများနှင့် နောက်ထပ်အစီအစဉ် တစ်ခုကို ဖမ်းယူသွားမည် မဟုတ်ပါ။"</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>၊ <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> တို့၏ အချို့အစိတ်အပိုင်းများနှင့် နောက်ထပ်အစီအစဉ် %3$d ခုတို့ကို ဖမ်းယူသွားမည် မဟုတ်ပါ။</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>၊ <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> တို့၏ အချို့အစိတ်အပိုင်းများနှင့် နောက်ထပ်အစီအစဉ် %3$d ခုတို့ကို ဖမ်းယူသွားမည် မဟုတ်ပါ။</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"သင်ဘယ်ရုပ်/သံကို ဖမ်းယူလိုပါသလဲ။"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"ဘယ်လောက်ကြာကြာ ဖမ်းယူလိုပါသနည်း။"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"စီစဉ်ပြီးပါပြီ"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"တူညီသည့် ပရိုဂရမ်ကို <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> ၌ ဖမ်းယူရန် စီစဉ်ထားပြီး ဖြစ်ပါသည်။"</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ဖမ်းယူပြီးပါပြီ"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ဤပရိုဂရမ်ကို ဖမ်းယူပြီးပါပြီ။ ၎င်းကို DVR စာကြည့်တိုက်တွင် ကြည့်ရှုနိုင်ပါသည်။"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"ရိုက်ကူးထားသည့်ပရိုဂရမ်ကို မတွေ့ပါ။"</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ဆက်စပ်နေသည့် ရိုက်ကူးမှုများ"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(ပရိုဂရမ် ဖော်ပြချက်မရှိပါ)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">ရိုက်ပြီးသား %1$d ခု</item>
- <item quantity="one">ရိုက်ပြီးသား %1$d ခု</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ကို ဖမ်းယူခြင်းအစီအစဉ်မှ ဖယ်ရှားလိုက်ပါပြီ"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ချန်နယ်ချိန်ကိရိယာလိုင်းပူးနေ၍ တစ်ချို့ကိုသာ ဖမ်းယူနိုင်မည်။"</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ချန်နယ်ချိန်ကိရိယာ လိုင်းပူးနေ၍ ဖမ်းယူနိုင်မည်မဟုတ်ပါ။"</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"စီစဉ်ထားသည့် ဖမ်းယူမှုများ မရှိသေးပါ။\nဖမ်းယူမှုကို ပရိုဂရမ်လမ်းညွှန်အား ကြည့်ရှု၍ စီစဉ်နိုင်ပါသည်။"</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">ရိုက်ကူးမှု %1$d ခု ပဋိပက္ခဖြစ်နေပါသည်</item>
- <item quantity="one">ရိုက်ကူးမှု %1$d ခု ပဋိပက္ခဖြစ်နေပါသည်</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"ဇာတ်လမ်းတွဲဆက်တင်များ"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"ဇာတ်လမ်းတွဲ စတင်ဖမ်းယူရန်"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"ဇာတ်လမ်းတွဲဖမ်းယူခြင်း ရပ်ရန်"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"ဇာတ်လမ်းတွဲဖမ်းယူခြင်းကို ရပ်မလား။"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ဖမ်းယူထားသည့် အပိုင်းများသည် DVR စာကြည့်တိုက်တွင် ရှိနေဦးမည်ဖြစ်သည်။"</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"ရပ်ရန်"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"အပိုင်းငယ်များ မရနိုင်သေးပါ။\nရနိုင်သည်နှင့် ၎င်းတို့ကို ဖမ်းယူသွားပါမည်။"</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d မိနစ်)</item>
- <item quantity="one">(%1$d မိနစ်) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"ဒီနေ့"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"မနက်ဖြန်"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"မနေ့က"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"ဒီနေ့ <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"မနက်ဖြန် <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"ရမှတ်"</string>
-</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index a2cf46cc..b9c149a7 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Play-kontroller"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Nylige kanaler"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanaler"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV-alternativer"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP-alternativer"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Play-kontroller er ikke tilgjengelige for denne kanalen"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Spill av eller sett på pause"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Spol fremover"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Teksting"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Visningsmodus"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"På"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Av"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Flere lydspor"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Få flere kanaler"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Innstillinger"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Kilde"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Bytt"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"På"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Av"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Lyd"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Hovedkontroll"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP-vindu"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Utforming"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Nede til høyre"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Oppe til høyre"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Oppe til venstre"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Nede til venstre"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Side om side"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Størrelse"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Stor"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Liten"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Inndatakilde"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenne/kabel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Ingen programinformasjon"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Ingen informasjon"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blokkert kanal"</string>
- <string name="default_language" msgid="4122326459624337928">"Ukjent språk"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Ukjent språk"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Teksting %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Teksting for hørselshemmede"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Av"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Tilpass formatering"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Gruppér etter"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Dette programmet er blokkert."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Dette programmet har ingen vurdering"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Dette programmet er vurdert som <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Inngang støtter ikke auto-kanalsøk"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Kunne ikke starte automatisk skanning for «<xliff:g id="TV_INPUT">%s</xliff:g>»"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d kanal er lagt til</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Ingen kanaler er lagt til"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Foreldrekontroll"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"På"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Av"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Andre land"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Ingen"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ingen"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Ingen vurdering"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blokkér program uten vurdering"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Ingen"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Høye begrensninger"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Medium begrensninger"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Skriv inn PIN-koden din for å se på denne kanalen"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Skriv inn PIN-koden din for å se på dette programmet"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Dette programmet er vurdert som <xliff:g id="RATING">%1$s</xliff:g>. Skriv inn PIN-koden din for å se dette programmet"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Dette programmet har ingen vurdering. Skriv inn PIN-koden din for å se dette programmet"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Skriv inn PIN-koden din"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"For å konfigurere foreldrekontroll, angi en PIN-kode"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Skriv inn en ny PIN-kode"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Prøv på nytt, PIN-koden er feil."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Prøv på nytt, PIN-koden er feil"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Skriv inn postnummeret ditt."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Direkte-TV-appen bruker postnummeret til å oppgi en fullstendig programoversikt for TV-kanalene."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Skriv inn postnummeret ditt"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Ugyldig postnummer"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Innstillinger"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Tilpass kanallisten"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Velg kanaler for programoversikten din"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanalkilder"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nye kanaler er tilgjengelig"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Foreldrekontroll"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Tidsforskyvning"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Ta opp mens du ser på direktesendte programmer, så du kan sette dem på pause eller spole bakover.\nAdvarsel: Dette kan redusere levetiden til den interne lagringen på grunn av intensiv bruk av lagringen."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Lisenser for åpen kildekode"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Åpen kildekode-lisenser"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Send tilbakemelding"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versjon"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"For å se på denne kanalen, trykk til høyre og skriv inn PIN-koden din"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"For å se på dette programmet, trykk til høyre og skriv inn PIN-koden din"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Dette programmet har ingen vurdering.\nFor å se dette programmet, trykk på knappen til høyre og skriv inn PIN-koden din"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Dette programmet har vurderingen <xliff:g id="RATING">%1$s</xliff:g>.\nFor å se på dette programmet, trykk til høyre og skriv inn PIN-koden din."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"For å se på denne kanalen, bruk Live TV-appen som er angitt som standard."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"For å se dette programmet, bruk Live TV-appen som er angitt som standard."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Dette programmet har ingen vurdering.\nFor å se dette programmet, bruk Live TV-appen som er angitt som standard."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Dette programmet er vurdert som <xliff:g id="RATING">%1$s</xliff:g>.\nFor å se dette programmet, bruk Live TV-appen som er angitt som standard."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programmet er blokkert"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Dette programmet har ingen vurdering"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Dette programmet er vurdert som <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Bare lyd"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Svakt signal"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Trykk på «SELECT» (VELG)"</b>" for å åpne TV-menyen."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Kunne ikke finne noen TV-inngang"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Kunne ikke finne TV-inngangen"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP støttes ikke"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Det finnes ingen tilgjengelige inndata som kan vises med PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tuner-typen kan ikke brukes. Kjør Live TV-appen med tuner-typen for TV-inndata."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Justering mislyktes."</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Kunne ikke finne noen app som kan håndtere denne handlingen."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d planlagte opptak</item>
<item quantity="one">%1$d planlagt opptak</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Avbryt opptak"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Stopp opptak"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Se på"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Spill av fra begynnelsen"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Gjenoppta avspilling"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Når det er for mange programmer som skal tas opp samtidig, blir bare programmene med høyere prioritet tatt opp."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Lagre"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Engangsopptak har høyeste prioritet"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Avbryt"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Avbryt"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Glem"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Stopp"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Se tidsplanen for opptak"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Bare dette programmet"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Spill inn dette i stedet"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Kanseller dette opptaket"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Se nå"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Slett opptak …"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Opptaksbar"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Opptak planlagt"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Opptakskonflikt"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Tar opp"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Opptaket mislyktes"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Leser av programmer for å opprette tidsplaner for opptak"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Leser av programmer"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Leser av programmer"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Se nylige opptak"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Opptaket av <xliff:g id="PROGRAMNAME">%1$s</xliff:g> er ufullstendig."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Opptakene av <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> og <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> er ufullstendige."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Opptakene av <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> og <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> er ufullstendige."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Opptaket av <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ble ikke fullført på grunn av utilstrekkelig lagringsplass."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Opptakene av <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> og <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ble ikke fullført på grunn av utilstrekkelig lagringsplass."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Opptakene av <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> og <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ble ikke fullført på grunn av utilstrekkelig lagringsplass."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR trenger mer lagringsplass"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Det kommer til å være mulig til å ta opp programmer med DVR. Det er imidlertid ikke nok lagringsplass på enheten din til at DVR kan fungere. Koble til en ekstern stasjon på <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB eller mer, og følg trinnene for å formatere den som lagringsenhet."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Det kommer til å være mulig til å ta opp programmer med DVR. Det er imidlertid ikke nok lagringsplass på enheten din til at DVR kan fungere. Koble til en ekstern stasjon på <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB eller mer, og følg trinnene for å formatere den som lagringsenhet."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Ikke nok lagringsplass"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Dette programmet blir ikke tatt opp fordi det ikke er nok lagringsplass. Prøv å slette noen eksisterende opptak."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Manglende lagringsplass"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Noe av lagringsplassen som brukes av DVR, mangler. Koble til den eksterne disken du bruke tidligere, for å slå på DVR igjen. Eventuelt kan du velge å glemme lagringsplassen hvis den ikke er tilgjengelig lenger."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Vil du glemme lagring?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Alt innspilt innhold og alle tidsplanene går tapt."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Vil du stoppe opptaket?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Det innspilte innholdet blir lagret."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Opptaket av <xliff:g id="PROGRAMNAME">%1$s</xliff:g> stoppes fordi det har konflikter med dette programmet. Det innspilte innholdet blir lagret."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Opptak er planlagt, men har konflikter"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Opptak har startet, men har konflikter"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> blir tatt opp."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Det samme programmet er allerede planlagt for opptak <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Allerede tatt opp"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Dette programmet er allerede tatt opp. Det er tilgjengelig i DVR-biblioteket."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Opptak av serie er planlagt"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> opptak er planlagt for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opptak er planlagt for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> opptak er planlagt for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> av dem blir ikke tatt opp på grunn av konflikter.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opptak er planlagt for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Det blir ikke tatt opp på grunn av konflikter.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> opptak er planlagt for <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episoder av denne serien og andre serier blir ikke tatt opp på grunn av konflikter.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opptak er planlagt for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episoder av denne serien og andre serier blir ikke tatt opp på grunn av konflikter.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> opptak er planlagt for <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Én episode av andre serier blir ikke tatt opp på grunn av konflikter.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opptak er planlagt for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Én episode av andre serier blir ikke tatt opp på grunn av konflikter.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> opptak er planlagt for <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episoder av andre serier blir ikke tatt opp på grunn av konflikter.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opptak er planlagt for <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episoder av andre serier blir ikke tatt opp på grunn av konflikter.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Finner ikke programopptaket."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Relaterte opptak"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Ingen programbeskrivelse)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d opptak</item>
<item quantity="one">%1$d opptak</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Vil du stoppe opptaket av serien?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Episoder som er tatt opp, er fremdeles tilgjengelige i DVR-biblioteket."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Stopp"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Ingen episoder er på luften nå."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Ingen episoder er tilgjengelige.\nDe blir tatt opp når de er tilgjengelige."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minutter)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> i dag"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> i morgen"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Poengsum"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programmer som er tatt opp"</string>
</resources>
diff --git a/res/values-ne-v23/strings.xml b/res/values-ne-rNP-v23/strings.xml
index 67220466..67220466 100644
--- a/res/values-ne-v23/strings.xml
+++ b/res/values-ne-rNP-v23/strings.xml
diff --git a/res/values-ne/arrays.xml b/res/values-ne-rNP/arrays.xml
index a6dc0066..a6dc0066 100644
--- a/res/values-ne/arrays.xml
+++ b/res/values-ne-rNP/arrays.xml
diff --git a/res/values-ne/rating_system_strings.xml b/res/values-ne-rNP/rating_system_strings.xml
index 776e7175..776e7175 100644
--- a/res/values-ne/rating_system_strings.xml
+++ b/res/values-ne-rNP/rating_system_strings.xml
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
new file mode 100644
index 00000000..9bc3dcaa
--- /dev/null
+++ b/res/values-ne-rNP/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"मोनो"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"स्टेरियो"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"प्ले नियन्त्रणहरु"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"च्यानलहरू"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"टिभी विकल्पहरू"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"यस च्यानलका लागि प्ले नियन्त्रणहरू अनुपलब्ध"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"प्ले वा पज"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"फास्ट फर्वार्ड"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"रिवाइन्ड"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"अर्को"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"अघिल्लो"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"कार्यक्रम गाइड"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"नयाँ च्यानलहरू उपलब्ध"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> खोल्नुहोस्"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"बन्द क्याप्सनहरु"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"डिस्प्ले मोड"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"मल्टि-अडियो"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"अझ बढी च्यानलहरू प्राप्त गर्नुहोस्"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"सेटिङहरू"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"टिभी (एन्टेना/केबल)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"कुनै पनि कार्यक्रम जानकारी छैन"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"केही सूचना छैन"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"अवरुद्ध च्यानल"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"अज्ञात भाषा"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"उपशीर्षकहरू %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"उपशीर्षक"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"बन्द गर्नुहोस्"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"फर्‍म्याटिङ अनुकूलित"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"बन्द क्याप्सनका लागि प्रणाली-विस्तृत प्राथमिकताहरू सेट गर्नुहोस्"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"डिस्प्ले मोड"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"मल्टि-अडियो"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"मोनो"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"स्टेरियो"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"५.१ सराउन्ड"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"७.१ सराउन्ड"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d च्यानलहरु"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"च्यानल सूची आफू अनुकूल गर्नुहोस्"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"समूह छान्नुहोस्"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"समूह अचयन नगर्नुहोस्"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"द्वारा समूह"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"च्यानल स्रोत"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"द्वारा समूह"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"यो कार्यक्रम निषेध गरिएको छ।"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"यो कार्यक्रमको मूल्याङ्कन गरिएको छैन"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"यो कार्यक्रम मूल्याङ्कन <xliff:g id="RATING">%1$s</xliff:g> गरिएको छ"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"इनपुटले स्वतः स्क्यान समर्थन गर्दैन"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' का लागि स्वतः स्क्यान सुरु गर्न असमर्थ"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"बन्द क्याप्सनका लागि प्रणाली-विस्तृत प्राथमिकताहरू सुरु गर्न असमर्थ।"</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d च्यानलहरू थपिए</item>
+ <item quantity="one">%1$d च्यानल थपियो</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"कुनै पनि च्यानल थपिएन"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"मुख्य नियन्त्रणहरू"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"खोल्नुहोस्"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"बन्द गर्नुहोस्"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"च्यानलहरू अवरुद्ध"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"सबै ब्लक गर्नुहोस्"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"सबै अनब्लक गर्नुहोस्"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"लुकेका च्यानलहरू"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"कार्यक्रम प्रतिबन्धहरू"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN फेर्नुहोस्"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"मूल्याङ्कन प्रणालीहरू"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"मूल्याङ्कन"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"सबै मूल्याङ्कन प्रणाली हेर्नुहोस्"</string>
+ <string name="other_countries" msgid="8342216398676184749">"अन्य देशहरू"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"कुनै पनि होइन"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"कुनै पनि होइन"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"मूल्याङ्कन नगरिएको"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"मूल्याङ्कन नगरिएका कार्यक्रमहरूमाथि रोक लगाउनु"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"कुनै पनि होइन"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"उच्च प्रतिबन्धहरू"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"मध्यम प्रतिबन्धहरू"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"न्यून प्रतिबन्धहरू"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"आफू अनुकूल"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"बालबालिकाका लागि उपयुक्त सामग्री"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"ठूला बच्चाहरुका लागि उपयुक्त सामग्री"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"किशोर किशोरीहरुका लागि उपयुक्त सामग्री"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"मेनुअल प्रतिबन्धहरु"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s र सहायक स्तर निर्धारण"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"सहायक स्तर निर्धारण"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"यो च्यानल हेर्न तपाईँको PIN प्रविष्टि गर्नुहोस्"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"यो कार्यक्रम हेर्न तपाईँको PIN प्रविष्टि गर्नुहोस्"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"यस कार्यक्रमलाई <xliff:g id="RATING">%1$s</xliff:g> भनेर मूल्याङ्कन गरिएको छ। यो कार्यक्रम हेर्न आफ्नो PIN प्रविष्ट गर्नुहोस्"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"यो कार्यक्रमको मूल्याङ्कन गरिएको छैन। यो कार्यक्रम हेर्न आफ्नो PIN प्रविष्ट गर्नुहोस्"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"आफ्नो पिन प्रविष्ट गर्नुहोस्"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"अभिभावकत्वको नियन्त्रण सेट गर्न, एउटा PIN सिर्जना गर्नुहोस्"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"नयाँ PIN प्रविष्टि गर्नुहोस्"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"तपाईँको PIN को पुष्टि गर्नुहोस्"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"तपाईंको हालको पिन प्रविष्ट गर्नुहोस्"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">तपाईंले ५ पटक गलत PIN प्रविष्ट गर्नुभयो।\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> सेकेन्डमा पुन: प्रयास गर्नुहोस्।</item>
+ <item quantity="one">तपाईंले ५ पटक गलत PIN प्रविष्ट गर्नुभयो।\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> सेकेन्डमा पुन: प्रयास गर्नुहोस्।</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"त्यो PIN गलत थियो। पुनः प्रयास गर्नुहोस्।"</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"पुनः प्रयास गर्नुहोस्, PIN मेल खाँदैन"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"आफ्नो जिप कोड प्रविष्ट गर्नुहोस्।"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"TV च्यानलहरूको कार्यक्रमको बारेमा समग्र मार्गदर्शन प्रदान गर्न लाइभ च्यानल अनुप्रयोगले उक्त जिप कोड प्रयोग गर्नेछ।"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"आफ्नो जिप कोड प्रविष्ट गर्नुहोस्"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"अमान्य ZIP कोड"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"सेटिङहरू"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"च्यानलको सूची आफू अनुकूल गर्नुहोस्"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"आफ्नो कार्यक्रम निर्देशिकाको लागि च्यानलहरू छनौट गर्नुहोस्"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"च्यानलका स्रोतहरू"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"नयाँ च्यानलहरू उपलब्ध छन्"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"अभिभावकीय नियन्त्रणहरू"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"टाइमसिफ्ट"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"तपाईंले लाइभ कार्यक्रमहरूलाई पज वा रिवाइन्ड गर्न सक्नुहोस् भन्नका खातिर हेर्दाहेर्दै रेकर्ड गर्नुहोस्।\nचेतावनी: यसले भण्डारणको अत्यन्त धेरै प्रयोग गरेर आन्तरिक भण्डारणको आयु कम गर्न सक्छ।"</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"स्रोतका इजाजतपत्रहरू खोल्नुहोस्"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"प्रतिक्रिया पठाउनुहोस्"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"संस्करण"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"यो च्यानल हेर्न, दायाँ प्रेस गर्नुहोस् र आफ्नो पिन प्रविष्ट गर्नुहोस्"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"यो कार्यक्रम हेर्न, दायाँ प्रेस गर्नुहोस् र आफ्नो पिन प्रविष्ट गर्नुहोस्"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"यो कार्यक्रमको मूल्याङ्कन गरिएको छैन।\nयो कार्यक्रम हेर्न दायाँ थिचेर आफ्नो PIN प्रविष्ट गर्नुहोस्"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"यो कार्यक्रम मूल्याङ्कन <xliff:g id="RATING">%1$s</xliff:g> गरिएको छ।\nयो कार्यक्रम हेर्न, दायाँ थिच्नुहोस् र आफ्नो PIN प्रविष्ट गर्नुहोस्।"</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"यो च्यानल हेर्न, पूर्वनिर्धारित लाइभ TV अनुप्रयोग प्रयोग गर्नुहोस्।"</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"यो कार्यक्रम हेर्न, पूर्वनिर्धारित लाइभ TV अनुप्रयोगको प्रयोग गर्नुहोस्।"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"यो कार्यक्रमको मूल्याङ्कन गरिएको छैन।\nयो कार्यक्रम हेर्न पूर्वनिर्धारित लाइभ TV अनुप्रयोग प्रयोग गर्नुहोस्।"</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"यो कार्यक्रम मूल्याङ्कन गरिएको छ <xliff:g id="RATING">%1$s</xliff:g>।\n यो कार्यक्रम हेर्न, पूर्वनिर्धारित लाइभ TV अनुप्रयोग प्रयोग गर्नुहोस्।"</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"प्रोग्राम ब्लक गरिएको छ"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"यो कार्यक्रमको मूल्याङ्कन गरिएको छैन"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"यो कार्यक्रम मूल्याङ्कन <xliff:g id="RATING">%1$s</xliff:g> गरिएको छ"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"अडियो मात्र"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"सिग्नल कमजोर छ"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"इन्टरनेटमा जडान गर्न सकिएन"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">अन्य च्यानलहरू रेकर्ड भइरहेका हुनाले <xliff:g id="END_TIME_1">%1$s</xliff:g> सम्म यो च्यानल प्ले गर्न सकिँदैन। \n\nरेकर्डिङको समय तालिकालाई समायोजन गर्न दायाँ बटन थिच्नुहोस्।</item>
+ <item quantity="one">अर्को च्यानल रेकर्ड भइरहेको हुनाले <xliff:g id="END_TIME_0">%1$s</xliff:g> सम्म यो च्यानल प्ले गर्न सकिँदैन। \n\nरेकर्डिङको समय तालिकालाई समायोजन गर्न दायाँ बटन थिच्नुहोस्।</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"शीर्षक छैन"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"च्यानल अवरुद्ध"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"नयाँ"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"स्रोतहरू"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d च्यानलहरू</item>
+ <item quantity="one">%1$d च्यानल</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"कुनै च्यानलहरू उपलब्ध छैनन्"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"नयाँ"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"सेटअप गरिएको छैन"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"थप स्रोतहरू प्राप्त गर्नुहोस्"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"लाइभ च्यानलहरू प्रस्तुत गर्ने अनुप्रयोगहरू ब्राउज गर्नुहोस्"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"उपलब्ध नयाँ च्यानलका स्रोतहरू"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"नयाँ च्यानलका स्रोतहरुसँग प्रस्ताव गर्न च्यानलहरू छन्। \n अहिले तिनीहरूलाई सेट गर्नुहोस् वा च्यानल स्रोतहरुका सेटिङमा पछि गर्नुहोस्।"</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"अब सेटअप गर्नुहोस्"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"ठीक छ, बुँझें"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"टिभी मेनु खोल्न "<b>"SELECT थिच्नुहोस्"</b>"।"</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"कुनै पनि टिभी स्रोत भेटिएन।"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"टिभी स्रोत भेटिएन लागेन"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ट्यूनर प्रकार अनुपयुक्त। कृपया ट्यूनर प्रकार टिभी स्रोतको लागि Live TV को अनुप्रयोग सुरु गर्नुहोस।"</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ट्युन गर्न असफल"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"यो कार्य सम्हाल्न कुनै पनि अनुप्रयोग भेटिएन।"</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"सबै स्रोत च्यानलहरू लुकेको छन्। \n हेर्नको लागि कम्तीमा एक च्यानल चयन गर्नुहोस्।"</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"भिडियो अप्रत्याशित रूपमा अनुपलब्ध।"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"BACK कुञ्जी जडान भएका उपकरणका लागि हो। बाहिर निस्कनका लागि गृह बटन थिच्नुहोस्।"</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"लाइभ च्यानलहरुलाई TV सूचीहरूलाई पढ्न अनुमति आवश्यक पदर्छ।"</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"आफ्नो स्रोतहरू सेट अप गर्नुहोस्"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"लाइभ च्यानलहरूले TV च्यानलहरूसँगै उपलब्ध गराइएका प्रवाह भइरहेका च्यानलहरूको परम्परागत अनुभवलाई संयोजन गर्छ। \n\nपहिले नै स्थापित च्यानल स्रोतहरू सेट अप गरेर सुरू गरौं। वा लाइभ च्यानलहरू प्रस्ताव गर्ने अझ बढी अनुप्रयोगहरूका लागि Google Play स्टोर ब्राउज गर्नुहोस्।"</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"रेकर्डिङ र समयतालिकाहरू"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"१० मिनेट"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"३० मिनेट"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"१ घन्टा"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"३ घन्टा"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"हालको"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"तालिकाबद्ध गरिएको"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"श्रृंखला"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"अन्य"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"यो च्यानल रेकर्ड गर्न सकिँदैन।"</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"यो कार्यक्रम रेकर्ड गर्न सकिँदैन।"</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> लाई रेकर्ड गर्ने कार्यतालिका निर्धारण गरिएको छ"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"अहिले देखि <xliff:g id="ENDTIME">%2$s</xliff:g> सम्म <xliff:g id="PROGRAMNAME">%1$s</xliff:g> नामक कार्यक्रम रेकर्ड गर्दै"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"समय सहितको पूर्ण कार्यतालिका"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">आगामी %1$d दिन</item>
+ <item quantity="one">आगामी %1$d दिन</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d मिनेट</item>
+ <item quantity="one">%1$d मिनेट</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d नयाँ रेकर्डिङहरू</item>
+ <item quantity="one">%1$d नयाँ रेकर्डिङ</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d रेकर्डिङहरू</item>
+ <item quantity="one">%1$d रेकर्डिङ</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d रेकर्डिङहरूको समय निर्धारण गरियो</item>
+ <item quantity="one">%1$d रेकर्डिङको समय निर्धारण गरियो</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"रेकर्डिङलाई रद्द गर्नुहोस्"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"रेकर्डिङलाई रोक्नुहोस्"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"हेर्नुहोस्"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"सुरुबाट चलाउनुहोस्"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"पुनःसुरु गर्नुहोस्"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"मेट्नुहोस्"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"रेकर्डिङहरू मेट्नुहोस्"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"पुनःसुरु गर्नु"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"सत्र <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"समयतालिका हेर्नु"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"थप पढ्नुहोस्"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"रेकर्डिङ मेट्नुहोस्"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"तपाईँले मेट्न चाहनुहुने एपिसोडहरूलाई चयन गर्नुहोस्। एक पटक मेटाएपछि तिनीहरूलाई पुन:प्राप्त गर्न सकिँदैन।"</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"मेट्नका लागि कुनै रेकर्डिङ छैन।"</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"हेरिएका एपिसोड चयन गर्नुहोस्"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"सबै एपिसोडहरू चयन गर्नुहोस्"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"सबै एपिसोडहरू चयन नगर्नुहोस्"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> मिनेट मध्ये <xliff:g id="WATCHED">%1$d</xliff:g> मिनेट हेरियो"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> सेकेन्ड मध्ये <xliff:g id="WATCHED">%1$d</xliff:g> सेकेन्ड हेरियो"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"कहिल्यै नहेरिएका"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%2$d मध्ये %1$d एपिसोडहरू मेटाइए</item>
+ <item quantity="one">%2$d मध्ये %1$d एपिसोड मेटाइयो</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"प्राथमिकता"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"सबैभन्दा उच्च"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"सबैभन्दा न्यून"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"नम्बर <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"च्यानलहरू"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"जुनसुकै"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"प्राथमिकता छान्नुहोस्"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"एकै समयमा अत्यन्त धेरै कार्यक्रमहरू रेकर्ड गर्नुपर्ने भएकाले उच्च प्राथमिकता भएका कार्यक्रमहरूलाई मात्र रेकर्ड गरिनेछ।"</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"सुरक्षित गर्नुहोस्"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"एक-पटके रेकर्डिङहरूलाई सबैभन्दा उच्च प्राथमिकता दिइन्छ"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"रोक्नुहोस्"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"रेकर्डिङको समयतालिका हेर्नुहोस्"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"यो कार्यक्रम मात्र"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"अहिले - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"सम्पूर्ण शृंखला…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"जे भए पनि समय निर्धारण गर्नुहोस्"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"बरु यो रेकर्ड गर्नुहोस्"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"यस रेकर्डिङलाई रद्द गर्नुहोस्"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"अहिले हेर्नुहोस्"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"रेकर्डिङहरू मेट्नुहोस्…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"रेकर्ड गर्न मिल्ने"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"रेकर्डिङको कार्यतालिका निर्धारण गरिएको छ"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"रेकर्डिङ सम्बन्धी असहमति"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"रेकर्ड गर्दै"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"रेकर्डिङ गर्न सकिएन"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"कार्यक्रमहरूको जानकारी पढ्दै"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"हालका रेकर्डिङहरू हेर्नुहोस्"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> को रेकर्डिङ अपूर्ण छ।"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> र <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> का रेकर्डिङहरू अपूर्ण छन्।"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> र <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> का रेकर्डिङहरू अपूर्ण छन्।"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"भण्डारण स्थान अपर्याप्त भएकाले <xliff:g id="PROGRAMNAME">%1$s</xliff:g> को रेकर्डिङ पूरा भएन।"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"भण्डारण स्थान अपर्याप्त भएकाले <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> र <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> का रेकर्डिङहरू पूरा भएनन्।"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"भण्डारण स्थान अपर्याप्त भएकाले <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> र <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> का रेकर्डिङहरू पूरा भएनन्।"</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR लाई थप भण्डारण चाहिन्छ"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"तपाईँले DVR मार्फत कार्यक्रमहरू रेकर्ड गर्न सक्नुहुनेछ। यद्यपि, अहिले तपाईँको यन्त्रमा DVR ले काम गर्न पुग्ने गरी पर्याप्त भण्डारण छैन। कृपया <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> जि.बि.वा सो भन्दा बढी भण्डारण क्षमता भएको कुनै बाह्य ड्राइभ जडान गर्नुहोस् र त्यसलाई यन्त्रको भण्डारणका रूपमा फर्म्याट गर्न आवश्यक कदमहरू चाल्नुहोस्।"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"पर्याप्त भण्डारण छैन"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"पर्याप्त भण्डारण उपलब्ध नभएको हुनाले यस कार्यक्रमलाई रेकर्ड गरिने छैन। केही विद्यमान रेकर्डिङहरू मेटाई हेर्नुहोस्।"</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"भण्डारण उपलब्ध छैन"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"रेकर्डिङ रोक्ने हो?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"रेकर्ड गरिएको सामग्रीलाई सुरक्षित गरिनेछ।"</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"यस कार्यक्रमसँग परस्पर विरोधी भएकाले <xliff:g id="PROGRAMNAME">%1$s</xliff:g> को रेकर्डिङ रोकिने छ। रेकर्ड गरिएका सामग्रीहरू सुरक्षित गरिने छन्।"</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"रेकर्डिङको कार्यतालिका निर्धारण गरिएको छ तर यसमा असहमतिहरू छन्"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"रेकर्डिङ सुरु भएको छ तर यसमा असहमतिहरू छन्"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> लाई रेकर्ड गरिनेछ।"</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> लाई रेकर्ड गरिँदै छ।"</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> का केही भागहरूलाई रेकर्ड गरिने छैन।"</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> र <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> का केही भागहरूलाई रेकर्ड गरिने छैन।"</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> र थप एक कार्यक्रमका केही भागहरूलाई रेकर्ड गरिने छैन।"</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> र थप %3$d कार्यक्रमहरूलाई रेकर्ड गरिने छैन।</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> र थप %3$d कार्यक्रमलाई रेकर्ड गरिने छैन।</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"तपाईं के रेकर्ड गर्न चाहनुहुन्छ?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"तपाईं कति बेरसम्म रेकर्ड गर्न चाहनुहुन्छ?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"पहिले नै समय सहितको कार्यतालिका निर्धारण गरिएको छ"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"यस कार्यक्रमलाई पहिले नै <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> मा रेकर्ड गर्न समय सहितको कार्यतालिका निर्धारण गरिएको छ।"</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"पहिले नै रेकर्ड गरिएको छ"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"यस कार्यक्रमलाई पहिले नै रेकर्ड गरिएको छ। यो DVR को लाइब्रेरीमा उपलब्ध छ।"</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"शृङ्खलाहरूको रेकर्डिङको समय तालिका बनाइयो"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> का <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रेकर्डिङहरूको समय तालिका तय गरिएको छ।</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> को <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> रेकर्डिङको समय तालिका तय गरिएको छ।</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> का <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रेकर्डिङहरूको समय तालिका तय गरिएको छ। तालमेल नमिलेका कारण ती मध्ये <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> लाई रेकर्ड गरिने छैन।</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> को <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> रेकर्डिङको समय तालिका तय गरिएको छ। तालमेल नमिलेका कारण यसलाई रेकर्ड गरिने छैन।</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> का <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> रेकर्डिङहरूको समय तालिका तय गरिएको छ। तालमेल नमिलेका कारण यस शृङ्खला र अन्य शृङ्खलाका <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> एपिसोडहरूलाई रेकर्ड गरिने छैन।</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> को <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> रेकर्डिङको समय तालिका तय गरिएको छ। तालमेल नमिलेका कारण यस शृङ्खला र अन्य शृङ्खलाका <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> एपिसोडहरूलाई रेकर्ड गरिने छैन।</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> का <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> रेकर्डिङहरूको समय तालिका तय गरिएको छ। तालमेल नमिलेका कारण अन्य शृङ्खलाको १ एपिसोडलाई रेकर्ड गरिने छैन।</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> को <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> रेकर्डिङको समय तालिका तय गरिएको छ। तालमेल नमिलेका कारण अन्य शृङ्खलाको १ एपिसोडलाई रेकर्ड गरिने छैन।</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> का <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> रेकर्डिङहरूको समय तालिका तय गरिएको छ। तालमेल नमिलेका कारण अन्य शृङ्खलाका <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> एपिसोडहरूलाई रेकर्ड गरिने छैन।</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> को <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> रेकर्डिङको समय तालिका तय गरिएको छ। तालमेल नमिलेका कारण अन्य शृङ्खलाका <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> एपिसोडहरूलाई रेकर्ड गरिने छैन।</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"रेकर्ड गरिएको कार्यक्रम भेट्टिएन।"</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"सम्बन्धित रेकर्डिङहरू"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d रेकर्डिङ</item>
+ <item quantity="one">%1$d रेकर्डिङ</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> लाई रेकर्डिङको समय सहितको कार्यतालिकाबाट हटाइयो"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ट्युनर सम्बन्धी असहमतिका कारण आंशिक रूपमा रेकर्ड गरिनेछ।"</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ट्युनर सम्बन्धी असहमतिका कारण रेकर्ड गरिने छैन।"</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"अहिलेसम्म समय सहितको कार्यतालिका निर्धारण गरिएको कुनै रेकर्डिङ छैन।\nतपाईं कार्यक्रम निर्देशिका मार्फत रेकर्डिङको समय सहितको कार्यतालिका निर्धारण गर्न सक्नुहुन्छ।"</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">रेकर्डिङ सम्बन्धी %1$d असहमतिहरू</item>
+ <item quantity="one">रेकर्डिङ सम्बन्धी %1$d असहमति</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"शृंखला सम्बन्धी सेटिङहरू"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"शृंखलाको रेकर्डिङ सुरु गर्नुहोस्"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"शृंखलाको रेकर्डिङ रोक्नुहोस्"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"शृंखलाको रेकर्डिङ रोक्ने हो?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"रेकर्ड गरिएका एपिसोडहरू DVR सम्बन्धी लाइब्रेरीमा उपलब्ध रहनेछन्।"</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"रोक्नुहोस्"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"अहिले कुनै एपिसोड प्रसारण भइरहेको छैन।"</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"कुनै एपिसोड उपलब्ध छैन।\nएपिसोडहरू उपलब्ध भएपछि तिनीहरूलाई रेकर्ड गरिनेछ।"</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d मिनेट)</item>
+ <item quantity="one">(%1$d मिनेट) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"आज"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"भोलि"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"हिजो"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"आज <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"भोलि <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"अङ्क"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"रेकर्ड गरिएका कार्यक्रमहरू"</string>
+</resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
deleted file mode 100644
index 142dfade..00000000
--- a/res/values-ne/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"मोनो"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"स्टेरियो"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"प्ले नियन्त्रणहरु"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"भर्खरैका च्यानलहरू"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"टिभी विकल्पहरू"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP विकल्पहरू"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"यस च्यानलका लागि प्ले नियन्त्रणहरू अनुपलब्ध"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"प्ले वा पज"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"फास्ट फर्वार्ड"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"रिवाइन्ड"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"अर्को"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"अघिल्लो"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"कार्यक्रम गाइड"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"नयाँ च्यानलहरू उपलब्ध"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> खोल्नुहोस्"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"बन्द क्याप्सनहरु"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"डिस्प्ले मोड"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"खुला"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"बन्द"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"मल्टि-अडियो"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"अझ बढी च्यानलहरू प्राप्त गर्नुहोस्"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"सेटिङहरू"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"स्रोत"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"स्वाप"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"खुला"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"बन्द"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"आवाज"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"मुख्य"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP सन्झ्याल"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"लेआउट"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"तल्लो दायाँ"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"माथिल्लो दायाँ"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"माथिल्लो बायाँ"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"तल्लो बायाँ"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"सँगसँगै"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"आकार"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"ठूलो"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"सानो"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"इनपुट स्रोत"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"टिभी (एन्टेना/केबल)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"कुनै पनि कार्यक्रम जानकारी छैन"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"केही सूचना छैन"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"अवरुद्ध च्यानल"</string>
- <string name="default_language" msgid="4122326459624337928">"अज्ञात भाषा"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"उपशीर्षक"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"बन्द गर्नुहोस्"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"फर्‍म्याटिङ अनुकूलित"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"बन्द क्याप्सनका लागि प्रणाली-विस्तृत प्राथमिकताहरू सेट गर्नुहोस्"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"डिस्प्ले मोड"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"मल्टि-अडियो"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"मोनो"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"स्टेरियो"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"५.१ सराउन्ड"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"७.१ सराउन्ड"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d च्यानलहरु"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"च्यानल सूची अनुकूलन गर्नुहोस्"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"समूह छान्नुहोस्"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"समूह अचयन नगर्नुहोस्"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"द्वारा समूह"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"च्यानल स्रोत"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"द्वारा समूह"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"यो कार्यक्रम निषेध गरिएको छ।"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"यो कार्यक्रम मूल्याङ्कन <xliff:g id="RATING">%1$s</xliff:g> गरिएको छ"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"इनपुटले स्वतः स्क्यान समर्थन गर्दैन"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' का लागि स्वतः स्क्यान सुरु गर्न असमर्थ"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"बन्द क्याप्सनका लागि प्रणाली-विस्तृत प्राथमिकताहरू सुरु गर्न असमर्थ।"</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d च्यानलहरू थपिए</item>
- <item quantity="one">%1$d च्यानल थपियो</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"कुनै पनि च्यानल थपिएन"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ट्यूनर"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"मुख्य नियन्त्रणहरू"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"खोल्नुहोस्"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"बन्द गर्नुहोस्"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"च्यानलहरू अवरुद्ध"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"सबै ब्लक गर्नुहोस्"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"सबै अनब्लक गर्नुहोस्"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"लुकेका च्यानलहरू"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"कार्यक्रम प्रतिबन्धहरू"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN फेर्नुहोस्"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"मूल्याङ्कन प्रणालीहरू"</string>
- <string name="option_ratings" msgid="4009116954188688616">"मूल्याङ्कन"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"सबै मूल्याङ्कन प्रणाली हेर्नुहोस्"</string>
- <string name="other_countries" msgid="8342216398676184749">"अन्य देशहरू"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"कुनै पनि होइन"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"कुनै पनि होइन"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"कुनै पनि होइन"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"उच्च प्रतिबन्धहरू"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"मध्यम प्रतिबन्धहरू"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"न्यून प्रतिबन्धहरू"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"अनुकूलन"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"बालबालिकाका लागि उपयुक्त सामग्री"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"ठूला बच्चाहरुका लागि उपयुक्त सामग्री"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"किशोर किशोरीहरुका लागि उपयुक्त सामग्री"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"मेनुअल प्रतिबन्धहरु"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s र सहायक स्तर निर्धारण"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"सहायक स्तर निर्धारण"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"यो च्यानल हेर्न तपाईँको PIN प्रविष्टि गर्नुहोस्"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"यो कार्यक्रम हेर्न तपाईँको PIN प्रविष्टि गर्नुहोस्"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"यस कार्यक्रमलाई <xliff:g id="RATING">%1$s</xliff:g> भनेर मूल्याङ्कन गरिएको छ। यो कार्यक्रम हेर्न आफ्नो PIN प्रविष्ट गर्नुहोस्"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"आफ्नो पिन प्रविष्ट गर्नुहोस्"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"अभिभावकत्वको नियन्त्रण सेट गर्न, एउटा PIN सिर्जना गर्नुहोस्"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"नयाँ PIN प्रविष्टि गर्नुहोस्"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"तपाईँको PIN को पुष्टि गर्नुहोस्"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"तपाईंको हालको पिन प्रविष्ट गर्नुहोस्"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">तपाईंले ५ पटक गलत PIN प्रविष्ट गर्नुभयो।\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> सेकेन्डमा पुन: प्रयास गर्नुहोस्।</item>
- <item quantity="one">तपाईंले ५ पटक गलत PIN प्रविष्ट गर्नुभयो।\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> सेकेन्डमा पुन: प्रयास गर्नुहोस्।</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"त्यो PIN गलत थियो। पुनः प्रयास गर्नुहोस्।"</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"पुनः प्रयास गर्नुहोस्, PIN मेल खाँदैन"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"सेटिङहरू"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"च्यानलको सूची अनुकूलन गर्नुहोस्"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"आफ्नो कार्यक्रम निर्देशिकाको लागि च्यानलहरू छनौट गर्नुहोस्"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"च्यानलका स्रोतहरू"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"नयाँ च्यानलहरू उपलब्ध छन्"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"अभिभावकीय नियन्त्रणहरू"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"स्रोतका इजाजतपत्रहरू खोल्नुहोस्"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"खुला स्रोत इजाजतपत्रहरू"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"संस्करण"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"यो च्यानल हेर्न, दायाँ प्रेस गर्नुहोस् र आफ्नो पिन प्रविष्ट गर्नुहोस्"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"यो कार्यक्रम हेर्न, दायाँ प्रेस गर्नुहोस् र आफ्नो पिन प्रविष्ट गर्नुहोस्"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"यो कार्यक्रम मूल्याङ्कन <xliff:g id="RATING">%1$s</xliff:g> गरिएको छ।\nयो कार्यक्रम हेर्न, दायाँ थिच्नुहोस् र आफ्नो PIN प्रविष्ट गर्नुहोस्।"</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"यो च्यानल हेर्न, पूर्वनिर्धारित लाइभ TV अनुप्रयोग प्रयोग गर्नुहोस्।"</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"यो कार्यक्रम हेर्न, पूर्वनिर्धारित लाइभ TV अनुप्रयोगको प्रयोग गर्नुहोस्।"</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"यो कार्यक्रम मूल्याङ्कन गरिएको छ <xliff:g id="RATING">%1$s</xliff:g>।\n यो कार्यक्रम हेर्न, पूर्वनिर्धारित लाइभ TV अनुप्रयोग प्रयोग गर्नुहोस्।"</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"प्रोग्राम ब्लक गरिएको छ"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"यो कार्यक्रम मूल्याङ्कन <xliff:g id="RATING">%1$s</xliff:g> गरिएको छ"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"अडियो मात्र"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"सिग्नल कमजोर छ"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"इन्टरनेटमा जडान गर्न सकिएन"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">अन्य च्यानलहरू रेकर्ड भइरहेका हुनाले <xliff:g id="END_TIME_1">%1$s</xliff:g> सम्म यो च्यानल प्ले गर्न सकिँदैन। \n\nरेकर्डिङको समय तालिकालाई समायोजन गर्न दायाँ बटन थिच्नुहोस्।</item>
- <item quantity="one">अर्को च्यानल रेकर्ड भइरहेको हुनाले <xliff:g id="END_TIME_0">%1$s</xliff:g> सम्म यो च्यानल प्ले गर्न सकिँदैन। \n\nरेकर्डिङको समय तालिकालाई समायोजन गर्न दायाँ बटन थिच्नुहोस्।</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"शीर्षक छैन"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"च्यानल अवरुद्ध"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"नयाँ"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"स्रोतहरू"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d च्यानलहरू</item>
- <item quantity="one">%1$d च्यानल</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"कुनै च्यानलहरू उपलब्ध छैनन्"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"नयाँ"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"सेटअप गरिएको छैन"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"थप स्रोतहरू प्राप्त गर्नुहोस्"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"लाइभ च्यानलहरू प्रस्तुत गर्ने अनुप्रयोगहरू ब्राउज गर्नुहोस्"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"उपलब्ध नयाँ च्यानलका स्रोतहरू"</string>
- <string name="new_sources_description" msgid="749649005588426813">"नयाँ च्यानलका स्रोतहरुसँग प्रस्ताव गर्न च्यानलहरू छन्। \n अहिले तिनीहरूलाई सेट गर्नुहोस् वा च्यानल स्रोतहरुका सेटिङमा पछि गर्नुहोस्।"</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"अब सेटअप गर्नुहोस्"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"ठीक छ, बुँझें"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"टिभी मेनु खोल्न "<b>"SELECT थिच्नुहोस्"</b>"।"</string>
- <string name="msg_no_input" msgid="3897674146985427865">"कुनै पनि टिभी स्रोत भेटिएन।"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"टिभी स्रोत भेटिएन लागेन"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP समर्थित छैन"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP सँग देखाउन सकिने कुनै स्रोत उपलब्ध छैन।"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ट्यूनर प्रकार अनुपयुक्त। कृपया ट्यूनर प्रकार टिभी स्रोतको लागि Live TV को अनुप्रयोग सुरु गर्नुहोस।"</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"ट्युन गर्न असफल"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"यो कार्य सम्हाल्न कुनै पनि अनुप्रयोग भेटिएन।"</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"सबै स्रोत च्यानलहरू लुकेको छन्। \n हेर्नको लागि कम्तीमा एक च्यानल चयन गर्नुहोस्।"</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"भिडियो अप्रत्याशित रूपमा अनुपलब्ध।"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"BACK कुञ्जी जडान भएका उपकरणका लागि हो। बाहिर निस्कनका लागि गृह बटन थिच्नुहोस्।"</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"लाइभ च्यानलहरुलाई TV सूचीहरूलाई पढ्न अनुमति आवश्यक पदर्छ।"</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"आफ्नो स्रोतहरू सेट अप गर्नुहोस्"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"लाइभ च्यानलहरूले TV च्यानलहरूसँगै उपलब्ध गराइएका प्रवाह भइरहेका च्यानलहरूको परम्परागत अनुभवलाई संयोजन गर्छ। \n\nपहिले नै स्थापित च्यानल स्रोतहरू सेट अप गरेर सुरू गरौं। वा लाइभ च्यानलहरू प्रस्ताव गर्ने अझ बढी अनुप्रयोगहरूका लागि Google Play स्टोर ब्राउज गर्नुहोस्।"</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"रेकर्डिङ र समयतालिकाहरू"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"१० मिनेट"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"३० मिनेट"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"१ घन्टा"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"३ घन्टा"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"हालको"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"तालिकाबद्ध गरिएको"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"श्रृंखला"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"अन्य"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"यो च्यानल रेकर्ड गर्न सकिँदैन।"</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"यो कार्यक्रम रेकर्ड गर्न सकिँदैन।"</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> लाई रेकर्ड गर्ने कार्यतालिका निर्धारण गरिएको छ"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"अहिले देखि <xliff:g id="ENDTIME">%2$s</xliff:g> सम्म <xliff:g id="PROGRAMNAME">%1$s</xliff:g> नामक कार्यक्रम रेकर्ड गर्दै"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"समय सहितको पूर्ण कार्यतालिका"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">आगामी %1$d दिन</item>
- <item quantity="one">आगामी %1$d दिन</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d मिनेट</item>
- <item quantity="one">%1$d मिनेट</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d नयाँ रेकर्डिङहरू</item>
- <item quantity="one">%1$d नयाँ रेकर्डिङ</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d रेकर्डिङहरू</item>
- <item quantity="one">%1$d रेकर्डिङ</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d रेकर्डिङहरूको समय निर्धारण गरियो</item>
- <item quantity="one">%1$d रेकर्डिङको समय निर्धारण गरियो</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"हेर्नुहोस्"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"सुरुबाट चलाउनुहोस्"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"पुनःसुरु गर्नुहोस्"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"मेट्नुहोस्"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"रेकर्डिङहरू मेट्नुहोस्"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"पुनःसुरु गर्नु"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"सत्र <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"समयतालिका हेर्नु"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"थप पढ्नुहोस्"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"रेकर्डिङ मेट्नुहोस्"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"तपाईँले मेट्न चाहनुहुने एपिसोडहरूलाई चयन गर्नुहोस्। एक पटक मेटाएपछि तिनीहरूलाई पुन:प्राप्त गर्न सकिँदैन।"</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"मेट्नका लागि कुनै रेकर्डिङ छैन।"</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"हेरिएका एपिसोड चयन गर्नुहोस्"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"सबै एपिसोडहरू चयन गर्नुहोस्"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"सबै एपिसोडहरू चयन नगर्नुहोस्"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> मिनेट मध्ये <xliff:g id="WATCHED">%1$d</xliff:g> मिनेट हेरियो"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> सेकेन्ड मध्ये <xliff:g id="WATCHED">%1$d</xliff:g> सेकेन्ड हेरियो"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"कहिल्यै नहेरिएका"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%2$d मध्ये %1$d एपिसोडहरू मेटाइए</item>
- <item quantity="one">%2$d मध्ये %1$d एपिसोड मेटाइयो</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"प्राथमिकता"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"सबैभन्दा उच्च"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"सबैभन्दा न्यून"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"नम्बर <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"च्यानलहरू"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"जुनसुकै"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"प्राथमिकता छान्नुहोस्"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"एकै समयमा अत्यन्त धेरै कार्यक्रमहरू रेकर्ड गर्नुपर्ने भएकाले उच्च प्राथमिकता भएका कार्यक्रमहरूलाई मात्र रेकर्ड गरिनेछ।"</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"सुरक्षित गर्नुहोस्"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"एक-पटके रेकर्डिङहरूलाई सबैभन्दा उच्च प्राथमिकता दिइन्छ"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"रद्द गर्नु"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"रद्द गर्नुहोस्"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"बिर्सनुहोस्"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"रोक्नुहोस्"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"रेकर्डिङको समयतालिका हेर्नुहोस्"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"यो कार्यक्रम मात्र"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"अहिले - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"सम्पूर्ण शृंखला…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"जे भए पनि समय निर्धारण गर्नुहोस्"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"बरु यो रेकर्ड गर्नुहोस्"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"यस रेकर्डिङलाई रद्द गर्नुहोस्"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"अहिले हेर्नुहोस्"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"रेकर्ड गर्न मिल्ने"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"रेकर्डिङको कार्यतालिका निर्धारण गरिएको छ"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"रेकर्डिङ सम्बन्धी असहमति"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"रेकर्ड गर्दै"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"रेकर्डिङ गर्न सकिएन"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"रेकर्डिङका समय तालिकाहरू सिर्जना गर्न कार्यक्रमहरू पढ्दै"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"कार्यक्रमहरूको जानकारी पढ्दै"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR लाई थप भण्डारण चाहिन्छ"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"तपाईँले DVR मार्फत कार्यक्रमहरू रेकर्ड गर्न सक्नुहुनेछ। यद्यपि, अहिले तपाईँको यन्त्रमा DVR ले काम गर्न पुग्ने गरी पर्याप्त भण्डारण छैन। कृपया <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> जि.बि.वा सो भन्दा बढी भण्डारण क्षमता भएको कुनै बाह्य ड्राइभ जडान गर्नुहोस् र त्यसलाई यन्त्रको भण्डारणका रूपमा फर्म्याट गर्न आवश्यक कदमहरू चाल्नुहोस्।"</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"भण्डारण उपलब्ध छैन"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR ले प्रयोग गरेको केही भण्डारण उपलब्ध छैन। DVR लाई पुन: सक्षम पार्न कृपया तपाईँले पहिले प्रयोग गर्नुभएको बाह्य ड्राइभलाई जडान गर्नुहोस्। वैकल्पिक रूपमा, यदि अब भण्डारण उपलब्ध छैन भने तपाईँ त्यसलाई बिर्सने विकल्प छान्न सक्नुहुन्छ।"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"भण्डारण बिर्सने हो?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"तपाईँका रेकर्ड गरिएका सबै सामग्री र समय सहितका कार्यतालिकाहरू हराउने छन्।"</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"रेकर्डिङ रोक्ने हो?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"रेकर्ड गरिएको सामग्रीलाई सुरक्षित गरिनेछ।"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"रेकर्डिङको कार्यतालिका निर्धारण गरिएको छ तर यसमा असहमतिहरू छन्"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"रेकर्डिङ सुरु भएको छ तर यसमा असहमतिहरू छन्"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> लाई रेकर्ड गरिनेछ।"</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> लाई रेकर्ड गरिँदै छ।"</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> का केही भागहरूलाई रेकर्ड गरिने छैन।"</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> र <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> का केही भागहरूलाई रेकर्ड गरिने छैन।"</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> र थप एक कार्यक्रमका केही भागहरूलाई रेकर्ड गरिने छैन।"</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> र थप %3$d कार्यक्रमहरूलाई रेकर्ड गरिने छैन।</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> र थप %3$d कार्यक्रमलाई रेकर्ड गरिने छैन।</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"तपाईँ के रेकर्ड गर्न चाहनुहुन्छ?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"तपाईँ कति बेरसम्म रेकर्ड गर्न चाहनुहुन्छ?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"पहिले नै समय सहितको कार्यतालिका निर्धारण गरिएको छ"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"यस कार्यक्रमलाई पहिले नै <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> मा रेकर्ड गर्न समय सहितको कार्यतालिका निर्धारण गरिएको छ।"</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"पहिले नै रेकर्ड गरिएको छ"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"यस कार्यक्रमलाई पहिले नै रेकर्ड गरिएको छ। यो DVR को लाइब्रेरीमा उपलब्ध छ।"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"रेकर्ड गरिएको कार्यक्रम भेट्टिएन।"</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"सम्बन्धित रेकर्डिङहरू"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(कार्यक्रम सम्बन्धी वर्णन छैन)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d रेकर्डिङ</item>
- <item quantity="one">%1$d रेकर्डिङ</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> लाई रेकर्डिङको समय सहितको कार्यतालिकाबाट हटाइयो"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ट्युनर सम्बन्धी असहमतिका कारण आंशिक रूपमा रेकर्ड गरिनेछ।"</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ट्युनर सम्बन्धी असहमतिका कारण रेकर्ड गरिने छैन।"</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"अहिलेसम्म समय सहितको कार्यतालिका निर्धारण गरिएको कुनै रेकर्डिङ छैन।\nतपाईँ कार्यक्रम निर्देशिका मार्फत रेकर्डिङको समय सहितको कार्यतालिका निर्धारण गर्न सक्नुहुन्छ।"</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">रेकर्डिङ सम्बन्धी %1$d असहमतिहरू</item>
- <item quantity="one">रेकर्डिङ सम्बन्धी %1$d असहमति</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"शृंखला सम्बन्धी सेटिङहरू"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"शृंखलाको रेकर्डिङ सुरु गर्नुहोस्"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"शृंखलाको रेकर्डिङ रोक्नुहोस्"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"शृंखलाको रेकर्डिङ रोक्ने हो?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"रेकर्ड गरिएका एपिसोडहरू DVR सम्बन्धी लाइब्रेरीमा उपलब्ध रहनेछन्।"</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"रोक्नुहोस्"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"कुनै एपिसोड उपलब्ध छैन।\nएपिसोडहरू उपलब्ध भएपछि तिनीहरूलाई रेकर्ड गरिनेछ।"</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d मिनेट)</item>
- <item quantity="one">(%1$d मिनेट) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"आज"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"भोलि"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"हिजो"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"आज <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"भोलि <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"अङ्क"</string>
-</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index f24ed1c3..a3e9dfed 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Afspeelknoppen"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Recente kanalen"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanalen"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Tv-opties"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP-opties"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Er zijn geen afspeelknoppen beschikbaar voor dit kanaal"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Afspelen of onderbreken"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Vooruitspoelen"</string>
@@ -32,36 +31,18 @@
<string name="channels_item_program_guide" msgid="2889807207930678418">"Programmagids"</string>
<string name="channels_item_setup" msgid="6557412175737379022">"Nieuwe kanalen beschikbaar"</string>
<string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> openen"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Ondertiteling"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Ondertitels"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Weergavemodus"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Aan"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Uit"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Kanalen ophalen"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Instellingen"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Bron"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Wisselen"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Aan"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Uit"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Geluid"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Hoofd"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP-venster"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Lay-out"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Rechtsonder"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Rechtsboven"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Linksboven"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Linksonder"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Naast elkaar"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Formaat"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Groot"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Klein"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Invoerbron"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"Tv (antenne/kabel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Geen programmagegevens"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Geen informatie"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Geblokkeerd kanaal"</string>
- <string name="default_language" msgid="4122326459624337928">"Onbekende taal"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Onbekende taal"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Ondertiteling %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Ondertiteling"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Uit"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Opmaak aanpassen"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Groeperen op"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Dit programma is geblokkeerd"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Dit programma is niet geclassificeerd"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Dit programma is beoordeeld als <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"De invoer biedt geen ondersteuning voor automatisch scannen"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Kan automatisch zoeken naar \'<xliff:g id="TV_INPUT">%s</xliff:g>\' niet starten"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d kanaal toegevoegd</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Geen kanalen toegevoegd"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Ouderlijk toezicht"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Aan"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Uit"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Andere landen"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Geen"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Geen"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Niet geclassificeerd"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Niet-geclas. prog. blokkeren"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Geen"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Strenge beperkingen"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Gem. beperkingen"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Je pincode opgeven om dit kanaal te bekijken"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Je pincode opgeven om dit programma te bekijken"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Dit programma heeft de classificatie <xliff:g id="RATING">%1$s</xliff:g>. Geef je pincode op om dit programma te bekijken."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Dit programma is niet geclassificeerd. Geef je pincode op om dit programma te bekijken."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Je pincode opgeven"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Stel een pincode in om ouderlijk toezicht in te stellen"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Nieuwe pincode opgeven"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Die pincode is onjuist. Probeer het opnieuw."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Probeer het opnieuw; de pincode komt niet overeen"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Je postcode opgeven"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"De app Live tv gebruikt je postcode om een volledige programmagids voor de tv-kanalen aan te leveren."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Geef je postcode op"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Ongeldige postcode"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Instellingen"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Kanaallijst aanpassen"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Kanalen kiezen voor je tv-gids"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanaalbronnen"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Nieuwe kanalen beschikbaar"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Ouderlijk toezicht"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Tijdverschuiving"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Neem op tijdens het kijken zodat je live programma\'s kunt onderbreken of terugspoelen.\nWaarschuwing: De levensduur van de interne opslag kan afnemen door het intensieve gebruik."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Open-sourcelicenties"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Open-sourcelicenties"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Feedback verzenden"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versie"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Als je dit kanaal wilt bekijken, druk je rechts en geef je je pincode op"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Als je dit programma wilt bekijken, druk je rechts en geef je je pincode op"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Dit programma is niet geclassificeerd.\nAls je dit programma wilt bekijken, druk je op Rechts en geef je je pincode op."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Dit programma is beoordeeld als <xliff:g id="RATING">%1$s</xliff:g>.\nAls je dit programma wilt bekijken, druk je rechts en geef je je pincode op."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Gebruik de standaardapp voor live tv om dit kanaal te bekijken."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Gebruik de standaardapp voor live tv om dit programma te bekijken."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Dit programma is niet geclassificeerd.\nAls je dit programma wilt bekijken, gebruik je de standaard-app voor live tv."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Dit programma heeft de classificatie <xliff:g id="RATING">%1$s</xliff:g>.\nGebruik de standaardapp voor live tv om dit programma te bekijken."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programma is geblokkeerd"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Dit programma is niet geclassificeerd"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Dit programma is beoordeeld als <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Alleen audio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Zwak signaal"</string>
@@ -181,15 +174,13 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Druk op SELECTEREN"</b>" voor toegang tot het tv-menu."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Geen tv-invoer gevonden"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Kan de tv-invoer niet vinden"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP wordt niet ondersteund"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Geen beschikbare invoer die kan worden weergegeven met PIP"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tunertype is geen geschikte optie. Start de app Live kanalen voor tv-invoer van het type tuner."</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tunertype is geen geschikte optie. Start de Live tv-app voor tv-invoer van het type tuner."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Afstemmen mislukt"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Er is geen app gevonden om deze actie uit te voeren."</string>
<string name="msg_all_channels_hidden" msgid="777397634062471936">"Alle bronkanalen zijn verborgen.\nSelecteer ten minste één kanaal om te bekijken."</string>
<string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"De video is onverwacht niet beschikbaar"</string>
<string name="msg_back_key_guide" msgid="7404682718828721924">"De toets TERUG is voor verbonden apparaten. Druk op de knop HOME om te sluiten."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"De app \'Live kanalen\' heeft toestemming nodig om tv-vermeldingen te lezen."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"De app \'Live tv\' heeft toestemming nodig om tv-vermeldingen te lezen."</string>
<string name="setup_sources_text" msgid="4988039637873759839">"Je bronnen configureren"</string>
<string name="setup_sources_description" msgid="5695518946225445202">"Live tv combineert de functionaliteit van traditionele tv-kanalen met streaming kanalen die worden geleverd door apps. \n\nJe kunt aan de slag gaan door de kanaalbronnen te configureren die al zijn geïnstalleerd. Of browse in de Google Play Store voor meer apps die live tv aanbieden."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Opnamen en planningen"</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d opnamen gepland</item>
<item quantity="one">%1$d opname gepland</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Opname annuleren"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Opname stoppen"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Bekijken"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Afspelen vanaf het begin"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Afspelen hervatten"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Wanneer er te veel programma\'s tegelijk moeten worden opgenomen, worden alleen de programma\'s met de hogere prioriteit opgenomen."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Opslaan"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Eenmalige opnamen krijgen de hoogste prioriteit"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Annuleren"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Annuleren"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Vergeten"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Stoppen"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Opnameschema bekijken"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Dit afzonderlijke programma"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Dit programma opnemen"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Deze opname annuleren"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Nu bekijken"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Opnamen verwijderen"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Kan worden opgenomen"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Opname gepland"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Opnameconflict"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Opnemen"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Opname mislukt"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Programma\'s lezen om opnameplanningen te maken"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Programma\'s lezen"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Programma\'s lezen"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Recente opnamen bekijken"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"De opname van <xliff:g id="PROGRAMNAME">%1$s</xliff:g> is niet voltooid."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"De opnamen van <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> en <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> zijn niet voltooid."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"De opnamen van <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> en <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> zijn niet voltooid."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"De opname van <xliff:g id="PROGRAMNAME">%1$s</xliff:g> is niet voltooid vanwege onvoldoende opslagruimte."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"De opnamen van <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> en <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> zijn niet voltooid vanwege onvoldoende opslagruimte."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"De opnamen van <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> en <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> zijn niet voltooid vanwege onvoldoende opslagruimte."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Voor DVR is meer opslagruimte nodig"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Je kunt programma\'s opnemen met DVR. Er is echter momenteel onvoldoende opslagruimte beschikbaar op je apparaat om DVR te gebruiken. Sluit een externe schijf aan die <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB of groter is en volg de stappen om deze te formatteren als apparaatopslag."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Je kunt programma\'s opnemen met DVR. Er is echter momenteel onvoldoende opslagruimte beschikbaar op je apparaat om DVR te gebruiken. Sluit een externe schijf aan die <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB of groter is en volg de stappen om deze te formatteren als apparaatopslag."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Onvoldoende opslagruimte"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Dit programma wordt niet opgenomen omdat er onvoldoende opslagruimte is. Verwijder een aantal bestaande opnamen."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Opslag ontbreekt"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Een deel van de opslagruimte ontbreekt die door de DVR wordt gebruikt. Sluit de externe schijf aan die je eerder hebt gebruikt om DVR opnieuw in te schakelen. Je kunt er ook voor kiezen de opslagruimte te vergeten als deze niet langer beschikbaar is."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Opslag vergeten?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Al je opgenomen content en planningen gaan verloren."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Opname stoppen?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"De opgenomen content wordt opgeslagen."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"De opname van <xliff:g id="PROGRAMNAME">%1$s</xliff:g> wordt gestopt omdat deze conflicteert met dit programma. De opgenomen content wordt opgeslagen."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Opname ingepland, maar heeft conflicten"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"De opname is gestart, maar heeft conflicten"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> wordt opgenomen."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Hetzelfde programma is al ingepland voor opname om <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Al opgenomen"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Dit programma is al opgenomen. Het is beschikbaar in de DVR-bibliotheek."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Serie-opname gepland"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">Er zijn <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> opnamen gepland voor <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one">Er is <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opname gepland voor <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">Er zijn <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> opnamen gepland voor <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> hiervan worden niet opgenomen vanwege conflicten.</item>
+ <item quantity="one">Er is <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opname gepland voor <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Dit wordt niet opgenomen vanwege conflicten.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">Er zijn <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> opnamen gepland voor <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> afleveringen van deze serie en andere series worden niet opgenomen vanwege conflicten.</item>
+ <item quantity="one">Er is <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opname gepland voor <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> afleveringen van deze serie en andere series worden niet opgenomen vanwege conflicten.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">Er zijn <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> opnamen gepland voor <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 aflevering van andere series wordt niet opgenomen vanwege conflicten.</item>
+ <item quantity="one">Er is <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opname gepland voor <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 aflevering van andere series wordt niet opgenomen vanwege conflicten.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">Er zijn <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> opnamen gepland voor <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> afleveringen van andere series worden niet opgenomen vanwege conflicten.</item>
+ <item quantity="one">Er is <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> opname gepland voor <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> afleveringen van andere series worden niet opgenomen vanwege conflicten.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Opgenomen programma niet gevonden."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Gerelateerde opnamen"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Geen programmabeschrijving)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d opnamen</item>
<item quantity="one">%1$d opname</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Serie-opname stoppen?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Opgenomen afleveringen blijven beschikbaar in de DVR-bibliotheek."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Stoppen"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Er worden nu geen afleveringen uitgezonden."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Er zijn geen afleveringen beschikbaar.\nZe worden opgenomen zodra ze beschikbaar zijn."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minuten)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> vandaag"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> morgen"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Score"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Opgenomen programma\'s"</string>
</resources>
diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa-rIN/strings.xml
new file mode 100644
index 00000000..5415e3bc
--- /dev/null
+++ b/res/values-pa-rIN/strings.xml
@@ -0,0 +1,356 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"ਮੋਨੋ"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"ਸਟੀਰੀਓ"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"ਪਲੇਬੈਕ ਕੰਟਰੋਲ"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"ਚੈਨਲ"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"ਟੀਵੀ ਵਿਕਲਪ"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"ਪਲੇਬੈਕ ਕੰਟਰੋਲ ਇਸ ਚੈਨਲ ਲਈ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ਚਲਾਓ ਜਾਂ ਰੋਕੋ"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ਤੇਜ਼ੀ ਨਾਲ ਅੱਗੇ ਕਰੋ"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"ਪਿੱਛੇ ਕਰੋ"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"ਅੱਗੇ"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"ਪਿੱਛੇ"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"ਪ੍ਰੋਗਰਾਮ ਗਾਈਡ"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"ਨਵੇਂ ਚੈਨਲ ਉਪਲਬਧ ਹਨ"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਖੋਲ੍ਹੋ"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"ਬੰਦ ਸੁਰਖੀਆਂ"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"ਡਿਸਪਲੇ ਮੋਡ"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"ਮਲਟੀ-ਔਡੀਓ"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"ਹੋਰ ਚੈਨਲ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"ਸੈਟਿੰਗਾਂ"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"ਟੀਵੀ (ਐਂਟੀਨਾ/ਕੇਬਲ)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"ਕੋਈ ਪ੍ਰੋਗਰਾਮ ਸਬੰਧੀ ਜਾਣਕਾਰੀ ਨਹੀਂ"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"ਕੋਈ ਜਾਣਕਾਰੀ ਨਹੀਂ"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"ਬਲੌਕ ਕੀਤਾ ਚੈਨਲ"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"ਅਗਿਆਤ ਭਾਸ਼ਾ"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"ਬੰਦ ਸੁਰਖੀਆਂ %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"ਬੰਦ ਸੁਰਖੀਆਂ"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ਬੰਦ"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"ਵੰਨਗੀਕਰਨ ਨੂੰ ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"ਬੰਦ ਸੁਰਖੀਆਂ ਦੇ ਲਈ ਸਿਸਟਮ-ਵਿਆਪਕ ਤਰਜੀਹਾਂ ਸੈੱਟ ਕਰੋ"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ਡਿਸਪਲੇ ਮੋਡ"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"ਮਲਟੀ-ਔਡੀਓ"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"ਮੋਨੋ"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ਸਟੀਰੀਓ"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 ਸਰਾਊਂਡ"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 ਸਰਾਊਂਡ"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ਚੈਨਲ"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ਚੈਨਲ ਸੂਚੀ ਨੂੰ ਵਿਸ਼ੇਸ਼ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"ਗਰੁੱਪ ਚੁਣੋ"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"ਗਰੁੱਪ ਨੂੰ ਅਣਚੁਣਿਆ ਕਰੋ"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ਇਸ ਅਨੁਸਾਰ ਗਰੁੱਪ ਬਣਾਓ"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ਚੈਨਲ ਸਰੋਤ"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"ਇਸ ਅਨੁਸਾਰ ਗਰੁੱਪ ਬਣਾਓ"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"ਇਹ ਪ੍ਰੋਗਰਾਮ ਬਲੌਕ ਕੀਤਾ ਹੋਇਆ ਹੈ"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"ਇਹ ਪ੍ਰੋਗਰਾਮ ਰੇਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"ਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ <xliff:g id="RATING">%1$s</xliff:g> ਰੇਟ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"ਇਨਪੁਟ ਸਵੈ-ਸਕੈਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' ਲਈ ਸਵੈ-ਸਕੈਨ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਦੇ ਅਯੋਗ"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"ਬੰਦ ਸੁਰਖੀਆਂ ਲਈ ਸਿਸਟਮ-ਵਿਆਪਕ ਤਰਜੀਹਾਂ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਦੇ ਅਯੋਗ।"</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">%1$d ਚੈਨਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ</item>
+ <item quantity="other">%1$d ਚੈਨਲ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"ਕੋਈ ਚੈਨਲ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤੇ ਗਏ"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"ਮਾਪਿਆਂ ਦੇ ਕੰਟਰੋਲ"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ਚਾਲੂ"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ਬੰਦ"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"ਚੈਨਲ ਬਲੌਕ ਕੀਤੇ ਗਏ"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"ਸਭ ਬਲੌਕ ਕਰੋ"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"ਸਭ ਅਣਬਲੌਕ ਕਰੋ"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"ਲੁਕੇ ਹੋਏ ਚੈਨਲ"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"ਪ੍ਰੋਗਰਾਮ ਪਾਬੰਦੀਆਂ"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN ਬਦਲੋ"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"ਰੇਟਿੰਗ ਸਿਸਟਮ"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"ਰੇਟਿੰਗਾਂ"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"ਸਭ ਰੇਟਿੰਗ ਸਿਸਟਮ ਵੇਖੋ"</string>
+ <string name="other_countries" msgid="8342216398676184749">"ਹੋਰ ਦੇਸ਼"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"ਕੋਈ ਨਹੀਂ"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ਕੋਈ ਨਹੀਂ"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"ਰੇਟਿੰਗ-ਰਹਿਤ"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"ਰੇਟਿੰਗ-ਰਹਿਤ ਪ੍ਰੋਗਰਾਮ ਬਲੌਕ ਕਰੋ"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"ਕੋਈ ਨਹੀਂ"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"ਉੱਚ ਪਾਬੰਦੀਆਂ"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"ਦਰਮਿਆਨੀਆਂ ਪਾਬੰਦੀਆਂ"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"ਘੱਟ ਪਾਬੰਦੀਆਂ"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"ਬੱਚਿਆਂ ਲਈ ਉਚਿਤ ਸਮੱਗਰੀ"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"ਵੱਡੇ ਬੱਚਿਆਂ ਲਈ ਉਚਿਤ ਸਮੱਗਰੀ"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"ਅੱਲੜ੍ਹਾਂ ਲਈ ਉਚਿਤ ਸਮੱਗਰੀ"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"ਦਸਤੀ ਪਾਬੰਦੀਆਂ"</string>
+ <string name="option_attribution" msgid="2967657807178951562">"ਰੇਟਿੰਗ ਵਰਣਨਾਂ ਲਈ ਸਰੋਤ"</string>
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s ਅਤੇ ਉੱਪ-ਰੇਟਿੰਗਾਂ"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"ਉੱਪ-ਰੇਟਿੰਗਾਂ"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ਇਹ ਚੈਨਲ ਦੇਖਣ ਲਈ ਆਪਣਾ PIN ਦਾਖਲ ਕਰੋ"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"ਇਹ ਪ੍ਰੋਗਰਾਮ ਦੇਖਣ ਲਈ ਆਪਣਾ PIN ਦਾਖਲ ਕਰੋ"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ <xliff:g id="RATING">%1$s</xliff:g> ਰੇਟ ਕੀਤਾ ਗਿਆ ਹੈ। ਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ ਵੇਖਣ ਲਈ ਆਪਣਾ PIN ਦਾਖਲ ਕਰੋ"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"ਇਹ ਪ੍ਰੋਗਰਾਮ ਰੇਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ। ਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ ਦੇਖਣ ਲਈ ਆਪਣਾ PIN ਦਾਖਲ ਕਰੋ"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"ਆਪਣਾ PIN ਦਾਖਲ ਕਰੋ"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"ਮਾਪਿਆਂ ਦੇ ਕੰਟਰੋਲਾਂ ਨੂੰ ਸੈੱਟ ਕਰਨ ਲਈ, ਇੱਕ PIN ਬਣਾਓ"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"ਨਵਾਂ PIN ਦਾਖਲ ਕਰੋ"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"ਆਪਣੇ PIN ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"ਆਪਣਾ ਮੌਜੂਦਾ PIN ਦਾਖਲ ਕਰੋ"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">ਤੁਸੀਂ 5 ਵਾਰ ਗਲਤ PIN ਦਾਖਲ ਕੀਤਾ\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> ਸਕਿੰਟ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ</item>
+ <item quantity="other">ਤੁਸੀਂ 5 ਵਾਰ ਗਲਤ PIN ਦਾਖਲ ਕੀਤਾ\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"ਉਹ PIN ਗਲਤ ਸੀ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ, PIN ਮੇਲ ਨਹੀਂ ਖਾਂਦਾ"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"ਆਪਣਾ ਜ਼ਿਪ ਕੋਡ ਦਾਖਲ ਕਰੋ।"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"ਲਾਈਵ ਚੈਨਲ ਐਪ ਟੀਵੀ ਚੈਨਲਾਂ ਲਈ ਮੁਕੰਮਲ ਪ੍ਰੋਗਰਾਮ ਗਾਈਡ ਮੁਹੱਈਆ ਕਰਵਾਉਣ ਵਾਸਤੇ ਜ਼ਿਪ ਕੋਡ ਦੀ ਵਰਤੋਂ ਕਰੇਗੀ।"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"ਆਪਣਾ ਜ਼ਿਪ ਕੋਡ ਦਾਖਲ ਕਰੋ"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"ਅਵੈਧ ਜ਼ਿਪ ਕੋਡ"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"ਸੈਟਿੰਗਾਂ"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ਚੈਨਲ ਸੂਚੀ ਨੂੰ ਵਿਸ਼ੇਸ਼ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ਆਪਣੀ ਪ੍ਰੋਗਰਾਮ ਗਾਈਡ ਲਈ ਚੈਨਲ ਚੁਣੋ"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ਚੈਨਲ ਸਰੋਤ"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"ਨਵੇਂ ਚੈਨਲ ਉਪਲਬਧ ਹਨ"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"ਮਾਪਿਆਂ ਦੇ ਕੰਟਰੋਲ"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"ਟਾਈਮ-ਸ਼ਿਫਟ"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"ਟੀਵੀ ਦੇਖਣ ਦੌਰਾਨ ਰਿਕਾਰਡ ਕਰੋ ਤਾਂ ਕਿ ਤੁਸੀਂ ਲਾਈਵ ਪ੍ਰੋਗਰਾਮਾਂ ਨੂੰ ਰੋਕ ਜਾਂ ਪਿੱਛੇ ਲੈ ਜਾ ਸਕੋਂ।\nਚਿਤਾਵਨੀ: ਇਸ ਨਾਲ ਸਟੋਰੇਜ ਦੀ ਵੱਧ ਵਰਤੋਂ ਹੋਣ ਕਰਕੇ ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ ਦਾ ਜੀਵਨਕਾਲ ਘੱਟ ਹੋ ਸਕਦਾ ਹੈ।"</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"ਖੁੱਲ੍ਹਾ ਸਰੋਤ ਲਾਇਸੰਸ"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"ਪ੍ਰਤੀਕਰਮ ਭੇਜੋ"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ਰੂਪ"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"ਇਸ ਚੈਨਲ ਨੂੰ ਵੇਖਣ ਲਈ, &amp;apos;ਸੱਜਾ&amp;apos; ਬਟਨ ਦਬਾਓ ਅਤੇ ਆਪਣਾ PIN ਦਾਖਲ ਕਰੋ"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"ਇਸ ਚੈਨਲ ਨੂੰ ਵੇਖਣ ਲਈ, &amp;apos;ਸੱਜਾ&amp;apos; ਬਟਨ ਦਬਾਓ ਅਤੇ ਆਪਣਾ PIN ਦਾਖਲ ਕਰੋ"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"ਇਹ ਪ੍ਰੋਗਰਾਮ ਰੇਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ।\nਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ ਦੇਖਣ ਲਈ, ਸੱਜਾ ਬਟਨ ਦਬਾਓ ਅਤੇ ਆਪਣਾ PIN ਦਾਖਲ ਕਰੋ"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"ਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ <xliff:g id="RATING">%1$s</xliff:g> ਰੇਟ ਕੀਤਾ ਗਿਆ ਹੈ।\nਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ ਵੇਖਣ ਲਈ, &amp;apos;ਸੱਜਾ&amp;apos; ਬਟਨ ਦਬਾਓ ਅਤੇ ਆਪਣਾ PIN ਦਾਖਲ ਕਰੋ।"</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ਇਸ ਚੈਨਲ ਨੂੰ ਵੇਖਣ ਲਈ, ਪੂਰਵ-ਨਿਰਧਾਰਤ ਲਾਈਵ ਟੀਵੀ ਐਪ ਦੀ ਵਰਤੋਂ ਕਰੋ।"</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ ਵੇਖਣ ਲਈ, ਪੂਰਵ-ਨਿਰਧਾਰਤ ਲਾਈਵ ਟੀਵੀ ਐਪ ਦੀ ਵਰਤੋਂ ਕਰੋ।"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"ਇਹ ਪ੍ਰੋਗਰਾਮ ਰੇਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ।\nਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ ਦੇਖਣ ਲਈ, ਪੂਰਵ-ਨਿਰਧਾਰਤ ਲਾਈਵ ਟੀਵੀ ਅੈਪ ਦੀ ਵਰਤੋਂ ਕਰੋ।"</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ <xliff:g id="RATING">%1$s</xliff:g> ਰੇਟ ਕੀਤਾ ਗਿਆ ਹੈ।\nਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ ਵੇਖਣ ਲਈ, ਪੂਰਵ-ਨਿਰਧਾਰਤ ਲਾਈਵ ਟੀਵੀ ਐਪ ਦੀ ਵਰਤੋਂ ਕਰੋ।"</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"ਪ੍ਰੋਗਰਾਮ ਬਲੌਕ ਕੀਤਾ ਹੋਇਆ ਹੈ"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"ਇਹ ਪ੍ਰੋਗਰਾਮ ਰੇਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ਇਸ ਪ੍ਰੋਗਰਾਮ ਨੂੰ <xliff:g id="RATING">%1$s</xliff:g> ਰੇਟ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ਸਿਰਫ ਔਡੀਓ"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"ਕਮਜ਼ੋਰ ਸਿਗਨਲ"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ਕੋਈ ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਨਹੀਂ"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="one">ਇਸ ਚੈਨਲ ਨੂੰ <xliff:g id="END_TIME_1">%1$s</xliff:g> ਤੱਕ ਨਹੀਂ ਚਲਾਇਆ ਜਾ ਸਕਦਾ ਕਿਉਂਕਿ ਹੋਰ ਚੈਨਲ ਰਿਕਾਰਡ ਕੀਤੇ ਜਾ ਰਹੇ ਹਨ। \n\nਰਿਕਾਰਡਿੰਗ ਦੇ ਨਿਯਤ ਸਮੇਂ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰਨ ਲਈ &amp;apos;ਸੱਜਾ&amp;apos; ਬਟਨ ਦਬਾਓ।</item>
+ <item quantity="other">ਇਸ ਚੈਨਲ ਨੂੰ <xliff:g id="END_TIME_1">%1$s</xliff:g> ਤੱਕ ਨਹੀਂ ਚਲਾਇਆ ਜਾ ਸਕਦਾ ਕਿਉਂਕਿ ਹੋਰ ਚੈਨਲ ਰਿਕਾਰਡ ਕੀਤੇ ਜਾ ਰਹੇ ਹਨ। \n\nਰਿਕਾਰਡਿੰਗ ਦੇ ਨਿਯਤ ਸਮੇਂ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰਨ ਲਈ &amp;apos;ਸੱਜਾ&amp;apos; ਬਟਨ ਦਬਾਓ।</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"ਕੋਈ ਸਿਰਲੇਖ ਨਹੀਂ"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ਚੈਨਲ ਬਲੌਕ ਹੈ"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"ਨਵਾਂ"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"ਸਰੋਤ"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">%1$d ਚੈਨਲ</item>
+ <item quantity="other">%1$d ਚੈਨਲ</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"ਕੋਈ ਚੈਨਲ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"ਨਵਾਂ"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"ਸਥਾਪਤ ਨਹੀਂ"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"ਹੋਰ ਸਰੋਤ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"ਲਾਈਵ ਚੈਨਲਾਂ ਦੀ ਪੇਸ਼ਕਸ਼ ਕਰਦੀਆਂ ਐਪਾਂ ਨੂੰ ਬ੍ਰਾਊਜ਼ ਕਰੋ"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"ਨਵੇਂ ਚੈਨਲ ਸਰੋਤ ਉਪਲਬਧ ਹਨ"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"ਨਵੇਂ ਚੈਨਲ ਸਰੋਤਾਂ ਕੋਲ ਪੇਸ਼ਕਸ਼ ਕਰਨ ਲਈ ਚੈਨਲ ਹਨ।\nਉਹਨਾਂ ਨੂੰ ਹੁਣੇ ਸਥਾਪਤ ਕਰੋ, ਜਾਂ ਇਹ ਬਾਅਦ ਵਿੱਚ ਚੈਨਲ ਸਰੋਤ ਸੈਟਿੰਗ ਵਿੱਚ ਕਰੋ।"</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"ਹੁਣੇ ਸਥਾਪਤ ਕਰੋ"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"ਠੀਕ, ਸਮਝ ਲਿਆ"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"ਟੀਵੀ ਮੀਨੂ \'ਤੇ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ "<b>"&amp;apos;ਚੁਣੋ&amp;apos; ਨੂੰ ਦਬਾਓ"</b>"।"</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"ਕੋਈ ਟੀਵੀ ਇਨਪੁਟ ਨਹੀਂ ਲੱਭੀ"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"ਟੀਵੀ ਇਨਪੁਟ ਨੂੰ ਲੱਭਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ਟਿਊਨਰ ਦੀ ਕਿਸਮ ਉਚਿਤ ਨਹੀਂ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ ਟਿਊਨਰ ਕਿਸਮ ਦੀ ਟੀਵੀ ਇਨਪੁਟ ਲਈ ਲਾਈਵ ਚੈਨਲ ਐਪ ਨੂੰ ਲਾਂਚ ਕਰੋ।"</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ਟਿਊਨ ਅਸਫ਼ਲ ਰਿਹਾ"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"ਇਸ ਕਾਰਵਾਈ ਨਾਲ ਨਿਪਟਣ ਲਈ ਕੋਈ ਐਪ ਨਹੀਂ ਲੱਭੀ।"</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"ਸਾਰੇ ਸਰੋਤ ਚੈਨਲ ਲੁਕੇ ਹੋਏ ਹਨ।\nਵੇਖਣ ਲਈ ਘੱਟੋ-ਘੱਟ ਇੱਕ ਚੈਨਲ ਨੂੰ ਚੁਣੋ।"</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ਵੀਡੀਓ ਫ਼ਾਈਲ ਅਣਕਿਆਸੇ ਤਰੀਕੇ ਨਾਲ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"&amp;apos;ਪਿੱਛੇ&amp;apos; ਕੁੰਜੀ ਕਨੈਕਟ ਕੀਤੀ ਡੀਵਾਈਸ ਲਈ ਹੈ। ਬਾਹਰ ਜਾਣ ਲਈ ਹੋਮ ਬਟਨ ਦਬਾਓ।"</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"ਲਾਈਵ ਚੈਨਲਾਂ ਨੂੰ ਟੀਵੀ ਸੂਚੀਆਂ ਪੜ੍ਹਨ ਲਈ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੈ।"</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"ਆਪਣੇ ਸਰੋਤਾਂ ਦੀ ਸਥਾਪਨਾ ਕਰੋ"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"ਲਾਈਵ ਚੈਨਲ ਐਪ ਰਵਾਇਤੀ ਟੀਵੀ ਚੈਨਲਾਂ ਦੇ ਅਨੁਭਵ ਨਾਲ ਐਪਾਂ ਦੁਆਰਾ ਮੁਹੱਈਆ ਕੀਤੇ ਸਟ੍ਰੀਮਿੰਗ ਚੈਨਲਾਂ ਦੇ ਅਨੁਭਵ ਨੂੰ ਮਿਲਾਉਂਦੀ ਹੈ। \n\nਪਹਿਲਾਂ ਤੋਂ ਸਥਾਪਤ ਕੀਤੇ ਚੈਨਲ ਸਰੋਤਾਂ ਦੀ ਸਥਾਪਨਾ ਕਰਕੇ ਸ਼ੁਰੂ ਕਰੋ। ਜਾਂ ਲਾਈਵ ਚੈਨਲਾਂ ਦੀ ਪੇਸ਼ਕਸ਼ ਕਰਦੀਆਂ ਹੋਰ ਐਪਾਂ ਲਈ Google Play ਸਟੋਰ ਨੂੰ ਬ੍ਰਾਊਜ਼ ਕਰੋ।"</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"ਰਿਕਾਰਡਿੰਗ ਅਤੇ ਨਿਯਤ ਸਮੇਂ"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 ਮਿੰਟ"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 ਮਿੰਟ"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 ਘੰਟਾ"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ਘੰਟੇ"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"ਹਾਲੀਆ"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"ਨਿਯਤ"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"ਲੜੀ"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"ਹੋਰ"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ਚੈਨਲ ਨੂੰ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"ਪ੍ਰੋਗਰਾਮ ਨੂੰ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ਨੂੰ ਰਿਕਾਰਡ ਕਰਨ ਲਈ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ।"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ਹੁਣ ਤੋਂ <xliff:g id="ENDTIME">%2$s</xliff:g> ਤੱਕ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"ਸੰਪੂਰਨ ਕਾਰਜ-ਕ੍ਰਮ"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="one">ਅਗਲਾ %1$d ਦਿਨ</item>
+ <item quantity="other">ਅਗਲੇ %1$d ਦਿਨ</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="one">%1$d ਮਿੰਟ</item>
+ <item quantity="other">%1$d ਮਿੰਟ</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="one">%1$d ਨਵੀਂ ਰਿਕਾਰਡਿੰਗ</item>
+ <item quantity="other">%1$d ਨਵੀਆਂ ਰਿਕਾਰਡਿੰਗਾਂ</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="one">%1$d ਰਿਕਾਰਡਿੰਗ</item>
+ <item quantity="other">%1$d ਰਿਕਾਰਡਿੰਗਾਂ</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="one">%1$d ਰਿਕਾਰਡਿੰਗ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ</item>
+ <item quantity="other">%1$d ਰਿਕਾਰਡਿੰਗਾਂ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"ਰਿਕਾਰਡਿੰਗ ਰੱਦ ਕਰੋ"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"ਰਿਕਾਰਡਿੰਗ ਬੰਦ ਕਰੋ"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"ਵੇਖੋ"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"ਮੁੱਢ ਤੋਂ ਚਲਾਓ"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"ਜਿੱਥੇ ਛੱਡਿਆ ਸੀ ਓਥੋਂ ਦੁਬਾਰਾ ਚਲਾਓ"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"ਮਿਟਾਓ"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ਰਿਕਾਰਡਿੰਗਾਂ ਮਿਟਾਓ"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"ਮੁੜ ਸ਼ੁਰੂ ਕਰੋ"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"ਸੀਜ਼ਨ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"ਕਾਰਜ-ਕ੍ਰਮ ਵੇਖੋ"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"ਹੋਰ ਪੜ੍ਹੋ"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ਰਿਕਾਰਡਿੰਗਾਂ ਮਿਟਾਓ"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"ਉਹਨਾਂ ਐਪੀਸੋਡਾਂ ਨੂੰ ਚੁਣੋ ਜਿੰਨ੍ਹਾਂ ਨੂੰ ਤੁਸੀਂ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ। ਇੱਕ ਵਾਰ ਮਿਟਾਏ ਜਾਣ ਤੋਂ ਬਾਅਦ ਉਹਨਾਂ ਨੂੰ ਮੁੜ-ਹਾਸਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"ਮਿਟਾਉਣ ਲਈ ਕੋਈ ਰਿਕਾਰਡਿੰਗਾਂ ਨਹੀਂ ਹਨ।"</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"ਵੇਖੇ ਗਏ ਐਪੀਸੋਡ ਚੁਣੋ"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"ਸਾਰੇ ਐਪੀਸੋਡ ਚੁਣੋ"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"ਸਾਰੇ ਐਪੀਸੋਡਾਂ ਨੂੰ ਅਣਚੁਣਿਆ ਕਰੋ"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> ਵਿੱਚੋਂ <xliff:g id="WATCHED">%1$d</xliff:g> ਮਿੰਟਾਂ ਦੀ ਰਿਕਾਰਡਿੰਗ ਵੇਖੀ ਗਈ"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> ਵਿੱਚੋਂ <xliff:g id="WATCHED">%1$d</xliff:g> ਸਕਿੰਟਾਂ ਦੀ ਰਿਕਾਰਡਿੰਗ ਵੇਖੀ ਗਈ"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"ਕਦੇ ਵੀ ਨਾ ਦੇਖੀਆਂ"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="one">%2$d ਵਿੱਚੋਂ %1$d ਐਪੀਸੋਡ ਮਿਟਾਇਆ ਗਿਆ ਹੈ</item>
+ <item quantity="other">%2$d ਵਿੱਚੋਂ %1$d ਐਪੀਸੋਡ ਮਿਟਾਏ ਗਏ ਹਨ</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ਤਰਜੀਹ"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"ਉੱਚਤਮ"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"ਨਿਊਨਤਮ"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"ਨੰਬਰ <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ਚੈਨਲ"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ਕੋਈ ਵੀ"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"ਤਰਜੀਹ ਚੁਣੋ"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"ਜਦੋਂ ਇੱਕੋ ਸਮੇਂ ਰਿਕਾਰਡ ਕਰਨ ਲਈ ਬਹੁਤ ਜ਼ਿਆਦਾ ਪ੍ਰੋਗਰਾਮ ਹੋਣ, ਤਾਂ ਸਿਰਫ਼ ਸਭ ਤੋਂ ਵੱਧ ਤਰਜੀਹ ਵਾਲੇ ਪ੍ਰੋਗਰਾਮ ਹੀ ਰਿਕਾਰਡ ਕੀਤੇ ਜਾਣਗੇ।"</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"ਰੱਖਿਅਤ ਕਰੋ"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ਇੱਕ ਵਾਰ ਕੀਤੀਆਂ ਜਾਣ ਵਾਲੀਆਂ ਰਿਕਾਰਡਿੰਗਾਂ ਦੀ ਉੱਚਤਮ ਤਰਜੀਹ ਹੁੰਦੀ ਹੈ"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"ਬੰਦ ਕਰੋ"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ਰਿਕਾਰਡਿੰਗ ਦਾ ਨਿਯਤ ਸਮਾਂ ਵੇਖੋ"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"ਇਹ ਸਿੰਗਲ ਪ੍ਰੋਗਰਾਮ"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ਹੁਣ - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"ਸਮੁੱਚੀ ਲੜੀਆਂ …"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"ਫਿਰ ਵੀ ਨਿਯਤ ਕਰੋ"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"ਇਸ ਦੀ ਬਜਾਏ ਇਸ ਨੂੰ ਰਿਕਾਰਡ ਕਰੋ"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ਇਸ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਰੱਦ ਕਰੋ"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"ਹੁਣ ਵੇਖੋ"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"ਰਿਕਾਰਡਿੰਗਾਂ ਮਿਟਾਓ…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"ਰਿਕਾਰਡ ਕਰਨ ਯੋਗ"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ਰਿਕਾਰਡਿੰਗ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ਰਿਕਾਰਡਿੰਗ ਵਿਵਾਦ"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ਰਿਕਾਰਡਿੰਗ"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ਰਿਕਾਰਡਿੰਗ ਅਸਫਲ ਰਹੀ"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"ਪ੍ਰੋਗਰਾਮਾਂ ਨੂੰ ਪੜ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"ਹਾਲੀਆ ਰਿਕਾਰਡਿੰਗਾਂ ਵੇਖੋ"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ਦੀ ਰਿਕਾਰਡਿੰਗ ਅਧੂਰੀ ਹੈ।"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ਅਤੇ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ਦੀਆਂ ਰਿਕਾਰਡਿੰਗਾਂ ਅਧੂਰੀਆਂ ਹਨ।"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ਅਤੇ <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ਦੀਆਂ ਰਿਕਾਰਡਿੰਗਾਂ ਅਧੂਰੀਆਂ ਹਨ।"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"ਲੋੜੀਂਦੀ ਸਟੋਰੇਜ ਨਾ ਹੋਣ ਕਰਕੇ <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ਦੀ ਰਿਕਾਰਡਿੰਗ ਪੂਰੀ ਨਹੀਂ ਹੋਈ।"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"ਲੋੜੀਂਦੀ ਸਟੋਰੇਜ ਨਾ ਹੋਣ ਕਰਕੇ <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ਅਤੇ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ਦੀਆਂ ਰਿਕਾਰਡਿੰਗਾਂ ਪੂਰੀਆਂ ਨਹੀਂ ਹੋਈਆਂ।"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"ਲੋੜੀਂਦੀ ਸਟੋਰੇਜ ਨਾ ਹੋਣ ਕਰਕੇ <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ਅਤੇ <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ਦੀਆਂ ਰਿਕਾਰਡਿੰਗਾਂ ਪੂਰੀਆਂ ਨਹੀਂ ਹੋਈਆਂ।"</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR ਨੂੰ ਹੋਰ ਸਟੋਰੇਜ ਦੀ ਲੋੜ ਹੈ"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"ਤੁਸੀਂ DVR ਨਾਲ ਪ੍ਰੋਗਰਾਮਾਂ ਨੂੰ ਰਿਕਾਰਡ ਕਰ ਸਕੋਂਗੇ। ਹਾਲਾਂਕਿ ਹੁਣ DVR ਦੇ ਕੰਮ ਕਰਨ ਲਈ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਵਿਚਲੀ ਸਟੋਰੇਜ ਕਾਫੀ ਨਹੀਂ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB ਜਾਂ ਉਸਤੋਂ ਵੀ ਜ਼ਿਆਦਾ ਸਟੋਰੇਜ ਵਾਲੀ ਬਾਹਰੀ ਡੀਵਾਈਸ ਨੂੰ ਕਨੈਕਟ ਕਰੋ ਅਤੇ ਉਸ ਨੂੰ ਡੀਵਾਈਸ ਸਟੋਰੇਜ ਵਜੋਂ ਵੰਨਗੀਕਿਰਤ ਕਰਨ ਲਈ ਪੜਾਵਾਂ ਦਾ ਅਨੁਸਰਣ ਕਰੋ।"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"ਸਟੋਰੇਜ ਕਾਫੀ ਨਹੀਂ ਹੈ"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"ਇਹ ਪ੍ਰੋਗਰਾਮ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ ਕਿਉਂਕਿ ਸਟੋਰੇਜ ਕਾਫ਼ੀ ਨਹੀਂ ਹੈ। ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਕੁਝ ਰਿਕਾਰਡਿੰਗਾਂ ਨੂੰ ਮਿਟਾਉਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"ਸਟੋਰੇਜ ਨਹੀਂ ਹੈ"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ਰਿਕਾਰਡਿੰਗ ਬੰਦ ਕਰਨੀ ਹੈ?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ਰਿਕਾਰਡ ਕੀਤੀ ਸਮੱਗਰੀ ਨੂੰ ਰੱਖਿਅਤ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ਦੀ ਰਿਕਾਰਡਿੰਗ ਬੰਦ ਹੋ ਜਾਵੇਗੀ ਕਿਉਂਕਿ ਇਹ ਇਸ ਪ੍ਰੋਗਰਾਮ ਨਾਲ ਵਿਵਾਦ ਕਰਦੀ ਹੈ। ਰਿਕਾਰਡ ਕੀਤੀ ਸਮੱਗਰੀ ਰੱਖਿਅਤ ਕੀਤੀ ਜਾਵੇਗੀ।"</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ਰਿਕਾਰਡਿੰਗ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਪਰ ਇਸ ਵਿੱਚ ਵਿਵਾਦ ਹਨ"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ਰਿਕਾਰਡਿੰਗ ਸ਼ੁਰੂ ਹੋ ਗਈ ਹੈ ਪਰ ਇਸ ਵਿੱਚ ਵਿਵਾਦ ਹਨ"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> ਦੇ ਕੁਝ ਹਿੱਸੇ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤੇ ਜਾਣਗੇ।"</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> ਅਤੇ <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ਦੇ ਕੁਝ ਹਿੱਸੇ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤੇ ਜਾਣਗੇ।"</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ਅਤੇ ਇੱਕ ਹੋਰ ਨਿਯਤ ਕੀਤੇ ਸਮੇਂ ਵਾਲੇ ਪ੍ਰੋਗਰਾਮਾਂ ਦੇ ਕੁਝ ਹਿੱਸੇ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤੇ ਜਾਣਗੇ।"</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ਅਤੇ %3$d ਨਿਯਤ ਕੀਤੇ ਸਮੇਂ ਦੇ ਕੁਝ ਹਿੱਸੇ ਨੂੰ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।</item>
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ਅਤੇ %3$d ਨਿਯਤ ਕੀਤੇ ਸਮਿਆਂ ਦੇ ਕੁਝ ਹਿੱਸੇ ਨੂੰ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"ਤੁਸੀਂ ਕੀ ਰਿਕਾਰਡ ਕਰਨਾ ਚਾਹੋਂਗੇ?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"ਤੁਸੀਂ ਕਿੰਨਾ ਚਿਰ ਰਿਕਾਰਡ ਕਰਨਾ ਚਾਹੋਂਗੇ?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ਪਹਿਲਾਂ ਹੀ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"ਉਸੇ ਪ੍ਰੋਗਰਾਮ ਦਾ <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> \'ਤੇ ਰਿਕਾਰਡ ਕੀਤੇ ਜਾਣ ਲਈ ਪਹਿਲਾਂ ਤੋਂ ਹੀ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ।"</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ਪਹਿਲਾਂ ਹੀ ਰਿਕਾਰਡ ਕੀਤਾ ਹੋਇਆ ਹੈ"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ਇਹ ਪ੍ਰੋਗਰਾਮ ਪਹਿਲਾਂ ਹੀ ਰਿਕਾਰਡ ਕੀਤਾ ਹੋਇਆ ਹੈ। ਇਹ DVR ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚ ਉਪਲਬਧ ਹੈ।"</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"ਲੜੀ ਦੀ ਰਿਕਾਰਡਿੰਗ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ਰਿਕਾਰਡਿੰਗ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ।</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ਰਿਕਾਰਡਿੰਗਾਂ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ।</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ਰਿਕਾਰਡਿੰਗ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ। ਉਹਨਾਂ ਵਿੱਚੋਂ <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> ਨੂੰ ਵਿਵਾਦਾਂ ਦੇ ਕਾਰਨ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ਰਿਕਾਰਡਿੰਗਾਂ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ। ਉਹਨਾਂ ਵਿੱਚੋਂ <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> ਨੂੰ ਵਿਵਾਦਾਂ ਦੇ ਕਾਰਨ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ਰਿਕਾਰਡਿੰਗ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ। ਇਸ ਲੜੀ ਅਤੇ ਹੋਰਨਾਂ ਲੜੀਆਂ ਦੇ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ਐਪੀਸੋਡ ਨੂੰ ਵਿਵਾਦਾਂ ਦੇ ਕਾਰਨ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ਰਿਕਾਰਡਿੰਗਾਂ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ। ਇਸ ਲੜੀ ਅਤੇ ਹੋਰਨਾਂ ਲੜੀਆਂ ਦੇ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ਐਪੀਸੋਡਾਂ ਨੂੰ ਵਿਵਾਦਾਂ ਦੇ ਕਾਰਨ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ਰਿਕਾਰਡਿੰਗ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ। ਹੋਰਨਾਂ ਲੜੀਆਂ ਦੇ 1 ਐਪੀਸੋਡ ਦੀ ਵਿਵਾਦਾਂ ਦੇ ਕਾਰਨ ਰਿਕਾਰਡਿੰਗ ਨਹੀਂ ਕੀਤੀ ਜਾਵੇਗੀ।</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ਰਿਕਾਰਡਿੰਗਾਂ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ। ਹੋਰਨਾਂ ਲੜੀਆਂ ਦੇ 1 ਐਪੀਸੋਡ ਦੀ ਵਿਵਾਦਾਂ ਦੇ ਕਾਰਨ ਰਿਕਾਰਡਿੰਗ ਨਹੀਂ ਕੀਤੀ ਜਾਵੇਗੀ।</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ਰਿਕਾਰਡਿੰਗ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ। ਹੋਰਨਾਂ ਲੜੀਆਂ ਦੇ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ਐਪੀਸੋਡ ਨੂੰ ਵਿਵਾਦਾਂ ਦੇ ਕਾਰਨ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।</item>
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ਰਿਕਾਰਡਿੰਗਾਂ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕੀਤਾ ਗਿਆ ਹੈ। ਹੋਰਨਾਂ ਲੜੀਆਂ ਦੇ <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ਐਪੀਸੋਡਾਂ ਨੂੰ ਵਿਵਾਦਾਂ ਦੇ ਕਾਰਨ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"ਰਿਕਾਰਡ ਕੀਤਾ ਪ੍ਰੋਗਰਾਮ ਨਹੀਂ ਲੱਭਿਆ।"</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"ਸਬੰਧਿਤ ਰਿਕਾਰਡਿੰਗਾਂ"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="one">%1$d ਰਿਕਾਰਡਿੰਗ</item>
+ <item quantity="other">%1$d ਰਿਕਾਰਡਿੰਗਾਂ</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ਨੂੰ ਰਿਕਾਰਡਿੰਗ ਦੇ ਨਿਯਤ ਸਮੇਂ ਤੋਂ ਹਟਾਇਆ ਗਿਆ।"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ਟਿਊਨਰ ਦੇ ਵਿਵਾਦਾਂ ਦੇ ਕਾਰਨ ਅਧੂਰਾ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ਟਿਊਨਰ ਦੇ ਵਿਵਾਦਾਂ ਦੇ ਕਾਰਨ ਰਿਕਾਰਡ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ਹਾਲੇ ਕਾਰਜ-ਕ੍ਰਮ \'ਤੇ ਕੋਈ ਰਿਕਾਰਡਿੰਗਾਂ ਨਹੀਂ ਹਨ।\nਤੁਸੀਂ ਪ੍ਰੋਗਰਾਮ ਗਾਈਡ ਵਿੱਚੋਂ ਰਿਕਾਰਡਿੰਗ ਦਾ ਸਮਾਂ ਨਿਯਤ ਕਰ ਸਕਦੇ ਹੋ।"</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="one">%1$d ਰਿਕਾਰਡਿੰਗ ਵਿਵਾਦ</item>
+ <item quantity="other">%1$d ਰਿਕਾਰਡਿੰਗ ਵਿਵਾਦ</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"ਲੜੀ ਦੀਆਂ ਸੈਟਿੰਗਾਂ"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"ਲੜੀ ਦੀ ਰਿਕਾਰਡਿੰਗ ਸ਼ੁਰੂ ਕਰੋ"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"ਲੜੀ ਦੀ ਰਿਕਾਰਡਿੰਗ ਬੰਦ ਕਰੋ"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"ਕੀ ਲੜੀ ਦੀ ਰਿਕਾਰਡਿੰਗ ਬੰਦ ਕਰਨੀ ਹੈ?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ਰਿਕਾਰਡ ਕੀਤੇ ਐਪੀਸੋਡ DVR ਲਾਇਬਰੇਰੀ ਵਿੱਚ ਉਪਲਬਧ ਰਹਿਣਗੇ।"</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"ਬੰਦ ਕਰੋ"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ਕੋਈ ਵੀ ਐਪੀਸੋਡਾਂ ਦਾ ਹੁਣ ਪ੍ਰਸਾਰਨ ਨਹੀਂ ਹੋ ਰਿਹਾ ਹੈ।"</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ਕੋਈ ਐਪੀਸੋਡ ਉਪਲਬਧ ਨਹੀਂ ਹਨ।\nਉਪਲਬਧ ਹੋਣ \'ਤੇ ਉਹਨਾਂ ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="one">(%1$d ਮਿੰਟ)</item>
+ <item quantity="other">(%1$d ਮਿੰਟ)</item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"ਅੱਜ"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"ਭਲਕੇ"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"ਕੱਲ੍ਹ"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ਅੱਜ"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ਭਲਕੇ"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"ਸਕੋਰ"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"ਰਿਕਾਰਡ ਕੀਤੇ ਪ੍ਰੋਗਰਾਮ"</string>
+</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 1e86cb7a..3db5beba 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Sterowanie odtwarzaniem"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Ostatnie kanały"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanały"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Opcje TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opcje PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Elementy sterujące Play są niedostępne dla tego kanału"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Odtwórz lub wstrzymaj"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Przewiń do przodu"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Napisy"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Tryb wyświetl."</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Włączony"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Wyłączony"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Wiele kan. audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Więcej kanałów"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Ustawienia"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Źródło"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Przełącz"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Włączone"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Wyłączone"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Dźwięk"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Główne okno"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Okno PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Układ"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Prawy dolny róg"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Prawy górny róg"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Lewy górny róg"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Lewy dolny róg"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Obok siebie"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Rozmiar"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Duży"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Mały"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Źródło sygnału"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/kabel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Brak informacji o programach"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Brak informacji"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Kanał zablokowany"</string>
- <string name="default_language" msgid="4122326459624337928">"Nieznany język"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Nieznany język"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Napisy: %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Napisy"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Wył."</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Dostosuj format"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Grupuj według"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ten program jest zablokowany"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ten program nie ma oceny"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Ten program ma ocenę <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Wejście nie obsługuje automatycznego skanowania"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Nie można rozpocząć automatycznego skanowania dla „<xliff:g id="TV_INPUT">%s</xliff:g>”"</string>
@@ -94,7 +76,6 @@
<item quantity="one">Dodano %1$d kanał</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Nie dodano kanałów"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Kontr. rodziciel."</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Wł."</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Wył."</string>
@@ -110,6 +91,8 @@
<string name="other_countries" msgid="8342216398676184749">"Inne kraje"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Brak"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Brak"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Bez oceny"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blokuj programy bez oceny"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Brak"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Duże ograniczenia"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Średnie ograniczenia"</string>
@@ -126,6 +109,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Wpisz kod PIN, by oglądać ten kanał"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Wpisz kod PIN, by oglądać ten program"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Ten program ma ocenę <xliff:g id="RATING">%1$s</xliff:g>. Aby go obejrzeć, podaj kod PIN."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Ten program nie ma oceny. Aby go obejrzeć, podaj kod PIN"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Wpisz kod PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Aby ustawić kontrolę rodzicielską, utwórz PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Wpisz nowy PIN"</string>
@@ -139,22 +123,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Nieprawidłowy PIN. Spróbuj ponownie"</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Spróbuj ponownie. Niezgodny kod PIN"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Wpisz kod pocztowy."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Aplikacja Telewizja online będzie używać kodu pocztowego, by udostępniać kompletny przewodnik po programach telewizyjnych."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Wpisz kod pocztowy"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Nieprawidłowy kod pocztowy"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Ustawienia"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Dostosuj listę kanałów"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Wybierz kanały do przewodnika TV"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Źródła kanałów"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Dostępne są nowe kanały"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Kontrola rodzicielska"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Przesunięcie w czasie"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Nagrywaj podczas oglądania, by móc wstrzymywać i przewijać programy na żywo.\nOstrzeżenie: funkcja ta intensywnie korzysta z pamięci wewnętrznej, co może skrócić jej żywotność."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licencje open source"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licencje open source"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Prześlij opinię"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Wersja"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Aby oglądać ten kanał, naciśnij Prawo i wpisz kod PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Aby oglądać ten program, naciśnij Prawo i wpisz kod PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Ten program nie ma oceny.\nAby go obejrzeć, naciśnij przycisk W prawo i podaj kod PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Ten program ma ocenę <xliff:g id="RATING">%1$s</xliff:g>.\nAby go oglądać, naciśnij Prawo i wpisz kod PIN"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Aby oglądać ten kanał, użyj standardowej aplikacji Telewizja na żywo."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Aby obejrzeć ten program, użyj standardowej aplikacji Telewizja na żywo."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Ten program nie ma oceny.\nAby go obejrzeć, użyj domyślnej aplikacji do obsługi telewizji na żywo."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Ten program ma ocenę <xliff:g id="RATING">%1$s</xliff:g>.\nAby go obejrzeć, użyj standardowej aplikacji Telewizja na żywo."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Program jest zablokowany"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ten program nie ma oceny"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Ten program ma ocenę <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Tylko dźwięk"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Słaby sygnał"</string>
@@ -189,8 +182,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Naciśnij SELECT"</b>", by otworzyć menu TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Nie znaleziono wejścia TV"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Nie można znaleźć wejścia TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Tryb PIP nie jest obsługiwany"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Brak sygnału wejściowego do wyświetlenia w trybie PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Nieodpowiedni typ tunera. Uruchom aplikację Telewizja online na jego wejściu TV."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Strojenie nie powiodło się"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Nie znaleziono aplikacji do obsługi tego działania."</string>
@@ -199,7 +190,7 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Klawisz BACK steruje podłączonym urządzeniem. Naciśnij przycisk HOME, by wyjść."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Aby odczytywać programy telewizyjne, Telewizja online potrzebuje uprawnień."</string>
<string name="setup_sources_text" msgid="4988039637873759839">"Skonfiguruj źródła"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Telewizja online to połączenie tradycyjnych kanałów TV i przesyłanych strumieniowo przez aplikacje.\n\nAby rozpocząć, skonfiguruj zainstalowane źródła kanałów. Możesz też przejrzeć Sklep Google Play, by znaleźć więcej aplikacji, które oferują dostęp do telewizji online."</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Telewizja online to połączenie tradycyjnych kanałów TV i przesyłanych strumieniowo przez aplikacje.\n\nAby rozpocząć, skonfiguruj zainstalowane źródła kanałów. Możesz też przejrzeć Sklep Google Play, by znaleźć więcej aplikacji, które oferują dostęp do telewizji online."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Nagrywanie i harmonogramy"</string>
<string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minut"</string>
<string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minut"</string>
@@ -244,6 +235,8 @@
<item quantity="other">%1$d zaplanowanego nagrania</item>
<item quantity="one">%1$d zaplanowane nagranie</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Anuluj nagrywanie"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Zatrzymaj nagrywanie"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Obejrzyj"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Odtwórz od początku"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Wznów odtwarzanie"</string>
@@ -278,9 +271,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Jeśli wybierzesz za dużo programów do nagrania w tym samym czasie, nagrane zostaną tylko te o wyższych priorytetach."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Zapisz"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Nagrania jednorazowe mają najwyższy priorytet"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Anuluj"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Anuluj"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Zapomnij"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Zatrzymaj"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Pokaż harmonogram nagrywania"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Tylko ten program"</string>
@@ -290,25 +280,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Nagraj to w zamian"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Anuluj to nagrywanie"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Obejrzyj teraz"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Usuń nagrania…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Można nagrać"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Zaplanowano nagrywanie"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Konflikt nagrywania"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Nagrywam"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Nie udało się nagrać"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Odczytuję programy, by utworzyć harmonogram nagrywania"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Odczytuję programy"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Odczytuję programy"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Zobacz ostatnie nagrania"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Nagranie <xliff:g id="PROGRAMNAME">%1$s</xliff:g> jest niepełne."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Nagrania <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> i <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> są niepełne."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Nagrania <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> i <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> są niepełne."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Nie udało się dokończyć nagrania <xliff:g id="PROGRAMNAME">%1$s</xliff:g> z powodu braku miejsca."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Nie udało się dokończyć nagrań <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> i <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> z powodu braku miejsca."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Nie udało się dokończyć nagrań <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> i <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> z powodu braku miejsca."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Nagrywarka DVR potrzebuje więcej miejsca"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Dzięki funkcji nagrywarki DVR możesz nagrywać programy, ale obecnie na urządzeniu jest za mało miejsca, by można było z niej korzystać. Podłącz dysk zewnętrzny o pojemności co najmniej <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB i postępuj zgodnie z instrukcjami, by sformatować go jako pamięć urządzenia."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Dzięki funkcji nagrywarki DVR możesz nagrywać programy, ale obecnie na urządzeniu jest za mało miejsca, by można było z niej korzystać. Podłącz dysk zewnętrzny o pojemności co najmniej <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB i postępuj zgodnie z instrukcjami, by sformatować go jako pamięć urządzenia."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Za mało miejsca"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Nie można nagrać tego programu, bo brakuje miejsca. Usuń któreś z wcześniejszych nagrań."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Brak dostępu do pamięci"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Brak dostępu do części pamięci wykorzystywanej przez DVR. Podłącz dysk zewnętrzny, którego używasz, zanim włączysz DVR ponownie. Jeśli nie masz już tego dysku zewnętrznego, możesz go zapomnieć."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Zapomnieć pamięć nagrywarki?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Wszystkie zapisane treści i zaplanowane nagrania zostaną utracone."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Zatrzymać nagrywanie?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Nagrana treść zostanie zapisana."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Nagrywanie programu „<xliff:g id="PROGRAMNAME">%1$s</xliff:g>” zostanie zatrzymane, bo jest w konflikcie z tym programem. Nagrane treści zostaną zachowane."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Nagrywanie zostało zaplanowane, ale wystąpiły konflikty"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Zaczęło się nagrywanie, ale występują konflikty"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Program <xliff:g id="PROGRAMNAME">%1$s</xliff:g> zostanie nagrany."</string>
@@ -328,17 +321,39 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Nagrywanie tego samego programu zostało już zaplanowane na <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Już nagrany"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Ten program został już nagrany. Jest dostępny w bibliotece nagrywarki DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Zaplanowano nagrywanie serialu"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="few">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nagrania serialu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="many">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nagrań serialu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nagrania serialu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> nagranie serialu <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="few">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nagrania serialu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Z powodu pokrywających się harmonogramów nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> odcinków.</item>
+ <item quantity="many">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nagrań serialu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Z powodu pokrywających się harmonogramów nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> odcinków.</item>
+ <item quantity="other">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nagrania serialu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Z powodu pokrywających się harmonogramów nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> odcinków.</item>
+ <item quantity="one">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> nagranie serialu <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Z powodu pokrywających się harmonogramów nie uda się nagrać tego odcinka.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="few">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nagrania serialu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Z powodu pokrywających się harmonogramów nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> odcinków tego i innych seriali.</item>
+ <item quantity="many">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nagrań serialu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Z powodu pokrywających się harmonogramów nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> odcinków tego i innych seriali.</item>
+ <item quantity="other">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nagrania serialu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Z powodu pokrywających się harmonogramów nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> odcinków tego i innych seriali.</item>
+ <item quantity="one">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> nagranie serialu <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Z powodu pokrywających się harmonogramów nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> odcinków tego i innych seriali.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="few">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nagrania serialu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Przez to nie uda się nagrać 1 odcinka innego serialu.</item>
+ <item quantity="many">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nagrań serialu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Przez to nie uda się nagrać 1 odcinka innego serialu.</item>
+ <item quantity="other">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> nagrania serialu <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Przez to nie uda się nagrać 1 odcinka innego serialu.</item>
+ <item quantity="one">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> nagranie serialu <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Przez to nie uda się nagrać 1 odcinka innego serialu.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="few">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nagrania serialu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Przez to nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> odcinków innych seriali.</item>
+ <item quantity="many">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nagrań serialu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Przez to nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> odcinków innych seriali.</item>
+ <item quantity="other">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> nagrania serialu <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Przez to nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> odcinków innych seriali.</item>
+ <item quantity="one">Zaplanowano <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> nagranie serialu <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Przez to nie uda się nagrać <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> odcinków innych seriali.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Nie znaleziono nagranego programu."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Powiązane nagrania"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Brak opisu programu)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="few">%1$d nagrania</item>
<item quantity="many">%1$d nagrań</item>
@@ -362,6 +377,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Zatrzymać nagrywanie cykliczne?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Nagrane odcinki będą dostępne w bibliotece nagrywarki DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Zatrzymaj"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"W tej chwili nie są nadawane żadne odcinki."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Brak dostępnych odcinków.\nZostaną one nagrane, gdy będą dostępne."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="few">(%1$d minuty)</item>
@@ -375,4 +391,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Dzisiaj, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Jutro, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Ocena"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Nagrane programy"</string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 45fa4e20..d1d3d09f 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"estéreo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Controlos de reprodução"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Canais recentes"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Canais"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Opções de TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opções de PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Controlos de reprodução indisponíveis para este canal"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Reproduzir ou colocar em pausa"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Avançar"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Legendas"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Modo de apres."</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Ativado"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Desativado"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multiáudio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Obter mais canais"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Definições"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Fonte"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Alternar"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Ativado"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Desativado"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Som"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Principal"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Janela de PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Esquema"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Canto inf. dir."</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Canto sup. dir."</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Canto sup. esq."</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Canto inf. esq."</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Lado a lado"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Tamanho"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Grande"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Pequeno"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Fonte de entrada"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/cabo)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Sem informação de programação"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Sem informações"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Canal bloqueado"</string>
- <string name="default_language" msgid="4122326459624337928">"Idioma desconhecido"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Idioma desconhecido"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Legendas %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Legendas"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Desativado"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Person. a formatação"</string>
@@ -83,16 +64,16 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Agrupar por"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Este programa está bloqueado"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Este programa não tem classificação."</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Este programa tem a classificação <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"A entrada não suporta procura automática"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Não é possível iniciar a verificação automática para \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Não é possível iniciar as preferências do sistema para as legendas."</string>
<plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d canais adicionados</item>
<item quantity="one">%1$d canal adicionado</item>
+ <item quantity="other">%1$d canais adicionados</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Nenhum canal adicionado"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Sintonizador"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Controlo parental"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Ativado"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Desativado"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Outros países"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Nenhum"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Nenhum"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Sem classificação"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Bloquear programas s/ classif."</string>
<string name="option_rating_none" msgid="5204552587760414879">"Nenhum"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Restrições elevadas"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Restrições médias"</string>
@@ -124,48 +107,58 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Introduzir o PIN para ver este canal"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Introduzir o PIN para ver este programa"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Este programa tem a classificação <xliff:g id="RATING">%1$s</xliff:g>. Introduza o PIN para ver este programa"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Este programa não tem classificação. Introduza o PIN para ver este programa."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Introduzir o PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Para definir os controlos parentais, crie um PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Introduzir o novo PIN"</string>
<string name="pin_enter_again" msgid="2618999754723090427">"Confirmar o PIN"</string>
<string name="pin_enter_old_pin" msgid="4588282612931041919">"Introduzir o PIN atual"</string>
<plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">Introduziu 5 vezes o PIN incorreto.\nTente novamente dentro de <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundos.</item>
<item quantity="one">Introduziu 5 vezes o PIN incorreto.\nTente novamente dentro de <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> segundo.</item>
+ <item quantity="other">Introduziu 5 vezes o PIN incorreto.\nTente novamente dentro de <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> segundos.</item>
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Esse PIN estava errado. Tente novamente."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Tente novamente, o PIN não corresponde"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Introduza o seu código postal."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"A aplicação Canais em Direto utiliza o código postal para disponibilizar um guia de programação completo para os canais de TV."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Introduza o seu código postal"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Código postal inválido"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Definições"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personalizar lista de canais"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Escolher canais para o guia de programação"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Fontes dos canais"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Novos canais disponíveis"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Controlo parental"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Controlo da reprodução"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Grave enquanto está a ver para poder colocar em pausa ou recuar programas em direto.\nAviso: isto pode reduzir a vida útil da memória de armazenamento interno devido à utilização intensiva da mesma."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licenças de código aberto"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licenças de código aberto"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Enviar comentários"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versão"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Para ver este canal, prima Direito e introduza o PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Para ver este programa, prima Direito e introduza o PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Este programa não tem classificação.\nPara ver este programa, prima Para a direita e introduza o PIN."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Este programa tem a classificação <xliff:g id="RATING">%1$s</xliff:g>.\nPara ver este programa, prima Direito e introduza o PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Para ver este canal, utilize a aplicação TV em direto predefinida."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Para ver este programa, utilize a aplicação TV em direto predefinida."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Este programa não tem classificação.\nPara ver este programa, utilize a aplicação de TV em direto predefinida."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Este programa tem a classificação <xliff:g id="RATING">%1$s</xliff:g>.\nPara o ver, utilize a aplicação TV em direto predefinida."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"O programa está bloqueado"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Este programa não tem classificação."</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Este programa tem a classificação <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Apenas áudio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Sinal fraco"</string>
<string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Sem ligação à Internet"</string>
<plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Não é possível reproduzir este canal até à(s) <xliff:g id="END_TIME_1">%1$s</xliff:g> porque estão a ser gravados outros canais. \n\nPrima para a direita para ajustar o horário de gravação.</item>
<item quantity="one">Não é possível reproduzir este canal até à(s) <xliff:g id="END_TIME_0">%1$s</xliff:g> porque está a ser gravado outro canal. \n\nPrima para a direita para ajustar o horário de gravação.</item>
+ <item quantity="other">Não é possível reproduzir este canal até à(s) <xliff:g id="END_TIME_1">%1$s</xliff:g> porque estão a ser gravados outros canais. \n\nPrima para a direita para ajustar o horário de gravação.</item>
</plurals>
<string name="channel_banner_no_title" msgid="8660301979190693176">"Sem título"</string>
<string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Canal bloqueado"</string>
<string name="setup_category_new" msgid="2899355289563443627">"Nova"</string>
<string name="setup_category_done" msgid="4750902502852212319">"Fontes"</string>
<plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d canais</item>
<item quantity="one">%1$d canal</item>
+ <item quantity="other">%1$d canais</item>
</plurals>
<string name="setup_input_no_channels" msgid="1669327912393163331">"Nenhum canal disponível"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Nova"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Prima SELECT"</b>" para aceder ao menu da TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Nenhuma entrada de TV encontrada"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Não é possível localizar a entrada de TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Não é suportada a opção PIP"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Nenhuma entrada disponível para apresentar com PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tipo de sintonizador inadequado. Inicie a aplicação Canais em direito para a entrada de TV do tipo de sintonizador."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Falha ao sintonizar"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Não foram encontradas aplicações para executar esta ação."</string>
@@ -207,25 +198,27 @@
<string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"A gravar <xliff:g id="PROGRAMNAME">%1$s</xliff:g> desde agora até às <xliff:g id="ENDTIME">%2$s</xliff:g>…"</string>
<string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Agenda completa"</string>
<plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">Próximos %1$d dias</item>
<item quantity="one">Próximo dia</item>
+ <item quantity="other">Próximos %1$d dias</item>
</plurals>
<plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d minutos</item>
<item quantity="one">%1$d minuto</item>
+ <item quantity="other">%1$d minutos</item>
</plurals>
<plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d novas gravações</item>
<item quantity="one">%1$d nova gravação</item>
+ <item quantity="other">%1$d novas gravações</item>
</plurals>
<plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d gravações</item>
<item quantity="one">%1$d gravação</item>
+ <item quantity="other">%1$d gravações</item>
</plurals>
<plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d gravações agendadas</item>
<item quantity="one">%1$d gravação agendada</item>
+ <item quantity="other">%1$d gravações agendadas</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Cancelar gravação"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Parar gravação"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Ver"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Reproduzir do início"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Retomar a reprodução"</string>
@@ -245,8 +238,8 @@
<string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> de <xliff:g id="DURATION">%2$d</xliff:g> segundos vistos"</string>
<string name="dvr_series_never_watched" msgid="6086008065876122655">"Nunca vistas"</string>
<plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%1$d de %2$d episódios eliminados</item>
<item quantity="one">%1$d de %2$d episódio eliminado</item>
+ <item quantity="other">%1$d de %2$d episódios eliminados</item>
</plurals>
<string name="dvr_series_settings_priority" msgid="5836437092774185710">"Prioridade"</string>
<string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Mais alta"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Quando existem demasiados programas para serem gravados em simultâneo, apenas são gravados os programas com as prioridades mais altas."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Guardar"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"As gravações únicas têm a prioridade mais alta"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Cancelar"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Cancelar"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Esquecer"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Parar"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Ver horários de gravação"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Este programa único"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Gravar antes este"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Cancelar esta gravação"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Ver agora"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Eliminar gravações"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Gravável"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Gravação agendada"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Conflito de gravação"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"A gravar"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Falha na gravação"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"A ler os programas para criar horários de gravação…"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"A ler os programas…"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"A ler os programas…"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Ver gravações recentes"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"A gravação de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> está incompleta."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"As gravações de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> e <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> estão incompletas."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"As gravações de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> e <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> estão incompletas."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"A gravação de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> não foi concluída devido a armazenamento insuficiente."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"As gravações de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> e <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> não foram concluídas devido a armazenamento insuficiente."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"As gravações de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> e <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> não foram concluídas devido a armazenamento insuficiente."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"O DVR necessita de mais armazenamento"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Pode gravar programas com o DVR. Contudo, não existe neste momento armazenamento suficiente no dispositivo para que o DVR funcione. Ligue uma unidade externa que tenha, pelo menos, <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB e siga os passos para a formatar como armazenamento do dispositivo."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Pode gravar programas com o DVR. Contudo, não existe neste momento armazenamento suficiente no dispositivo para que o DVR funcione. Ligue uma unidade externa que tenha, pelo menos, <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB e siga os passos para a formatar como armazenamento do dispositivo."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Sem armazenamento suficiente"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Este programa não será gravado porque não existe armazenamento suficiente. Experimente eliminar algumas gravações existentes."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Armazenamento em falta"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Algum do armazenamento utilizado pelo DVR está em falta. Ligue a unidade externa que utilizou anteriormente para reativar o DVR. Em alternativa, pode optar por esquecer o armazenamento se este já não estiver disponível."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Pretende esquecer o armazenamento?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Todos os seus conteúdos e agendamentos gravados serão perdidos."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Pretende parar a gravação?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"O conteúdo gravado será guardado."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"A gravação de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> será interrompida devido a conflitos com este programa. O conteúdo gravado será guardado."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Gravação agendada, mas com conflitos"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"A gravação foi iniciada, mas tem conflitos"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"O programa <xliff:g id="PROGRAMNAME">%1$s</xliff:g> será gravado."</string>
@@ -297,8 +290,8 @@
<string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Algumas partes de <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> e de <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> não serão gravadas."</string>
<string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Algumas partes de <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, de <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> e de mais um horário não serão gravadas."</string>
<plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other">Algumas partes de <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, de <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> e de mais %3$d horários não serão gravadas.</item>
<item quantity="one">Algumas partes de <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, de <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> e de mais %3$d horário não serão gravadas.</item>
+ <item quantity="other">Algumas partes de <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, de <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> e de mais %3$d horários não serão gravadas.</item>
</plurals>
<string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"O que gostaria de gravar?"</string>
<string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Durante quanto tempo pretende gravar?"</string>
@@ -306,20 +299,32 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"O mesmo programa já foi agendado para ser gravado às <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Já gravado"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Este programa já foi gravado. Está disponível na biblioteca do DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Gravação da série agendada"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one">Foi agendada <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> gravação para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravações para <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one">Foi agendada <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> gravação para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Esta não será gravada devido a conflitos.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravações para <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> destas não serão gravadas devido a conflitos.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one">Foi agendada <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> gravação para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episódios desta e de outras séries não serão gravados devido a conflitos.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> gravações para <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episódios desta e de outras séries não serão gravados devido a conflitos.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one">Foi agendada <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> gravação para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Não será gravado 1 episódio de outra série devido a conflitos.</item>
+ <item quantity="other">Foram agendadas <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravações para <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Não será gravado 1 episódio de outra série devido a conflitos.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one">Foi agendada <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> gravação para <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Não serão gravados <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episódios de outras séries devido a conflitos.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> gravações para <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Não serão gravados <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episódios de outras séries devido a conflitos.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Programa gravado não encontrado."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Gravações relacionadas"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Sem descrição do programa)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d gravações</item>
<item quantity="one">%1$d gravação</item>
+ <item quantity="other">%1$d gravações</item>
</plurals>
<string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
<string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> removido da agenda de gravação"</string>
@@ -327,8 +332,8 @@
<string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Não será gravado devido a conflitos de sintonizador."</string>
<string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Ainda não existem gravações agendadas.\nPode agendar a gravação a partir do guia de programação."</string>
<plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d conflitos de gravação</item>
<item quantity="one">%1$d conflito de gravação</item>
+ <item quantity="other">%1$d conflitos de gravação</item>
</plurals>
<string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Definições de séries"</string>
<string name="dvr_series_schedules_start" msgid="8458768834047133835">"Iniciar gravação da série"</string>
@@ -336,10 +341,11 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Pretende parar a gravação da série?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Os episódios gravados ficam disponíveis na biblioteca do DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Parar"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Não estão a ser transmitidos episódios em direto."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Não existem episódios disponíveis.\nVão ser gravados assim que estiverem disponíveis."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d minutos)</item>
<item quantity="one">(%1$d minuto) </item>
+ <item quantity="other">(%1$d minutos)</item>
</plurals>
<string name="dvr_date_today" msgid="7691050705354303471">"Hoje"</string>
<string name="dvr_date_tomorrow" msgid="4136735681186981844">"Amanhã"</string>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> de hoje"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> de amanhã"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Pontuação"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programas gravados"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 9c22a58a..9a8abe2e 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"estéreo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Controles de reprodução"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Canais recentes"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Canais"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Opções da TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opções de PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Controles de reprodução indisponíveis para este canal"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Reproduzir ou pausar"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Avançar"</string>
@@ -33,47 +32,29 @@
<string name="channels_item_setup" msgid="6557412175737379022">"Novos canais disponíveis"</string>
<string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Abrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="options_item_closed_caption" msgid="5945274655046367170">"Closed captions"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Modo de exibiç."</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Modo de exibição"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Ativado"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Desativado"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Múltip. áudios"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Adquirir mais canais"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Config."</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Origem"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Trocar"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Ativadas"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Desativadas"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Som"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Principal"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Janela de PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Layout"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Inferior direito"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Superior direito"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Superior esquerdo"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Inferior esquerdo"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Lado a lado"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Tamanho"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Grande"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Pequeno"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Origem da entrada"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Áudios múltiplos"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Mais canais"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Configurações"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/a cabo)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Nenhuma informação sobre o programa"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Nenhuma informação"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Canal bloqueado"</string>
- <string name="default_language" msgid="4122326459624337928">"Idioma desconhecido"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Idioma desconhecido"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Closed captions %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Closed captions"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Desativado"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Person. formatação"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Definir preferências gerais do sistema para closed captions"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Personalizar formatação"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Defina as preferências gerais do sistema para closed captions"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"Modo de exibição"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Múltiplos áudios"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Áudios múltiplos"</string>
<string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
<string name="multi_audio_channel_stereo" msgid="3758995659214256587">"estéreo"</string>
<string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"Surround 5.1"</string>
<string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"Surround 7.1"</string>
<string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d canais"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Pers. lista canais"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Personalizar lista de canais"</string>
<string name="edit_channels_item_select_group" msgid="4953000352257999703">"Selecionar grupo"</string>
<string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Desmarcar grupo"</string>
<string name="edit_channels_item_group_by" msgid="7794571851966798199">"Agrupar por"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"Padrão"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Agrupar por"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Este programa está bloqueado"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Este programa não tem classificação"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Este programa foi classificado como <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"A entrada não suporta verificação automática"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Não foi possível iniciar a verificação automática de \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
@@ -92,7 +74,6 @@
<item quantity="other">%1$d canais adicionados</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Nenhum canal adicionado"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Sintonizador"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Contr. p/ os pais"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Ativado"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Desativado"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Outros países"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Nenhum"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Nenhum"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Sem classificação"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Bloquear programas sem classificação"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Nenhum"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Restrições altas"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Restrições médias"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Digite seu PIN para assistir a este canal"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Digite seu PIN para assistir a este programa"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Este programa foi classificado como <xliff:g id="RATING">%1$s</xliff:g>. Digite seu PIN para assisti-lo"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Este programa não tem classificação. Digite seu PIN para assisti-lo"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Informe seu PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Para definir os controles para os pais, crie um PIN."</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Inserir novo PIN"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"O PIN estava errado. Tente novamente."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Tente novamente, o PIN não corresponde"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Config."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Digite seu CEP."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"O app Canais ao vivo usará o CEP para fornecer um guia completo da programação para os canais de TV."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Digite seu CEP"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"CEP inválido"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Configurações"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personalizar lista de canais"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Escolher canais para guia de programação"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Fontes do canal"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Escolha canais para o guia de programação"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Fontes de canais"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Novos canais disponíveis"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Controle dos pais"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Diferença de tempo"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Grave enquanto assiste para poder pausar ou retroceder programas ao vivo.\nAviso: isso pode diminuir a vida útil do armazenamento interno devido ao uso intenso do armazenamento."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licenças de código aberto"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licenças de código aberto"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Enviar feedback"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versão"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Para assistir a este canal, pressione para a direita e digite o PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Para assistir a este programa, pressione para a direita e digite o PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Este programa não tem classificação.\nPressione o botão direito e digite seu PIN para assisti-lo"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Este programa foi classificado como <xliff:g id="RATING">%1$s</xliff:g>.\nPara assistir a este programa, pressione para a direita e digite o PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Para assistir este canal, use o app padrão de TV ao vivo."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Para assistir este programa, use o app padrão de TV ao vivo."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Este programa não tem classificação.\nUse o app padrão de TV ao vivo para assisti-lo."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Este programa foi classificado como <xliff:g id="RATING">%1$s</xliff:g>.\nPara assistir este programa, use o app padrão de TV ao vivo."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programa bloqueado"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Este programa não tem classificação"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Este programa foi classificado como <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Somente áudio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Sinal fraco"</string>
@@ -170,8 +163,8 @@
<string name="setup_input_no_channels" msgid="1669327912393163331">"Nenhum canal disponível"</string>
<string name="setup_input_new" msgid="3337725672277046798">"Novas"</string>
<string name="setup_input_setup_now" msgid="1772000402336958967">"Não configurada"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Adquirir mais fontes"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Procurar apps que ofereçam canais ao vivo"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Adquira mais fontes"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Procure apps que ofereçam canais ao vivo"</string>
<string name="new_sources_title" msgid="3878933676500061895">"Novas fontes de canais disponíveis"</string>
<string name="new_sources_description" msgid="749649005588426813">"Novas fontes de canais têm canais para oferecer.\nConfigure-as agora ou faça isso mais tarde nas configurações de fontes de canais."</string>
<string name="new_sources_action_setup" msgid="177693761664016811">"Configurar agora"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Pressione \"SELECIONAR\""</b>" para acessar o menu da TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Nenhuma entrada de TV encontrada"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Não foi possível encontrar a entrada de TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP não é suportado"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Não há entrada disponível que possa ser mostrada com PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tipo de sintonizador não adequado. Inicie o app \"Canais ao vivo\" para abrir o tipo de sintonizador para entrada de TV."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Falha na sintonia"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Nenhum app foi encontrado para executar esta ação."</string>
@@ -190,7 +181,7 @@
<string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"O vídeo está inesperadamente indisponível"</string>
<string name="msg_back_key_guide" msgid="7404682718828721924">"A tecla VOLTAR é para dispositivos conectados. Pressione o botão INÍCIO para sair."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"O app \"Canais ao vivo\" precisa de permissão para ler a programação de TV."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Configurar suas fontes"</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Configure suas fontes"</string>
<string name="setup_sources_description" msgid="5695518946225445202">"Os canais ao vivo combinam a experiência dos canais de TV tradicionais com canais de streaming fornecidos por apps. \n\nComece configurando as fontes de canais já instaladas ou procure na Google Play Store mais apps que ofereçam canais ao vivo."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Gravações e programações"</string>
<string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minutos"</string>
@@ -226,6 +217,8 @@
<item quantity="one">%1$d gravação programada</item>
<item quantity="other">%1$d gravações programadas</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Cancelar gravação"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Interromper gravação"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Assistir"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Reproduzir do início"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Retomar reprodução"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Quando houver muitos programas a serem gravados ao mesmo tempo, apenas os com maior prioridade serão gravados."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Salvar"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Gravações únicas têm a maior prioridade"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Cancelar"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Cancelar"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Ignorar"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Parar"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Ver programação de gravação"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Este único programa"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Gravar este, e não o outro"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Cancelar esta gravação"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Assistir agora"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Excluir gravações…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Pode ser gravado"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Gravação programada"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Conflito de gravação"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Gravação"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Falha na gravação"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Lendo programas para criar programações de gravação"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Lendo programas"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Lendo programas"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Ver gravações recentes"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"A gravação de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> está incompleta."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"As gravações de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> e <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> estão incompletas."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"As gravações de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> e <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> estão incompletas."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"A gravação de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> não foi concluída devido à falta de espaço de armazenamento."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"As gravações de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> e <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> não foram concluídas devido à falta de espaço de armazenamento."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"As gravações de <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> e <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> não foram concluídas devido à falta de espaço de armazenamento."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"O DVR precisa de mais armazenamento"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Você poderá gravar programas com DVR. No entanto, não há espaço de armazenamento suficiente no seu dispositivo no momento para que o DVR funcione. Conecte um drive externo que tenha <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB ou mais e siga as etapas para formatá-lo como um armazenamento do dispositivo."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Você poderá gravar programas com DVR. No entanto, não há espaço de armazenamento suficiente no seu dispositivo no momento para que o DVR funcione. Conecte um drive externo que tenha <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB ou mais e siga as etapas para formatá-lo como um armazenamento do dispositivo."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Armazenamento insuficiente"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Este programa não será gravado porque não há espaço de armazenamento suficiente. Tente excluir algumas gravações já existentes."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Armazenamento ausente"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Alguns dos armazenamentos usados por DVR estão ausentes. Conecte o drive externo usado antes de reativar o DVR. Também é possível optar por esquecer o armazenamento se ele não estiver mais disponível."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Esquecer armazenamento?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Todo o conteúdo gravado e programações serão perdidos."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Interromper gravação?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"O conteúdo gravado será salvo."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"A gravação de <xliff:g id="PROGRAMNAME">%1$s</xliff:g> será interrompida porque ela tem um conflito com esse programa. O conteúdo gravado será salvo."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Gravação programada, mas há conflitos"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"A gravação começou, mas há conflitos"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"O programa <xliff:g id="PROGRAMNAME">%1$s</xliff:g> será gravado."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"A gravação do mesmo programa já foi programada para <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Já gravado"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Este programa já foi gravado. Ele está disponível na biblioteca de DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Gravação de série programada"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one">Foi programada <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravação de <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other">Foram programadas <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravações de <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one">Foi programada <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravação de <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Ao todo, <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> delas não serão gravadas devido a conflitos.</item>
+ <item quantity="other">Foram programadas <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravações de <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Ao todo, <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> delas não serão gravadas devido a conflitos.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one">Foi programada <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> gravação de <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Ao todo, <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episódios dessa e de outras séries não serão gravados devido a conflitos.</item>
+ <item quantity="other">Foram programadas <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> gravações de <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Ao todo, <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episódios dessa e de outras séries não serão gravados devido a conflitos.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one">Foi programada <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravação de <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Ao todo, 1 episódio de outras séries não será gravado devido a conflitos.</item>
+ <item quantity="other">Foram programadas <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> gravações de <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Ao todo, 1 episódio de outras séries não será gravado devido a conflitos.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one">Foi programada <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> gravação de <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Ao todo, <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episódios de outras séries não serão gravados devido a conflitos.</item>
+ <item quantity="other">Foram programadas <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> gravações de <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Ao todo, <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episódios de outras séries não serão gravados devido a conflitos.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Programa gravado não encontrado."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Gravações relacionadas"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"Nenhuma descrição do programa"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d gravação</item>
<item quantity="other">%1$d gravações</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Parar gravação da série?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Os episódios gravados permanecerão disponíveis na biblioteca de DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Parar"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Nenhum episódio está sendo transmitido no momento."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Nenhum episódio disponível.\nOs episódios serão gravados quando estiverem disponíveis."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d minuto)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> hoje"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> amanhã"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Pontuação"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programas gravados"</string>
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index adc3b359..1fe9e1e9 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Comenzi de redare"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Canale recente"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Canale"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Opțiuni TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Opțiuni PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Comenzile de redare nu sunt disponibile pentru acest canal"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Redați sau întrerupeți redarea"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Derulați rapid înainte"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Subtitrări"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Mod de afișare"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Activat"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Dezactivat"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Obțineți mai multe canale"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Setări"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Sursă"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Schimbați"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Activat"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Dezactivat"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Sunet"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Principală"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Fereastră PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Aspect"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Dreapta jos"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Dreapta sus"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Stânga sus"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Stânga jos"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Alăturat"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Dimensiuni"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Mare"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Mic"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Sursă de intrare"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenă/cablu)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Nu există informații despre program"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Nicio informație"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Canal blocat"</string>
- <string name="default_language" msgid="4122326459624337928">"Limbă necunoscută"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Limbă necunoscută"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Subtitrări %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Subtitrări"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Dezactivat"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Personaliz. format."</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Grupați după"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Acest program este blocat"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Acest program nu este evaluat"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Acest program este clasificat ca <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Intrarea nu acceptă scanarea automată"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Nu poate fi inițiată scanarea automată pentru „<xliff:g id="TV_INPUT">%s</xliff:g>”"</string>
@@ -93,7 +75,6 @@
<item quantity="one">%1$d canal adăugat</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Niciun canal adăugat"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Control parental"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Activat"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Dezactivat"</string>
@@ -109,6 +90,8 @@
<string name="other_countries" msgid="8342216398676184749">"Alte țări"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Niciunul"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Niciunul"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Neevaluat"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blocați programele neevaluate"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Niciuna"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Restricții majore"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Restricții medii"</string>
@@ -125,6 +108,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Introduceți codul PIN pentru a viziona acest canal"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Introduceți codul PIN pt. a viziona acest program"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Acest program este evaluat cu <xliff:g id="RATING">%1$s</xliff:g>. Pentru a viziona programul, introduceți codul PIN"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Acest program nu este evaluat. Introduceți codul PIN pentru a-l viziona."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Introduceți codul PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Pentru a seta controlul parental, creați un cod PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Introduceți un nou cod PIN"</string>
@@ -137,22 +121,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Codul PIN a fost greșit. Încercați din nou."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Încercați din nou. Codul PIN nu se potrivește."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Introduceți codul poștal"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Aplicația Canale live va folosi codul poștal pentru a vă oferi un ghid de programe complet pentru canalele TV."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Introduceți codul poștal"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Cod poștal nevalid"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Setări"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personalizați lista de canale"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Alegeți canale pentru ghidul de programe"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Sursele canalelor"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Noi canale disponibile"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Control parental"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Decalare temporală"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Înregistrați în timpul vizionării, ca să puteți întrerupe sau derula înapoi programele live.\nAvertisment: astfel, se utilizează intensiv memoria internă și i se poate reduce durata de viață."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licențe open source"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licențe open source"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Trimiteți feedback"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Versiune"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Pentru a viziona acest canal, apăsați la dreapta și introduceți codul PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Pentru a viziona acest program, apăsați la dreapta și introduceți codul PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Acest program nu este evaluat.\nPentru a-l viziona, apăsați pe Drept și introduceți codul PIN."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Acest program este clasificat ca <xliff:g id="RATING">%1$s</xliff:g>.\nPentru a viziona acest program, apăsați pe săgeata spre dreapta și introduceți codul PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Pentru a viziona acest canal, folosiți aplicația prestabilită pentru programe TV live."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Pentru a viziona acest program, folosiți aplicația prestabilită pentru programe TV live."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Acest program nu este evaluat.\nPentru a-l viziona, utilizați aplicația prestabilită TV live."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Acest program este evaluat cu <xliff:g id="RATING">%1$s</xliff:g>.\nPentru a viziona acest program, folosiți aplicația prestabilită pentru programe TV live."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programul este blocat"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Acest program nu este evaluat"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Acest program este clasificat ca <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Numai conținut audio"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Semnal slab"</string>
@@ -185,8 +178,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Apăsați pe SELECTAȚI"</b>" pentru a accesa meniul TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Nu s-a găsit nicio intrare TV"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Nu se poate găsi intrarea TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Funcția PIP nu este acceptată"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Nu există intrări disponibile pentru afișarea cu PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tipul tuner nu este corespunzător. Lansați aplicația Canale live pentru intrarea TV tip tuner."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Eroare la optimizare"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Nu s-a găsit o aplicație care să îndeplinească această acțiune."</string>
@@ -235,6 +226,8 @@
<item quantity="other">%1$d de înregistrări programate</item>
<item quantity="one">%1$d înregistrare programată</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Anulați înregistrarea"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Opriți înregistrarea"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Vizionați"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Redați de la început"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Reluați redarea"</string>
@@ -268,9 +261,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Când există prea multe programe de înregistrat în același timp, vor fi înregistrate numai cele cu priorități mai mari."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Salvați"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Înregistrările unice au cea mai mare prioritate"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Anulați"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Anulați"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Eliminați"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Opriți"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Vedeți programul de înregistrare"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Numai acest program"</string>
@@ -280,25 +270,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Înregistrați acest program"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Anulați această înregistrare"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Vedeți acum"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Ștergeți înregistrări…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Se poate înregistra"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Înregistrare programată"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Conflict privind înregistrarea"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Se înregistrează"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Nu s-a înregistrat"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Se citesc programele pentru crearea programărilor de înregistrare"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Se citesc programele"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Se citesc programele"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Vedeți înregistrările recente"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Înregistrarea pentru <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nu este finalizată."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Înregistrările pentru <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> și <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> nu sunt finalizate."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Înregistrările pentru <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> și <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> nu sunt finalizate."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Înregistrarea pentru <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nu s-a finalizat, din cauza spațiului de stocare insuficient."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Înregistrările pentru <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> și <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> nu s-au finalizat, din cauza spațiului de stocare insuficient."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Înregistrările pentru <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> și <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> nu s-au finalizat, din cauza spațiului de stocare insuficient."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR are nevoie de mai mult spațiu de stocare"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Veți putea înregistra programe folosind DVR. Cu toate acestea, momentan, pe dispozitiv nu există suficient spațiu de stocare ca să funcționeze DVR-ul. Conectați o unitate externă de cel puțin <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB și urmați pașii pentru a o formata ca stocare pe dispozitiv."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Veți putea înregistra programe folosind DVR. Cu toate acestea, momentan, pe dispozitiv nu există suficient spațiu de stocare ca să funcționeze DVR-ul. Conectați o unitate externă de cel puțin <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB și urmați pașii pentru a o formata ca stocare pe dispozitiv."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Nu există suficient spațiu de stocare"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Programul nu va fi înregistrat, deoarece nu există suficient spațiu de stocare. Ștergeți unele înregistrări existente."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Stocare lipsă"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"O parte din stocarea folosită de DVR lipsește. Pentru a reactiva DVR, conectați unitatea externă folosită anterior. Dacă stocarea externă nu mai este disponibilă, puteți să o eliminați."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Eliminați stocarea?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Tot conținutul înregistrat și toate programările vor fi șterse."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Opriți înregistrarea?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Conținutul înregistrat va fi salvat."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Înregistrarea pentru <xliff:g id="PROGRAMNAME">%1$s</xliff:g> va fi oprită, deoarece există conflicte cu acest program. Conținutul înregistrat va fi salvat."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Înregistrarea a fost programată, dar există conflicte"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Înregistrarea a început, dar există conflicte"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> va fi înregistrat."</string>
@@ -317,17 +310,34 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Același program a fost programat deja pentru înregistrare la <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Înregistrat deja"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Acest program a fost înregistrat deja. Este disponibil în biblioteca DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Înregistrarea serialului a fost programată"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> înregistrări au fost programate pentru <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> de înregistrări au fost programate pentru <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> înregistrare a fost programată pentru <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> înregistrări au fost programate pentru <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> dintre acestea nu vor fi înregistrate din cauza unor conflicte.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> de înregistrări au fost programate pentru <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> dintre acestea nu vor fi înregistrate din cauza unor conflicte.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> înregistrare a fost programată pentru <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Nu va fi înregistrată din cauza unor conflicte.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> înregistrări au fost programate pentru <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episoade din acest serial și din alte seriale nu vor fi înregistrate din cauza unor conflicte.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> de înregistrări au fost programate pentru <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episoade din acest serial și din alte seriale nu vor fi înregistrate din cauza unor conflicte.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> înregistrare a fost programată pentru <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episoade din acest serial și din alte seriale nu vor fi înregistrate din cauza unor conflicte.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> înregistrări au fost programate pentru <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Un episod din alte seriale nu va fi înregistrat din cauza unor conflicte.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> de înregistrări au fost programate pentru <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Un episod din alte seriale nu va fi înregistrat din cauza unor conflicte.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> înregistrare a fost programată pentru <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Un episod din alte seriale nu va fi înregistrat din cauza unor conflicte.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> înregistrări au fost programate pentru <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episoade din alte seriale nu vor fi înregistrate din cauza unor conflicte.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> de înregistrări au fost programate pentru <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episoade din alte seriale nu vor fi înregistrate din cauza unor conflicte.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> înregistrare a fost programată pentru <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episoade din alte seriale nu vor fi înregistrate din cauza unor conflicte.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Programul înregistrat nu a fost găsit."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Înregistrări conexe"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Nicio descriere de program)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="few">%1$d înregistrări</item>
<item quantity="other">%1$d de înregistrări</item>
@@ -349,6 +359,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Opriți înregistrarea seriei?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Episoadele înregistrate vor rămâne disponibile în biblioteca DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Opriți"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Acum nu este difuzat niciun episod."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Nu există episoade disponibile.\nAcestea vor fi înregistrate de îndată ce vor fi disponibile."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="few">(%1$d minute)</item>
@@ -361,4 +372,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, astăzi"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, mâine"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Scor"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programe înregistrate"</string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 61bef1f6..3d2e8ced 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"Моно"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"Стерео"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Управление"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Недавние каналы"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Каналы"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Настройки ТВ"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Настройки PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Команды управления недоступны для этого канала"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Воспроизведение/пауза"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Перемотать вперед"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Субтитры"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Режим"</string>
<string name="options_item_pip" msgid="3951350386626879645">"Кадр в кадре"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Вкл."</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Выкл."</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Многоканальный"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Ещё каналы"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Настройки"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Источник"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Поменять"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Вкл."</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Выкл."</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Звук"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Главное окно"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Кадр в кадре"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Расположение"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Справа внизу"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Справа вверху"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Слева вверху"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Слева внизу"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Рядом"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Размер"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Крупный"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Мелкий"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Источник"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"ТВ (антенна/кабель)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Нет информации о программах"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Неизвестно"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Заблокированный канал"</string>
- <string name="default_language" msgid="4122326459624337928">"Неизвестный язык"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Неизвестный язык"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Субтитры (%1$d)"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Субтитры"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Выкл."</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Настройка субтитров"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Группировать по"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Эта программа заблокирована"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Для программы не заданы возрастные ограничения"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Возрастное ограничение этой программы: <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Этот вход не поддерживает автоматическое сканирование"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Не удалось начать автосканирование для входа \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
@@ -94,7 +76,6 @@
<item quantity="other">Добавлено %1$d канала</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Нет каналов"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Тюнер"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Родительский контроль"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Вкл."</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Выкл."</string>
@@ -110,6 +91,8 @@
<string name="other_countries" msgid="8342216398676184749">"Другие страны"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Нет"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Без рейтинга"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Без классификации"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Блокировать программы без классификации"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Без рейтинга"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Строгие ограничения"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Средние ограничения"</string>
@@ -126,6 +109,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Введите PIN-код, чтобы посмотреть этот канал"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Введите PIN-код, чтобы посмотреть эту программу"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Возрастное ограничение для этой программы: <xliff:g id="RATING">%1$s</xliff:g>. Чтобы посмотреть ее, введите PIN-код."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Для этой программы не указаны возрастные ограничения. Чтобы посмотреть ее, введите PIN-код."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Введите PIN-код"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Чтобы установить родительский контроль, создайте PIN-код"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Введите новый PIN-код"</string>
@@ -139,22 +123,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Неверный PIN-код. Повторите попытку."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"PIN-коды не совпадают. Повторите попытку."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Введите почтовый индекс"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Приложение \"Прямой эфир\" использует почтовый индекс, чтобы создавать телегид специально для вас."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Введите почтовый индекс"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Недопустимый почтовый индекс."</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Настройки"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Настроить список"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Выбрать каналы для телегида"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Источники каналов"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Доступны новые каналы"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Родительский контроль"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Сдвиг времени"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Записывайте прямые трансляции, чтобы потом пересматривать интересные моменты.\nОбратите внимание! Когда включена эта функция, интенсивно используется внутренняя память устройства. В результате срок ее службы может сократиться."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Лицензии открытого ПО"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Лицензии открытого ПО"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Отправить отзыв"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Версия"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Чтобы смотреть этот канал, нажмите стрелку вправо и введите PIN-код."</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Чтобы смотреть эту программу, нажмите стрелку вправо и введите PIN-код."</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Для программы не заданы возрастные ограничения.\nЧтобы посмотреть ее, нажмите на стрелку вправо и введите PIN-код."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Возрастное ограничение этой программы: <xliff:g id="RATING">%1$s</xliff:g>.\nЧтобы посмотреть ее, нажмите на стрелку вправо и введите PIN-код."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Чтобы смотреть этот канал, используйте приложение для просмотра телепрограмм по умолчанию."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Чтобы посмотреть эту программу, используйте приложение для просмотра телепрограмм по умолчанию."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Для программы не заданы возрастные ограничения.\nЧтобы посмотреть ее, используйте приложение для просмотра телепрограмм, установленное по умолчанию."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Возрастное ограничение для этой программы: <xliff:g id="RATING">%1$s</xliff:g>.\nЧтобы посмотреть ее, используйте приложение для просмотра телепрограмм по умолчанию."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Программа заблокирована"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Для программы не заданы возрастные ограничения"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Возрастное ограничение этой программы: <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Только аудио"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Слабый сигнал"</string>
@@ -189,8 +182,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Нажмите кнопку \"ВЫБРАТЬ\""</b>", чтобы открыть меню телевизора."</string>
<string name="msg_no_input" msgid="3897674146985427865">"ТВ-вход не найден"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Не удается найти ТВ-вход"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP не поддерживается"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Нет источника для режима PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Для ТВ-входа типа \"тюнер\" используйте приложение \"Прямой эфир\""</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Не удалось выполнить настройку"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Действие не поддерживается ни в одном приложении."</string>
@@ -244,6 +235,8 @@
<item quantity="many">%1$d запланированных записей</item>
<item quantity="other">%1$d запланированной записи</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Отменить запись"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Остановить запись"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Смотреть"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Смотреть с начала"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Продолжить просмотр"</string>
@@ -278,9 +271,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Если вы выберете слишком много программ для одновременной записи, будут записываться только те, у которых наивысший приоритет."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Сохранить"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Однократная запись имеет самый высокий приоритет"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Отмена"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Отмена"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Удалить"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Остановить"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Смотреть расписание записи"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Только эту серию"</string>
@@ -290,25 +280,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Записать эту программу"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Отменить эту запись"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Смотреть"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Удалить записи…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Можно записать"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Таймер записи установлен"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Конфликт таймера записи"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Идет запись"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Ошибка записи видео"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Выполняется чтение программ. Будет создано расписание записи."</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Выполняется чтение программ…"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Выполняется чтение программ…"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Недавние записи"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Не удалось завершить запись \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\"."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Не удалось завершить записи \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\" и \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\"."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Не удалось завершить записи \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\", \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" и \"<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>\"."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Не удалось завершить запись \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" из-за нехватки места."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Не удалось завершить записи \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\" и \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" из-за нехватки места."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Не удалось завершить записи \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\", \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" и \"<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>\" из-за нехватки места."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Недостаточно места на устройстве"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Вы сможете записывать программы на DVR, однако в настоящее время на вашем устройстве недостаточно места. Подключите внешний накопитель объемом не менее <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> ГБ и отформатируйте его как память устройства."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Вы сможете записывать программы на DVR, однако в настоящее время на вашем устройстве недостаточно места. Подключите внешний накопитель объемом не менее <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> ГБ и отформатируйте его как память устройства."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Недостаточно места"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Недостаточно места для сохранения данных. Попробуйте удалить несколько ненужных записей."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Хранилище отсутствует"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Хранилище не найдено. Подсоедините внешний диск, прежде чем снова включить видеомагнитофон, либо удалите хранилище, если оно недоступно."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Удалить хранилище?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Все созданные и запланированные записи будут стерты."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Остановить запись?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Записанный контент будет сохранен."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Запись сериала \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" будет остановлена из-за конфликта в расписании. Записанный контент сохранится."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Возник конфликт в расписании записи"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Возник конфликт в расписании записи"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Программа \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" будет записана."</string>
@@ -328,17 +321,39 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Запись этой программы уже запланирована на <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Программа уже записана"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Эта программа сохранена в библиотеке видеорекордера."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Запись запланирована"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one">Запланирована <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> запись сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\".</item>
+ <item quantity="few">Запланировано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записи сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\".</item>
+ <item quantity="many">Запланировано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записей сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\".</item>
+ <item quantity="other">Запланировано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записи сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\".</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one">Запланирована <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> запись сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>) этого сериала не будут записаны из-за конфликта в расписании.</item>
+ <item quantity="few">Запланировано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записи сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>) этого сериала не будут записаны из-за конфликта в расписании.</item>
+ <item quantity="many">Запланировано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записей сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>) этого сериала не будут записаны из-за конфликта в расписании.</item>
+ <item quantity="other">Запланировано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записи сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>) этого сериала не будут записаны из-за конфликта в расписании.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one">Запланирована <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> запись сериала \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) этого и других сериалов не будут записаны из-за конфликта в расписании.</item>
+ <item quantity="few">Запланировано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записи сериала \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) этого и других сериалов не будут записаны из-за конфликта в расписании.</item>
+ <item quantity="many">Запланировано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записей сериала \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) этого и других сериалов не будут записаны из-за конфликта в расписании.</item>
+ <item quantity="other">Запланировано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записи сериала \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) этого и других сериалов не будут записаны из-за конфликта в расписании.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one">Запланирована <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> запись сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Одна серия другого сериала не будет записана из-за конфликта в расписании.</item>
+ <item quantity="few">Запланировано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записи сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Одна серия другого сериала не будет записана из-за конфликта в расписании.</item>
+ <item quantity="many">Запланировано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записей сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Одна серия другого сериала не будет записана из-за конфликта в расписании.</item>
+ <item quantity="other">Запланировано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записи сериала \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Одна серия другого сериала не будет записана из-за конфликта в расписании.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one">Запланирована <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> запись сериала \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) других сериалов не будут записаны из-за конфликта в расписании.</item>
+ <item quantity="few">Запланировано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записи сериала \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) других сериалов не будут записаны из-за конфликта в расписании.</item>
+ <item quantity="many">Запланировано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записей сериала \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) других сериалов не будут записаны из-за конфликта в расписании.</item>
+ <item quantity="other">Запланировано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записи сериала \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Несколько серий (<xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>) других сериалов не будут записаны из-за конфликта в расписании.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Записанная программа не найдена."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Похожие записи"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(без описания)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d запись</item>
<item quantity="few">%1$d записи</item>
@@ -362,6 +377,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Остановить запись?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Записанные серии будут сохранены в библиотеке видеорекордера."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Остановить"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"В эфире нет ни одной серии."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Серий пока нет.\nОни будут записаны, как только выйдут в эфир."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d минута)</item>
@@ -375,4 +391,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Сегодня, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Завтра, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Оценка"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Записанные программы"</string>
</resources>
diff --git a/res/values-si-v23/strings.xml b/res/values-si-rLK-v23/strings.xml
index 1209e55b..1209e55b 100644
--- a/res/values-si-v23/strings.xml
+++ b/res/values-si-rLK-v23/strings.xml
diff --git a/res/values-si/arrays.xml b/res/values-si-rLK/arrays.xml
index 657fb91d..657fb91d 100644
--- a/res/values-si/arrays.xml
+++ b/res/values-si-rLK/arrays.xml
diff --git a/res/values-si/rating_system_strings.xml b/res/values-si-rLK/rating_system_strings.xml
index f22044ba..f22044ba 100644
--- a/res/values-si/rating_system_strings.xml
+++ b/res/values-si-rLK/rating_system_strings.xml
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
new file mode 100644
index 00000000..2cd7fbf0
--- /dev/null
+++ b/res/values-si-rLK/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"මොනෝ"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"ස්ටීරියෝ"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"ධාවක පාලන"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"නාලිකා"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"රූපවාහිනී විකල්ප"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"මෙම නාලිකාව සඳහා Play පාලන ලද නොහැකිය"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ධාවනය හෝ විරාමය කරන්න"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"වේගයෙන් ඉදිරියට"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"නැවත ඔතන්න"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"ඊළඟ"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"පෙර"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"වැඩසටහන් නියාමකය"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"නව නාලිකා දැන් තිබේ"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> විවෘත කරන්න"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"වසන ලද ශිර්ෂ"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"දර්ශන ආකාරය"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"බහු-ශ්‍රව්‍ය"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"තවත් නාලිකා ගන්න"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"සැකසීම්"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (ඇන්ටනාව/කේබලය)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"වැඩසටහන් තොරතුරු නැත"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"තොරතුරු නැත."</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"නාලිකාව අවහිර කරන ලදි"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"නොදන්නා භාෂාව"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"වැසූ සිරස්තල %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"වැසූ සිරස්තල"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"අක්‍රිය කරන්න"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"ආකෘතිකරණය අභිරුචි කරන්න"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"වසන ලද ශීර්ෂ සඳහා පද්ධතිය-පුරා මනාපයන් සකසන්න"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"දර්ශන ආකාරය"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"බහු-ශ්‍රව්‍ය"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"මොනෝ"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ස්ටීරියෝ"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 සරවුන්ඩ්"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 සරවුන්ඩ්"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"නාලිකා %1$d"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"අභිරුචිකරණය කළ නාලිකා ලැයිස්තුව"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"වර්ගය තෝරන්න"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"වර්ග තේරීම ඉවත් කරන්න"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"වර්ග මගින්"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"නාලිකාවේ මූලය"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"වර්ග මගින්"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"මෙම වැඩසටහන අවහිර කර තිබේ"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"මෙම වැඩසටහන අගයා නැත"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"මෙම වැඩසටහන <xliff:g id="RATING">%1$s</xliff:g> ලෙස අගයා ඇත"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"ආදානය ස්වයංක්‍රිය-සම්මුර්ත කිරීමටසහාය නොදේ"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' සඳහා ස්වයංක්‍රිය-පරිලෝකනය ආරම්භ කිරීමට නොහැකි විය"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"උපසිරැසි සඳහා පද්ධතිය-පුරා මනාපයන් ආරම්භ කළ නොහැක."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="one">නාලිකා %1$dක් එක් කරන ලදී</item>
+ <item quantity="other">නාලිකා %1$dක් එක් කරන ලදී</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"නාලිකා එකතු කළේ නැත"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"මව්පිය පාලනය"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"සක්‍රිය කරන්න"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"අක්‍රිය කරන්න"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"නාලිකා අවහිර කරන ලදි"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"සියල්ල අවහිර කරන්න"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"සියල්ල අවහිර නොකරන්න"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"සැඟවුණු නාලිකා"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"වැඩ සටහන සීමා කිරීම්"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN වෙනස් කරන්න"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"ඇගයීම පද්ධති"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"ශ්‍රේණිගත කිරීම්"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"සියළුම ඇගයීම පද්ධති බලන්න"</string>
+ <string name="other_countries" msgid="8342216398676184749">"වෙනත් රටවල්"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"කිසිවක් නැත"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"කිසිවක් නැත"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"අගයා නොමැති"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"අගයා නැති වැඩසටහන් අවහිර කරන්න"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"කිසිවක් නැත"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"ඉහළ සීමා කිරීම්"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"මධ්‍යම සීමා කිරීම්"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"අඩු සීමා කිරීම්"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"අභිරුචි"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"යොවුන් ළමයි සඳහා අන්තර්ගතයන් සුදුසුය"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"යොවුන් ළමයි සඳහා අන්තර්ගතයන් සුදුසුය"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"යොවුන් ළමයි සඳහා අන්තර්ගතයන් සුදුසුය"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"අයාන්ත්‍රික සීමා කිරීම්"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s සහ උප-ඇගයීම්"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"උප-ඇගයීම්"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"මෙම නාලිකාව නැරඹිමට ඔබගේ PIN එක ඇතුළු කරන්න"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"මෙම වැඩසටහන නැරඹිමට ඔබගේ PIN එක ඇතුළු කරන්න"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"මෙම වැඩසටහන <xliff:g id="RATING">%1$s</xliff:g> ඇගයුම ලබා ඇත. මෙම වැඩසටහන නැරඹිමට ඔබගේ PIN එක ඇතුළු කරන්න"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"මෙම වැඩසටහන අගයා නැත. මෙම වැඩසටහන නැරඹිමට ඔබගේ PIN එක ඇතුළු කරන්න"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"ඔබගේ PIN එක ඇතුළු කරන්න"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"මව්පිය පාලකයක් සකසන්න, PIN එකක් සාදන්න"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"අලුත් PIN එක ඇතුළු කරන්න"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"ඔබගේ PIN එක තහවුරු කරන්න"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"ඔබගේ දැනට තිබෙන PIN එක ඇතුළු කරන්න"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="one">ඔබ විසින් වැරදි PIN අංකය 5 වතාවක් ඇතුළු කරන ලදී.\nතත්පර <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g>කින් නැවත උත්සාහ කරන්න.</item>
+ <item quantity="other">ඔබ විසින් වැරදි PIN අංකය 5 වතාවක් ඇතුළු කරන ලදී.\nතත්පර <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g>කින් නැවත උත්සාහ කරන්න.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"එම PIN එක වැරදිය. නැවත උත්සාහ කරන්න."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"PIN එක ගැලපී නැත"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"ඔබේ ZIP කේතය ඇතුළු කරන්න."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"සජීව නාලිකා යෙදුම TV නාලිකා සඳහා සම්පූර්ණ වැඩසටහන් මාර්ගෝපදේශයක් සැපයීමට ZIP කේතය භාවිත කරනු ඇත."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"ඔබේ ZIP කේතය ඇතුළු කරන්න"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"වලංගු නොවන ZIP කේතයකි"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"සැකසීම්"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"නාලිකා ලැයිස්තුව අභිමත කරන්න"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ඔබගේ වැඩසටහන් මාර්ගෝපදේශය සඳහා නාලිකා තෝරන්න"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"නාලිකා මූලාශ්‍ර"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"නව නාලිකා තිබේ"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"මාපිය පාලන"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"ඔබට වැඩසටහන් විරාම කිරීමට හෝ ප්‍රතිවාදනය කිරීමට හැකි වන ලෙස නරඹන අතරතුර පටිගත කරන්න.\nඅවවාදයයි: මෙය අභ්‍යන්තර ගබඩාවෙහි ආයු කාලය ගබඩාව දැඩි ලෙස භාවිත කිරීමෙන් අඩු කළ හැකිය."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"විවෘත මූලාශ්‍ර බලපත්‍ර"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"ප්‍රතිපෝෂණය යවන්න"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"අනුවාදය"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"මෙම නාලිකාව නැරඹිමට දකුණ ඔබා PIN එක ඇතුළු කරන්න"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"මෙම වැඩසටහන නැරඹිමට දකුණ ඔබා PIN එක ඇතුළු කරන්න"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"මෙම වැඩසටහන අගයා නැත.\nමෙම වැඩසටහන නැරඹීමට දකුණ ඔබා ඔබගේ PIN එක ඇතුළු කරන්න"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"මෙම වැඩසටහන <xliff:g id="RATING">%1$s</xliff:g> අගයන ලදි.\nමෙම වැඩසටහන නැරඹීමට දකුණ ඔබා ඔබගේ PIN එක ඇතුළු කරන්න."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"මෙම නාලිකාව නැරඹීම සඳහා, පෙරනිමි සජීවි TV යෙදුම භාවිතා කරන්න."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"මෙම වැඩසටහන නැරඹීමට, පෙරනිමි සජීවි TV යෙදුම භාවිතා කරන්න."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"මෙම වැඩසටහන අගයා නැත.\nමෙම වැඩසටහන නැරඹීමට, පෙරනිමි සජීවි TV යෙදුම භාවිත කරන්න."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"මෙම වැඩසටහන <xliff:g id="RATING">%1$s</xliff:g> ලෙස වර්ගීකරණය කර ඇත.\nමෙම වැඩසටහන නැරඹීමට, පෙරනිමි සජීවි TV යෙදුම භාවිතා කරන්න."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"වැඩසටහන අවහිර කරන ලදි"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"මෙම වැඩසටහන අගයා නැත"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"මෙම වැඩසටහන <xliff:g id="RATING">%1$s</xliff:g> ලෙස අගයා ඇත"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ශ්‍රව්‍ය පමණයි"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"දුර්වල සංඥාව"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"අන්තර්ජාල සබැඳුමක් නැත"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="one">වෙනත් නාලිකා පටිගත වෙමින් ඇති නිසා මෙම නාලිකාව <xliff:g id="END_TIME_1">%1$s</xliff:g> වනතෙක් ධාවනය කළ නොහැකිය. \n\nපටිගත කිරීමේ කාල සටහන සීරුමාරු කිරීමට දකුණ ඔබන්න.</item>
+ <item quantity="other">වෙනත් නාලිකා පටිගත වෙමින් ඇති නිසා මෙම නාලිකාව <xliff:g id="END_TIME_1">%1$s</xliff:g> වනතෙක් ධාවනය කළ නොහැකිය. \n\nපටිගත කිරීමේ කාල සටහන සීරුමාරු කිරීමට දකුණ ඔබන්න.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"මාතෘකාවක් නොමැත"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"නාලිකාව අවහිර කරන ලදි"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"නව"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"මූලාශ්‍ර"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="one">නාලිකා %1$d</item>
+ <item quantity="other">නාලිකා %1$d</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"ලබා ගත හැකි නාලිකා නැත"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"නව"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"සකසා නැත"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"තවත් මූලාශ්‍ර ලබා ගන්න"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"සජීව නාලිකා පිරිනමන යෙදුම් බ්‍රවුස් කරන්න"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"නව නාලිකා මූලාශ්‍ර ලබා ගත හැකිය"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"නව නාලිකා මූලාශ්‍රවලට පිරිනැමීමට නාලිකා ඇත.\nඒවා දැන් පිහිටුවන්න, නැතහොත් මෙය පසුව නාලිකා මූලාශ්‍ර සැකසීම තුළ සිදු කරන්න."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"දැන් පිහිටුවන්න"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"හරි, තේරුණා"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"TV මෙනුවට පිවිසීමට "<b>"SELECT ඔබන්න"</b>"."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"TV ආදානය සොයාගැනීමට නොහැකි විය"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"TV ආදානය සොයාගත නොහැක"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"සුසරක වර්ගය ගැලපෙන්නේ නැත; කරුණාකර සුසර කරන වර්ගයේ TV අදානය සඳහා සජීවී නාලිකා යෙදුම දමන්න."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"සුසර කිරීම අසාර්ථක වුණි"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"මෙම ක්‍රියාව හැසිරවීමට යෙදුමක් සොයාගත්තේ නැත"</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"සියලුම මූල නාලිකා සඟවන ලදි.\nනැරඹීමට අඩුම තරමේ එක නාලිකාවක් වත් තෝරන්න."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"වීඩියෝව බලාපොරොත්තු නොවූ ලෙස නොතිබේ"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"සම්බන්ධිත උපාංගය සඳහා BACK යතුර. පිටවීමට Home බොත්තම ඔබන්න."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"සජීවී නාලිකාවලට TV ලැයිස්තුගත කිරීම් කියවීමට අවසරය අවශ්‍යයි."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"ඔබගේ මූලාශ්‍ර පිහිටුවන්න"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"සජීවී නාලිකා සම්ප්‍රදායික TV නාලිකාවල අත්දැකීම යෙදුම්වලින් සපයන ප්‍රවාහ කිරීමේ නාලිකා සමග ඒකාබද්ධ කරයි. \n\nදැනටමත් ස්ථාපනය කර ඇති නාලිකා මූලාශ්‍ර පිහිටුවීමෙන් ආරම්භ කරන්න. නැතහොත් සජීවී නාලිකා පිරිනමන තවත් යෙදුම් සඳහා Google Play Store බ්‍රවුස් කරන්න."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"පටිගත කිරීම් සහ කාලසටහන්"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"මිනිත්තු 10"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"මිනිත්තු 30"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"පැය 1"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"පැය 3"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"මෑත"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"නියමිත"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"මාලා"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"වෙනත්"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"නාලිකාව පටිගත කළ නොහැකිය."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"වැඩසටහන පටිගත කළ නොහැකිය."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> පටිගත කිරීමට කාල සටහන්ගත කර ඇත"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> දැන් සිට <xliff:g id="ENDTIME">%2$s</xliff:g> දක්වා පටිගත කරමින්"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"සම්පූර්ණ කාල සටහන"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="one">ඊළඟ දින %1$d</item>
+ <item quantity="other">ඊළඟ දින %1$d</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="one">මිනිත්තු %1$d</item>
+ <item quantity="other">මිනිත්තු %1$d</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="one">නව පටිගත කිරීම් %1$d</item>
+ <item quantity="other">නව පටිගත කිරීම් %1$d</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="one">පටිගත කිරීම් %1$d</item>
+ <item quantity="other">පටිගත කිරීම් %1$d</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="one">පටිගත කිරීම් %1$dක් කාලසටහන්ගත කර ඇත</item>
+ <item quantity="other">පටිගත කිරීම් %1$dක් කාලසටහන්ගත කර ඇත</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"පටිගත කිරීම අවලංගු කරන්න"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"පටිගත කිරීම නවත්වන්න"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"ඔරලෝසුව"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"මුල සිට ධාවනය කරන්න"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"ධාවනය නැවත පටන් ගැනීම"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"මකන්න"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"පටිගත කිරීම් මකන්න"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"නැවත පටන්ගන්න"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"වෙළුම <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"කාල සටහන බලන්න"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"තව කියවන්න"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"පටිගත කිරීම් මකන්න"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"ඔබ මැකීමට කැමති කථාංග තෝරන්න. වරක් මැකූ පසු ඒවා ප්‍රතිසාධනය කළ නොහැකිය."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"මැකීමට පටිගත කිරීම් නැත."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"නැරඹූ කථාංග තෝරන්න"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"සියලු කථාංග තෝරන්න"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"සියලු කථාංග තේරීම ඉවත් කරන්න"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"මිනිත්තු <xliff:g id="DURATION">%2$d</xliff:g>කින් <xliff:g id="WATCHED">%1$d</xliff:g>ක් නරඹන ලදී"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"තත්පර <xliff:g id="DURATION">%2$d</xliff:g>කින් <xliff:g id="WATCHED">%1$d</xliff:g>ක් නරඹන ලදී"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"කිසිදා නරඹා නැත"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="one">කථාංග %2$dකින් %1$dක් මකා ඇත</item>
+ <item quantity="other">කථාංග %2$dකින් %1$dක් මකා ඇත</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ප්‍රමුඛතාව"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"වැඩිම"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"අඩුම"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"නැත. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"නාලිකා"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ඕනෑම"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"ප්‍රමුඛතාව තේරීම"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"එකම අවස්ථාවේදී පටිගත කිරීමට ප්‍රමාණයට වඩා වැඩි වැඩසටහන් ගණන් ඇති විට, වඩා ඉහළ ප්‍රමුඛතා සහිත ඒවා පමණක් පටිගත කරනු ඇත."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"සුරකින්න"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"එක්-වරක පටිගත කිරීම්වලට වැඩිම ප්‍රමුඛතාව ඇත"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"නතර කරන්න"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"පටිගත කිරීමේ කාල සටහන බලන්න"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"මෙම තනි වැඩසටහන"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"දැන් - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"මුළු මාලාව…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"කෙසේ වෙතත් කාල සටහන්ගත කරන්න"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"ඒ වෙනුවට මෙය පටිගත කරන්න"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"මෙම පටිගත කිරීම අවලංගු කරන්න"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"දැන් නරඹන්න"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"පටිගත කිරීම් මකන්න..."</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"පටිගත කළ හැකි"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"පටිගත කිරීම කාල සටහන්ගතයි"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"පටිගත කිරීමේ ගැටුම"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"පටිගත කරමින්"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"පටිගත කිරීම අසාර්ථක විය"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"කියවීමේ වැඩසටහන්"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"මෑත පටිගත කිරීම් බලන්න"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> හි පටිගත කිරීම අසම්පූර්ණයි."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> සහ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> හි පටිගත කිරීම් අසම්පූර්ණයි."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> සහ <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> හි පටිගත කිරීම් අසම්පූර්ණයි."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"ප්‍රමාණවත් නොවන ගබඩාව නිසා <xliff:g id="PROGRAMNAME">%1$s</xliff:g> හි පටිගත කිරීම සම්පූර්ණ නොකරන ලදී."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"ප්‍රමාණවත් නොවන ගබඩාව නිසා <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> සහ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> හි පටිගත කිරීම් සම්පූර්ණ නොකරන ලදී."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"ප්‍රමාණවත් නොවන ගබඩාව නිසා <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> සහ <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> හි පටිගත කිරීම් සම්පූර්ණ නොකරන ලදී."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR සඳහා වැඩිපුර ගබඩාව අවශ්‍යයි"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"ඔබට DVR සමගින් වැඩසටහන් පටිගත කිරීමට හැකි වනු ඇත. කෙසේ වෙතත් දැන් DVR ක්‍රියා කිරීම සඳහා ඔබේ උපාංගයේ ප්‍රමාණවත් තරම් ගබඩාව නැත. කරුණාකර <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB හෝ ඊට වඩා විශාල බාහිර ධාවකයක් සම්බන්ධ කර එය උපාංග ගබඩාව ලෙස ෆෝමැට් කිරීමට පහත පියවර අනුගමනය කරන්න."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"ප්‍රමාණවත් තරම් ගබඩා ඉඩ නැත"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"ප්‍රමාණවත් තරම් ගබඩා ඉඩ නොමැති නිසා මෙම වැඩසටහන පටිගත කළ නොහැකි වනු ඇත. පවතින පටිගත කිරීම් සමහරක් මැකීම උත්සාහ කරන්න."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"අස්ථානගත ගබඩාව"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"පටිගත කිරීම නවත්වන්නද?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"පටිගත කළ අන්තර්ගතය සුරැකෙනු ඇත."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"මෙම වැඩසටහන සමගින් වන ගැටුම් නිසා <xliff:g id="PROGRAMNAME">%1$s</xliff:g> හි පටිගත කිරීම නවත්වන ලදී. පටිගත කරන ලද අන්තර්ගතය සුරකිනු ඇත."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"පටිගත කිරීම කාල සටහන්ගත කර ඇති නමුත් ගැටුම් ඇත"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"පටිගත කිරීම ආරම්භ කර ඇති නමුත් ගැටුම් ඇත"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> පටිගත කරනු ඇත."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> වාර්තා කරමින් පවතී."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> හි සමහර කොටස් පටිගත නොකරනු ඇත."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> සහ <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> හි සමහර කොටස් පටිගත නොකරනු ඇත."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> හි සමහර කොටස් සහ තවත් එක් කාලසටහනක් පටිගත නොකරනු ඇත."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> හි සමහර කොටස් සහ තව කාල සටහන් %3$dක් පටිගත නොකරනු ඇත.</item>
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> හි සමහර කොටස් සහ තව කාල සටහන් %3$dක් පටිගත නොකරනු ඇත.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"ඔබ පටිගත කිරීමට කැමති කුමක්ද?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"ඔබ කොපමණ කාලයක් පටිගත කිරීමට කැමතිද?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"දැනටමත් කාලසටහන්ගත කර ඇත"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"එම වැඩසටහනම <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>ට පටිගත කිරීමට කාල සටහන්ගත කර ඇත."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"දැනටමත් පටිගත කර ඇත"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"මෙම වැඩසටහන දැනටමත් පටිගත කර ඇත. එය DVR පුස්තකාලය තුළදී ලබා ගත හැකිය."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"මාලා පටිගත කිරීම කාලසටහන්ගත කරන ලදී"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one">පටිගත කිරීම් <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>ක් <xliff:g id="SERIESNAME_3">%2$s</xliff:g> සඳහා කාල සටහන්ගත කර ඇත.</item>
+ <item quantity="other">පටිගත කිරීම් <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>ක් <xliff:g id="SERIESNAME_3">%2$s</xliff:g> සඳහා කාල සටහන්ගත කර ඇත.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one">පටිගත කිරීම් <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>ක් <xliff:g id="SERIESNAME_3">%2$s</xliff:g> සඳහා කාල සටහන්ගත කර ඇත. ඒවායින් <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>ක් ගැටුම් නිසා පටිගත නොකරනු ඇත.</item>
+ <item quantity="other">පටිගත කිරීම් <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>ක් <xliff:g id="SERIESNAME_3">%2$s</xliff:g> සඳහා කාල සටහන්ගත කර ඇත. ඒවායින් <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>ක් ගැටුම් නිසා පටිගත නොකරනු ඇත.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one">පටිගත කිරීම් <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>ක් <xliff:g id="SERIESNAME_4">%2$s</xliff:g> සඳහා කාල සටහන්ගත කර ඇත. මෙම මාලාවෙහි සහ වෙනත් මාලාවල කථාංග <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>ක් ගැටුම් නිසා පටිගත නොකරනු ඇත.</item>
+ <item quantity="other">පටිගත කිරීම් <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>ක් <xliff:g id="SERIESNAME_4">%2$s</xliff:g> සඳහා කාල සටහන්ගත කර ඇත. මෙම මාලාවෙහි සහ වෙනත් මාලාවල කථාංග <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>ක් ගැටුම් නිසා පටිගත නොකරනු ඇත.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one">පටිගත කිරීම් <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>ක් <xliff:g id="SERIESNAME_3">%2$s</xliff:g> සඳහා කාලසටහන්ගත කර ඇත. වෙනත් මාලාවල කථාංග 1ක් ගැටුම් නිසා පටිගත නොකරනු ඇත.</item>
+ <item quantity="other">පටිගත කිරීම් <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g>ක් <xliff:g id="SERIESNAME_3">%2$s</xliff:g> සඳහා කාලසටහන්ගත කර ඇත. වෙනත් මාලාවල කථාංග 1ක් ගැටුම් නිසා පටිගත නොකරනු ඇත.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one">පටිගත කිරීම් <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>ක් <xliff:g id="SERIESNAME_4">%2$s</xliff:g> සඳහා කාල සටහන්ගත කර ඇත. වෙනත් මාලාවේ කථාංග <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>ක් ගැටුම් නිසා පටිගත නොකරනු ඇත.</item>
+ <item quantity="other">පටිගත කිරීම් <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g>ක් <xliff:g id="SERIESNAME_4">%2$s</xliff:g> සඳහා කාල සටහන්ගත කර ඇත. වෙනත් මාලාවේ කථාංග <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>ක් ගැටුම් නිසා පටිගත නොකරනු ඇත.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"පටිගත කළ වැඩසටහන හමු නොවීය."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"අදාළ පටිගත කිරීම්"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="one">පටිගත කිරීම් %1$d</item>
+ <item quantity="other">පටිගත කිරීම් %1$d</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"පටිගත කිරීමේ කාල සටහනින් <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ඉවත් කරන ලදී"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"සුසරක ගැටුම් නිසා අර්ධ වශයෙන් පටිගත කරනු ඇත."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"සුසරක ගැටුම් නිසා පටිගත නොකරනු ඇත."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"තවම කාල සටහනෙහි පටිගත කිරීම් නැත.\nඔබට වැඩසටහන් මාර්ගෝපදේශය වෙතින් පටිගත කිරීම කාලසටහන්ගත කළ හැකිය."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="one">පටිගත කිරීමේ ගැටුම් %1$d</item>
+ <item quantity="other">පටිගත කිරීමේ ගැටුම් %1$d</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"මාලා සැකසීම්"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"මාලා පටිගත කිරීම අරඹන්න"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"මාලා පටිගත කිරීම නවත්වන්න"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"මාලා පටිගත කිරීම නවත්වන්නද?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"පටිගත කළ කථාංග DVR පුස්තකාලය තුළ ලබා ගත හැකිව පවතිනු ඇත."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"නවත්වන්න"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"දැන් ගුවනේ කථාංග නැත."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ලබා ගත හැකි කථාංග නැත.\nඒවා ලබා ගත හැකි වූ විට පටිගත කරනු ඇත."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="one">(මිනිත්තු %1$d)</item>
+ <item quantity="other">(මිනිත්තු %1$d)</item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"අද"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"හෙට"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"ඊයේ"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"අද <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"හෙට <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"ලකුණු"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"පටිගත කළ වැඩසටහන්"</string>
+</resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
deleted file mode 100644
index eab8c336..00000000
--- a/res/values-si/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"මොනෝ"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"ස්ටීරියෝ"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"ධාවක පාලන"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"මෑත නාලිකා"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"රූපවාහිනී විකල්ප"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP විකල්ප"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"මෙම නාලිකාව සඳහා Play පාලන ලද නොහැකිය"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ධාවනය හෝ විරාමය කරන්න"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"වේගයෙන් ඉදිරියට"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"නැවත ඔතන්න"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"ඊළඟ"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"පෙර"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"වැඩසටහන් නියාමකය"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"නව නාලිකා දැන් තිබේ"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> විවෘත කරන්න"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"වසන ලද ශිර්ෂ"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"දර්ශන ආකාරය"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"සක්‍රියයි"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"අක්‍රිය කරන්න"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"බහු-ශ්‍රව්‍ය"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"තවත් නාලිකා ගන්න"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"සැකසීම්"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"මුල්‍ය"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"මාරු කරන්න"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"සක්‍රියයි"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"අක්‍රිය කරන්න"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"ශබ්දය"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"මූලික"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP කවුළුව"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"පිරිසැලසුම"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"පහළ දකුණ"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"ඉහළ දකුණ"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"ඉහළ වම"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"පහළ වම"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"පැතෙන් පැත්තට"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"ප්‍රමාණය"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"ලොකු"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"කුඩා"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"මූලය අදානය කරන්න"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (ඇන්ටනාව/කේබලය)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"වැඩසටහන් තොරතුරු නැත"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"තොරතුරු නැත."</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"නාලිකාව අවහිර කරන ලදි"</string>
- <string name="default_language" msgid="4122326459624337928">"නොදන්නා භාෂාව"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"වැසූ සිරස්තල"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"අක්‍රිය කරන්න"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"ආකෘතිකරණය අභිරුචි කරන්න"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"වසන ලද ශීර්ෂ සඳහා පද්ධතිය-පුරා මනාපයන් සකසන්න"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"දර්ශන ආකාරය"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"බහු-ශ්‍රව්‍ය"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"මොනෝ"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ස්ටීරියෝ"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 සරවුන්ඩ්"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 සරවුන්ඩ්"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"නාලිකා %1$d"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"අභිරුචිකරණය කළ නාලිකා ලැයිස්තුව"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"වර්ගය තෝරන්න"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"වර්ග තේරීම ඉවත් කරන්න"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"වර්ග මගින්"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"නාලිකාවේ මූලය"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"වර්ග මගින්"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"මෙම වැඩසටහන අවහිර කර තිබේ"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"මෙම වැඩසටහන <xliff:g id="RATING">%1$s</xliff:g> ලෙස අගයා ඇත"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"ආදානය ස්වයංක්‍රිය-සම්මුර්ත කිරීමටසහාය නොදේ"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' සඳහා ස්වයංක්‍රිය-පරිලෝකනය ආරම්භ කිරීමට නොහැකි විය"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"උපසිරැසි සඳහා පද්ධතිය-පුරා මනාපයන් ආරම්භ කළ නොහැක."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="one">නාලිකා %1$dක් එක් කරන ලදී</item>
- <item quantity="other">නාලිකා %1$dක් එක් කරන ලදී</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"නාලිකා එකතු කළේ නැත"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"සුසරකය"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"මව්පිය පාලනය"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"සක්‍රිය කරන්න"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"අක්‍රිය කරන්න"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"නාලිකා අවහිර කරන ලදි"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"සියල්ල අවහිර කරන්න"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"සියල්ල අවහිර නොකරන්න"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"සැඟවුණු නාලිකා"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"වැඩ සටහන සීමා කිරීම්"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN වෙනස් කරන්න"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"ඇගයීම පද්ධති"</string>
- <string name="option_ratings" msgid="4009116954188688616">"ශ්‍රේණිගත කිරීම්"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"සියළුම ඇගයීම පද්ධති බලන්න"</string>
- <string name="other_countries" msgid="8342216398676184749">"වෙනත් රටවල්"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"කිසිවක් නැත"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"කිසිවක් නැත"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"කිසිවක් නැත"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"ඉහළ සීමා කිරීම්"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"මධ්‍යම සීමා කිරීම්"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"අඩු සීමා කිරීම්"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"අභිරුචි"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"යොවුන් ළමයි සඳහා අන්තර්ගතයන් සුදුසුය"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"යොවුන් ළමයි සඳහා අන්තර්ගතයන් සුදුසුය"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"යොවුන් ළමයි සඳහා අන්තර්ගතයන් සුදුසුය"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"අයාන්ත්‍රික සීමා කිරීම්"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s සහ උප-ඇගයීම්"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"උප-ඇගයීම්"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"මෙම නාලිකාව නැරඹිමට ඔබගේ PIN එක ඇතුළු කරන්න"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"මෙම වැඩසටහන නැරඹිමට ඔබගේ PIN එක ඇතුළු කරන්න"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"මෙම වැඩසටහන <xliff:g id="RATING">%1$s</xliff:g> ඇගයුම ලබා ඇත. මෙම වැඩසටහන නැරඹිමට ඔබගේ PIN එක ඇතුළු කරන්න"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"ඔබගේ PIN එක ඇතුළු කරන්න"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"මව්පිය පාලකයක් සකසන්න, PIN එකක් සාදන්න"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"අලුත් PIN එක ඇතුළු කරන්න"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"ඔබගේ PIN එක තහවුරු කරන්න"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"ඔබගේ දැනට තිබෙන PIN එක ඇතුළු කරන්න"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="one">ඔබ විසින් වැරදි PIN අංකය 5 වතාවක් ඇතුළු කරන ලදී.\nතත්පර <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g>කින් නැවත උත්සාහ කරන්න.</item>
- <item quantity="other">ඔබ විසින් වැරදි PIN අංකය 5 වතාවක් ඇතුළු කරන ලදී.\nතත්පර <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g>කින් නැවත උත්සාහ කරන්න.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"එම PIN එක වැරදිය. නැවත උත්සාහ කරන්න."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"PIN එක ගැලපී නැත"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"සැකසීම්"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"නාලිකා ලැයිස්තුව අභිමත කරන්න"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"ඔබගේ වැඩසටහන් මාර්ගෝපදේශය සඳහා නාලිකා තෝරන්න"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"නාලිකා මූලාශ්‍ර"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"නව නාලිකා තිබේ"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"මාපිය පාලන"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"විවෘත මූලාශ්‍ර බලපත්‍ර"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"විවෘත මූලාශ්‍ර වරපත්"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"අනුවාදය"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"මෙම නාලිකාව නැරඹිමට දකුණ ඔබා PIN එක ඇතුළු කරන්න"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"මෙම වැඩසටහන නැරඹිමට දකුණ ඔබා PIN එක ඇතුළු කරන්න"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"මෙම වැඩසටහන <xliff:g id="RATING">%1$s</xliff:g> අගයන ලදි.\nමෙම වැඩසටහන නැරඹීමට දකුණ ඔබා ඔබගේ PIN එක ඇතුළු කරන්න."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"මෙම නාලිකාව නැරඹීම සඳහා, පෙරනිමි සජීවි TV යෙදුම භාවිතා කරන්න."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"මෙම වැඩසටහන නැරඹීමට, පෙරනිමි සජීවි TV යෙදුම භාවිතා කරන්න."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"මෙම වැඩසටහන <xliff:g id="RATING">%1$s</xliff:g> ලෙස වර්ගීකරණය කර ඇත.\nමෙම වැඩසටහන නැරඹීමට, පෙරනිමි සජීවි TV යෙදුම භාවිතා කරන්න."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"වැඩසටහන අවහිර කරන ලදි"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"මෙම වැඩසටහන <xliff:g id="RATING">%1$s</xliff:g> ලෙස අගයා ඇත"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ශ්‍රව්‍ය පමණයි"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"දුර්වල සංඥාව"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"අන්තර්ජාල සබැඳුමක් නැත"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="one">වෙනත් නාලිකා පටිගත වෙමින් ඇති නිසා මෙම නාලිකාව <xliff:g id="END_TIME_1">%1$s</xliff:g> වනතෙක් ධාවනය කළ නොහැකිය. \n\nපටිගත කිරීමේ කාල සටහන සීරුමාරු කිරීමට දකුණ ඔබන්න.</item>
- <item quantity="other">වෙනත් නාලිකා පටිගත වෙමින් ඇති නිසා මෙම නාලිකාව <xliff:g id="END_TIME_1">%1$s</xliff:g> වනතෙක් ධාවනය කළ නොහැකිය. \n\nපටිගත කිරීමේ කාල සටහන සීරුමාරු කිරීමට දකුණ ඔබන්න.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"මාතෘකාවක් නොමැත"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"නාලිකාව අවහිර කරන ලදි"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"නව"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"මූලාශ්‍ර"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="one">නාලිකා %1$d</item>
- <item quantity="other">නාලිකා %1$d</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"ලබා ගත හැකි නාලිකා නැත"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"නව"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"සකසා නැත"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"තවත් මූලාශ්‍ර ලබා ගන්න"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"සජීව නාලිකා පිරිනමන යෙදුම් බ්‍රවුස් කරන්න"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"නව නාලිකා මූලාශ්‍ර ලබා ගත හැකිය"</string>
- <string name="new_sources_description" msgid="749649005588426813">"නව නාලිකා මූලාශ්‍රවලට පිරිනැමීමට නාලිකා ඇත.\nඒවා දැන් පිහිටුවන්න, නැතහොත් මෙය පසුව නාලිකා මූලාශ්‍ර සැකසීම තුළ සිදු කරන්න."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"දැන් පිහිටුවන්න"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"හරි, තේරුණා"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"TV මෙනුවට පිවිසීමට "<b>"SELECT ඔබන්න"</b>"."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"TV ආදානය සොයාගැනීමට නොහැකි විය"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"TV ආදානය සොයාගත නොහැක"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP සහාය දක්වන්නේ නැත"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP සමඟ පෙන්වූ විට අදානයක් එහි නොතිබේ"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"සුසරක වර්ගය ගැලපෙන්නේ නැත; කරුණාකර සුසර කරන වර්ගයේ TV අදානය සඳහා සජීවී නාලිකා යෙදුම දමන්න."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"සුසර කිරීම අසාර්ථක වුණි"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"මෙම ක්‍රියාව හැසිරවීමට යෙදුමක් සොයාගත්තේ නැත"</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"සියලුම මූල නාලිකා සඟවන ලදි.\nනැරඹීමට අඩුම තරමේ එක නාලිකාවක් වත් තෝරන්න."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"වීඩියෝව බලාපොරොත්තු නොවූ ලෙස නොතිබේ"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"සම්බන්ධිත උපාංගය සඳහා BACK යතුර. පිටවීමට Home බොත්තම ඔබන්න."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"සජීවී නාලිකාවලට TV ලැයිස්තුගත කිරීම් කියවීමට අවසරය අවශ්‍යයි."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"ඔබගේ මූලාශ්‍ර පිහිටුවන්න"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"සජීවී නාලිකා සම්ප්‍රදායික TV නාලිකාවල අත්දැකීම යෙදුම්වලින් සපයන ප්‍රවාහ කිරීමේ නාලිකා සමග ඒකාබද්ධ කරයි. \n\nදැනටමත් ස්ථාපනය කර ඇති නාලිකා මූලාශ්‍ර පිහිටුවීමෙන් ආරම්භ කරන්න. නැතහොත් සජීවී නාලිකා පිරිනමන තවත් යෙදුම් සඳහා Google Play Store බ්‍රවුස් කරන්න."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"පටිගත කිරීම් සහ කාලසටහන්"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"මිනිත්තු 10"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"මිනිත්තු 30"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"පැය 1"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"පැය 3"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"මෑත"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"නියමිත"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"මාලා"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"වෙනත්"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"නාලිකාව පටිගත කළ නොහැකිය."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"වැඩසටහන පටිගත කළ නොහැකිය."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> පටිගත කිරීමට කාල සටහන්ගත කර ඇත"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> දැන් සිට <xliff:g id="ENDTIME">%2$s</xliff:g> දක්වා පටිගත කරමින්"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"සම්පූර්ණ කාල සටහන"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="one">ඊළඟ දින %1$d</item>
- <item quantity="other">ඊළඟ දින %1$d</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="one">මිනිත්තු %1$d</item>
- <item quantity="other">මිනිත්තු %1$d</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="one">නව පටිගත කිරීම් %1$d</item>
- <item quantity="other">නව පටිගත කිරීම් %1$d</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="one">පටිගත කිරීම් %1$d</item>
- <item quantity="other">පටිගත කිරීම් %1$d</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="one">පටිගත කිරීම් %1$dක් කාලසටහන්ගත කර ඇත</item>
- <item quantity="other">පටිගත කිරීම් %1$dක් කාලසටහන්ගත කර ඇත</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"ඔරලෝසුව"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"මුල සිට ධාවනය කරන්න"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"ධාවනය නැවත පටන් ගැනීම"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"මකන්න"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"පටිගත කිරීම් මකන්න"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"නැවත පටන්ගන්න"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"වෙළුම <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"කාල සටහන බලන්න"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"තව කියවන්න"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"පටිගත කිරීම් මකන්න"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"ඔබ මැකීමට කැමති කථාංග තෝරන්න. වරක් මැකූ පසු ඒවා ප්‍රතිසාධනය කළ නොහැකිය."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"මැකීමට පටිගත කිරීම් නැත."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"නැරඹූ කථාංග තෝරන්න"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"සියලු කථාංග තෝරන්න"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"සියලු කථාංග තේරීම ඉවත් කරන්න"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"මිනිත්තු <xliff:g id="DURATION">%2$d</xliff:g>කින් <xliff:g id="WATCHED">%1$d</xliff:g>ක් නරඹන ලදී"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"තත්පර <xliff:g id="DURATION">%2$d</xliff:g>කින් <xliff:g id="WATCHED">%1$d</xliff:g>ක් නරඹන ලදී"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"කිසිදා නරඹා නැත"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="one">කථාංග %2$dකින් %1$dක් මකා ඇත</item>
- <item quantity="other">කථාංග %2$dකින් %1$dක් මකා ඇත</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ප්‍රමුඛතාව"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"වැඩිම"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"අඩුම"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"නැත. <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"නාලිකා"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ඕනෑම"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"ප්‍රමුඛතාව තේරීම"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"එකම අවස්ථාවේදී පටිගත කිරීමට ප්‍රමාණයට වඩා වැඩි වැඩසටහන් ගණන් ඇති විට, වඩා ඉහළ ප්‍රමුඛතා සහිත ඒවා පමණක් පටිගත කරනු ඇත."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"සුරකින්න"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"එක්-වරක පටිගත කිරීම්වලට වැඩිම ප්‍රමුඛතාව ඇත"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"අවලංගු කර."</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"අවලංගු කරන්න"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"අමතක කරන්න"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"නතර කරන්න"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"පටිගත කිරීමේ කාල සටහන බලන්න"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"මෙම තනි වැඩසටහන"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"දැන් - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"මුළු මාලාව…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"කෙසේ වෙතත් කාල සටහන්ගත කරන්න"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"ඒ වෙනුවට මෙය පටිගත කරන්න"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"මෙම පටිගත කිරීම අවලංගු කරන්න"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"දැන් නරඹන්න"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"පටිගත කළ හැකි"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"පටිගත කිරීම කාල සටහන්ගතයි"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"පටිගත කිරීමේ ගැටුම"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"පටිගත කරමින්"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"පටිගත කිරීම අසාර්ථක විය"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"පටිගත කිරීමේ කාලසටහන් සෑදීමට වැඩසටහන් කියවමින්"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"කියවීමේ වැඩසටහන්"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR සඳහා වැඩිපුර ගබඩාව අවශ්‍යයි"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"ඔබට DVR සමගින් වැඩසටහන් පටිගත කිරීමට හැකි වනු ඇත. කෙසේ වෙතත් දැන් DVR ක්‍රියා කිරීම සඳහා ඔබේ උපාංගයේ ප්‍රමාණවත් තරම් ගබඩාව නැත. කරුණාකර <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB හෝ ඊට වඩා විශාල බාහිර ධාවකයක් සම්බන්ධ කර එය උපාංග ගබඩාව ලෙස ෆෝමැට් කිරීමට පහත පියවර අනුගමනය කරන්න."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"අස්ථානගත ගබඩාව"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR මගින් භාවිත කළ ගබඩා සමහරක් අස්ථානගතය. කරුණාකර DVR නැවත-සබල කිරීමට ඔබ පෙරදී භාවිත කළ බාහිර drive සම්බන්ධ කරන්න. විකල්පව, එය තවදුරටත් ලබා ගත නොහැකි නම් ඔබට ගබඩාව අමතක කිරීමට තේරිය හැකිය."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"ගබඩාව අමතකද?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"ඔබේ පටිගත කළ සියලු අන්තර්ගත සහ කාල සටහන් අහිමි වනු ඇත."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"පටිගත කිරීම නවත්වන්නද?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"පටිගත කළ අන්තර්ගතය සුරැකෙනු ඇත."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"පටිගත කිරීම කාල සටහන්ගත කර ඇති නමුත් ගැටුම් ඇත"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"පටිගත කිරීම ආරම්භ කර ඇති නමුත් ගැටුම් ඇත"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> පටිගත කරනු ඇත."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> වාර්තා කරමින් පවතී."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> හි සමහර කොටස් පටිගත නොකරනු ඇත."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> සහ <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> හි සමහර කොටස් පටිගත නොකරනු ඇත."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> හි සමහර කොටස් සහ තවත් එක් කාලසටහනක් පටිගත නොකරනු ඇත."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> හි සමහර කොටස් සහ තව කාල සටහන් %3$dක් පටිගත නොකරනු ඇත.</item>
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> හි සමහර කොටස් සහ තව කාල සටහන් %3$dක් පටිගත නොකරනු ඇත.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"ඔබ පටිගත කිරීමට කැමති කුමක්ද?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"ඔබ කොපමණ කාලයක් පටිගත කිරීමට කැමතිද?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"දැනටමත් කාලසටහන්ගත කර ඇත"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"එම වැඩසටහනම <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>ට පටිගත කිරීමට කාල සටහන්ගත කර ඇත."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"දැනටමත් පටිගත කර ඇත"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"මෙම වැඩසටහන දැනටමත් පටිගත කර ඇත. එය DVR පුස්තකාලය තුළදී ලබා ගත හැකිය."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"පටිගත කළ වැඩසටහන හමු නොවීය."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"අදාළ පටිගත කිරීම්"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(වැඩසටහන් විස්තරය නැත)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="one">පටිගත කිරීම් %1$d</item>
- <item quantity="other">පටිගත කිරීම් %1$d</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"පටිගත කිරීමේ කාල සටහනින් <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ඉවත් කරන ලදී"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"සුසරක ගැටුම් නිසා අර්ධ වශයෙන් පටිගත කරනු ඇත."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"සුසරක ගැටුම් නිසා පටිගත නොකරනු ඇත."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"තවම කාල සටහනෙහි පටිගත කිරීම් නැත.\nඔබට වැඩසටහන් මාර්ගෝපදේශය වෙතින් පටිගත කිරීම කාලසටහන්ගත කළ හැකිය."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="one">පටිගත කිරීමේ ගැටුම් %1$d</item>
- <item quantity="other">පටිගත කිරීමේ ගැටුම් %1$d</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"මාලා සැකසීම්"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"මාලා පටිගත කිරීම අරඹන්න"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"මාලා පටිගත කිරීම නවත්වන්න"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"මාලා පටිගත කිරීම නවත්වන්නද?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"පටිගත කළ කථාංග DVR පුස්තකාලය තුළ ලබා ගත හැකිව පවතිනු ඇත."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"නවත්වන්න"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ලබා ගත හැකි කථාංග නැත.\nඒවා ලබා ගත හැකි වූ විට පටිගත කරනු ඇත."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="one">(මිනිත්තු %1$d)</item>
- <item quantity="other">(මිනිත්තු %1$d)</item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"අද"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"හෙට"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"ඊයේ"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"අද <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"හෙට <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"ලකුණු"</string>
-</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 78d94c7f..1d747d7a 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -20,54 +20,35 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Ovládanie prehrávania"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Nedávne kanály"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"Možnosti TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Možnosti PIP"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanály"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"Možnosti televízie"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Pre tento kanál nie sú k dispozícii ovládacie prvky prehrávania"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Prehrať alebo pozastaviť"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Pretočiť dopredu"</string>
<string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Pretočiť späť"</string>
<string name="play_controls_description_skip_next" msgid="1603587562124694592">"Ďalej"</string>
<string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Naspäť"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Program. sprievodca"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Dostupné sú nové kanály"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Televízny program"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Dostupné nové kanály"</string>
<string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Spustiť aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="options_item_closed_caption" msgid="5945274655046367170">"Skryté titulky"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Režim zobrazenia"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Zapnuté"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Vypnuté"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"Obraz v obraze"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Viackanálový zvuk"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Ďalšie kanály"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Nastavenia"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Zdroj"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Zameniť"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Zapnuté"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Vypnuté"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Zvuk"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Hlavné"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Okno PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Rozloženie"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Vpravo dole"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Vpravo hore"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Vľavo hore"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Vľavo dole"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Vedľa seba"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Rozmery"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Veľké"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Malé"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Zdroj vstupu"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (anténa/kábel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Žiadne informácie o programe"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Žiadne informácie"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Zablokovaný kanál"</string>
- <string name="default_language" msgid="4122326459624337928">"Neznámy jazyk"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Neznámy jazyk"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Skryté titulky: %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Skryté titulky"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Vypnuté"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Prispôsobiť formát"</string>
<string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Nastavenie systémových predvolieb pre skryté titulky"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"Režim zobrazenia"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multi-audio"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Viackanálový zvuk"</string>
<string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
<string name="multi_audio_channel_stereo" msgid="3758995659214256587">"stereo"</string>
<string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"Priestorový zvuk 5.1"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Zoskupiť podľa"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Tento program je zablokovaný."</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Tento program nemá hodnotenie"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Hodnotenie tohto programu je <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Vstup nepodporuje automatické vyhľadávanie"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Nepodarilo sa automaticky prehľadať vstup <xliff:g id="TV_INPUT">%s</xliff:g>"</string>
@@ -94,7 +76,6 @@
<item quantity="one">%1$d pridaný kanál</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Žiadne pridané kanály"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Rodič. kontrola"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Zapnuté"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Vypnuté"</string>
@@ -110,6 +91,8 @@
<string name="other_countries" msgid="8342216398676184749">"Iné krajiny"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Žiadny"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Žiadny"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Nehodnotené"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blokovať nehodnotené programy"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Žiadne"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Silné obmedzenia"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Stredné obmedzenia"</string>
@@ -126,6 +109,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Zadanie kódu PIN na pozeranie tohto kanála"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Zadanie kódu PIN na pozeranie tohto programu"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Tento program má hodnotenie <xliff:g id="RATING">%1$s</xliff:g>. Ak ho chcete pozerať, zadajte kód PIN."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Tento program nemá hodnotenie. Ak ho chcete pozerať, zadajte kód PIN."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Zadanie kódu PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Ak chcete nastaviť rodičovskú kontrolu, vytvorte kód PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Zadajte nový kód PIN"</string>
@@ -139,22 +123,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Kód PIN bol zadaný chybne. Skúste to znova."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Kód PIN nesúhlasí. Skúste to znova."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Zadajte svoje PSČ."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Aplikácia Televízia online vám na základe poštového smerovacieho čísla poskytne kompletný program televíznych kanálov."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Zadajte svoje PSČ"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Neplatné PSČ"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Nastavenia"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Prispôsobiť zoznam kanálov"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Vybrať kanály pre televízny program"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Vyberte kanály pre televízny program"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Zdroje kanálov"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"K dispozícii sú nové kanály"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Rodičovská kontrola"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Posunutie času"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Zaznamenávajte pozerané programy vysielané naživo, aby ste ich mohli pozastaviť alebo pretočiť späť.\nUpozornenie: Intenzívnym využívaním interného úložiska môže dôjsť ku skráteniu jeho životnosti."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licencie open source"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Licencie open source"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Odoslať spätnú väzbu"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Verzia"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Ak chcete sledovať tento kanál, stlačte šípku vpravo a zadajte kód PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Ak chcete sledovať tento program, stlačte šípku doprava a zadajte kód PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Tento program nemá hodnotenie.\nAk ho chcete pozerať, stlačte šípku doprava a zadajte PIN."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Hodnotenie tohto programu je <xliff:g id="RATING">%1$s</xliff:g>.\nAk chcete sledovať tento program, stlačte šípku doprava a zadajte kód PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Ak chcete sledovať tento kanál, použite predvolenú aplikáciu Live TV."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Ak chcete sledovať tento program, použite predvolenú aplikáciu Live TV."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Tento program nemá hodnotenie.\nAk ho chcete pozerať, použite predvolenú aplikáciu Live TV."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Tento program má hodnotenie <xliff:g id="RATING">%1$s</xliff:g>.\nAk ho chcete sledovať, použite predvolenú aplikáciu Live TV."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Program je zablokovaný"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Tento program nemá hodnotenie"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Hodnotenie tohto programu je <xliff:g id="RATING">%1$s</xliff:g>."</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Iba zvuk"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Slabý signál"</string>
@@ -179,7 +172,7 @@
<string name="setup_input_new" msgid="3337725672277046798">"Nové"</string>
<string name="setup_input_setup_now" msgid="1772000402336958967">"Nenastavené"</string>
<string name="setup_store_action_title" msgid="4083402039720973414">"Získať ďalšie zdroje"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Prehliadajte aplikácie, ktoré ponúkajú televíziu online"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Aplikácie, ponúkajúce televíziu online"</string>
<string name="new_sources_title" msgid="3878933676500061895">"K dispozícii sú nové zdroje kanálov"</string>
<string name="new_sources_description" msgid="749649005588426813">"K dispozícii sú nové zdroje s ďalšími kanálmi.\nMôžete ich nastaviť hneď alebo neskôr v nastavení zdrojov kanálov."</string>
<string name="new_sources_action_setup" msgid="177693761664016811">"Nastaviť"</string>
@@ -189,8 +182,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Stlačením tlačidla VYBRAŤ"</b>" prejdete do TV ponuky."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Nenašiel sa žiadny TV vstup"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"TV vstup sa nenašiel"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Funkcia Obraz v obraze (PIP) nie je podporovaná"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Neexistuje vstup, ktorý by mohla funkcia PIP zobraziť"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Typ tunera nie je vhodný. Pre TV vstup typu tunera spustite aplikáciu Aktívne kanály."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Ladenie zlyhalo"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Aplikácia potrebná na spracovanie tejto akcie sa nenašla."</string>
@@ -199,7 +190,7 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Kláves Späť je určený pre pripojené zariadenie. Aplikáciu ukončite stlačením tlačidla Domov."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Aktívne kanály potrebujú povolenie na čítanie televíznych programov."</string>
<string name="setup_sources_text" msgid="4988039637873759839">"Nastavte si zdroje"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Televízia online spája zážitok z tradičných televíznych kanálov so streamovaním kanálov z aplikácií. \n\nZačnite nastavením zdrojov kanálov, ktoré už máte nainštalované. Prípadne si prehliadnite Obchod Google Play a získajte ďalšie aplikácie, ktoré poskytujú televíziu online."</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Televízia online spája tradičné televízne kanály so streamovanými kanálmi z aplikácií. \n\nAk chcete začať, nastavte si zdroje kanálov, ktoré už máte nainštalované. Prípadne si môžete v Obchode Google Play vyhľadať ďalšie aplikácie, ktoré ponúkajú televíziu online."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Nahrávanie a plány"</string>
<string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minút"</string>
<string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minút"</string>
@@ -244,6 +235,8 @@
<item quantity="other">%1$d plánovaných záznamov</item>
<item quantity="one">%1$d plánovaný záznam</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Zrušiť zaznamenávanie"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Zastaviť zaznamenávanie"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Prehrať"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Prehrať od začiatku"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Obnoviť prehrávanie"</string>
@@ -278,9 +271,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Keď naplánujete nahrávanie príliš veľa programov súčasne, zaznamenajú sa iba programy s najvyššími prioritami."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Uložiť"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Jednorazové záznamenávania majú najvyššiu prioritu"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Zrušiť"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Zrušiť"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Odstrániť"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Zastaviť"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Zobraziť rozvrh nahrávania"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Iba tento program"</string>
@@ -290,25 +280,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Zaznamenať radšej tento program"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Zrušiť tento záznam"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Pozrieť"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Odstrániť nahratý obsah..."</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Je možné nahrať"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Nahrávanie je naplánované"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Konflikt nahrávania"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Nahráva sa"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Nahrávanie zlyhalo"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Čítajú sa programy s cieľom vytvoriť plány zaznamenávania"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Načítavajú sa programy"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Načítavajú sa programy"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Zobraziť nedávne nahrávky"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Záznam programu <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nie je úplný."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Záznamy programov <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> a <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> nie sú úplné."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Záznamy programov <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> a <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> nie sú úplné."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Zaznamenávanie programu <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nebolo dokončené z dôvodu nedostatku miesta v úložisku."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Zaznamenávanie programov <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> a <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> nebolo dokončené z dôvodu nedostatku miesta v úložisku."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Zaznamenávanie programov <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> a <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> nebolo dokončené z dôvodu nedostatku miesta v úložisku."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR vyžaduje viac miesta v úložisku"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Budete môcť zaznamenávať programy pomocou zariadenia DVR. Teraz však v úložisku vášho zariadenia nie je dostatok miesta na fungovanie zariadenia DVR. Pripojte externý disk s minimálnou kapacitou <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB a podľa uvedených krokov ho naformátujte ako úložisko zariadenia."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Budete môcť zaznamenávať programy pomocou zariadenia DVR. Teraz však v úložisku vášho zariadenia nie je dostatok miesta na fungovanie zariadenia DVR. Pripojte externý disk s minimálnou kapacitou <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB a podľa uvedených krokov ho naformátujte ako úložisko zariadenia."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Nedostatok úložiska"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Tento program nebude nahratý z dôvodu nedostatku úložiska. Skúste odstrániť časť nahratého obsahu."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Chýba úložisko"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Určitá časť úložiska využitého zariadením DVR chýba. Pred opätovným povolením zariadenia DVR pripojte externý disk, ktorý ste predtým používali. Prípadne môžete úložisko odstrániť, ak už nie je ďalej k dispozícii."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Odstrániť úložisko?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Všetok váš zaznamenaný obsah a plány budú stratené."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Zastaviť nahrávanie?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Nahraný obsah sa uloží."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Zaznamenávanie relácie <xliff:g id="PROGRAMNAME">%1$s</xliff:g> bude zastavené, pretože koliduje s týmto programom. Zaznamenaný obsah sa uloží."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Nahrávanie je naplánované, ale obsahuje konflikty"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Záznam sa spustil, ale obsahuje konflikty"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Zaznamená sa program <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
@@ -328,17 +321,39 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Zaznamenanie rovnakého programu už bolo naplánované na <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Už je zaznamenané"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Tento program je už zaznamenaný. Nájdete ho v knižnici zariadenia DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Zaznamenávanie relácie bolo naplánované"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="few">Pre seriál <xliff:g id="SERIESNAME_3">%2$s</xliff:g> boli naplánované <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> záznamy.</item>
+ <item quantity="many">Pre seriál <xliff:g id="SERIESNAME_3">%2$s</xliff:g> bolo naplánovaného <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> záznamu.</item>
+ <item quantity="other">Pre seriál <xliff:g id="SERIESNAME_3">%2$s</xliff:g> bolo naplánovaných <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> záznamov.</item>
+ <item quantity="one">Pre seriál <xliff:g id="SERIESNAME_1">%2$s</xliff:g> bol naplánovaný <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> záznam.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="few">Pre seriál <xliff:g id="SERIESNAME_3">%2$s</xliff:g> boli naplánované <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> záznamy. Z dôvodu konfliktov sa nezaznamenajú niektoré epizódy (počet: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>).</item>
+ <item quantity="many">Pre seriál <xliff:g id="SERIESNAME_3">%2$s</xliff:g> bolo naplánovaného <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> záznamu. Z dôvodu konfliktov sa nezaznamenajú niektoré epizódy (počet: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>)</item>
+ <item quantity="other">Pre seriál <xliff:g id="SERIESNAME_3">%2$s</xliff:g> bolo naplánovaných <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> záznamov. Z dôvodu konfliktov sa nezaznamenajú niektoré epizódy (počet: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>)</item>
+ <item quantity="one">Pre seriál <xliff:g id="SERIESNAME_1">%2$s</xliff:g> bol naplánovaný <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> záznam. Z dôvodu konfliktov sa nezaznamená.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="few">Pre seriál <xliff:g id="SERIESNAME_4">%2$s</xliff:g> boli naplánované <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> záznamy. Z dôvodu konfliktov sa nezaznamenajú niektoré epizódy z tohto seriálu a ďalších seriálov (počet: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="many">Pre seriál <xliff:g id="SERIESNAME_4">%2$s</xliff:g> bolo naplánovaného <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> záznamu. Z dôvodu konfliktov sa nezaznamenajú niektoré epizódy z tohto seriálu a ďalších seriálov (počet: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="other">Pre seriál <xliff:g id="SERIESNAME_4">%2$s</xliff:g> bolo naplánovaných <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> záznamov. Z dôvodu konfliktov sa nezaznamenajú niektoré epizódy z tohto seriálu a ďalších seriálov (počet: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="one">Pre seriál <xliff:g id="SERIESNAME_1">%2$s</xliff:g> bol naplánovaný <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> záznam. Z dôvodu konfliktov sa nezaznamenajú niektoré epizódy z tohto seriálu a ďalších seriálov (počet: <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g>).</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="few">Pre seriál <xliff:g id="SERIESNAME_3">%2$s</xliff:g> boli naplánované <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> záznamy.Z dôvodu konfliktov nebude zaznamenaná 1 epizóda inej relácie.</item>
+ <item quantity="many">Pre seriál <xliff:g id="SERIESNAME_3">%2$s</xliff:g> bolo naplánovaného <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> záznamu.Z dôvodu konfliktov nebude zaznamenaná 1 epizóda inej relácie.</item>
+ <item quantity="other">Pre seriál <xliff:g id="SERIESNAME_3">%2$s</xliff:g> bolo naplánovaných <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> záznamov.Z dôvodu konfliktov nebude zaznamenaná 1 epizóda inej relácie.</item>
+ <item quantity="one">Pre seriál <xliff:g id="SERIESNAME_1">%2$s</xliff:g> bol naplánovaný <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> záznam.Z dôvodu konfliktov nebude zaznamenaná 1 epizóda inej relácie.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="few">Pre seriál <xliff:g id="SERIESNAME_4">%2$s</xliff:g> boli naplánované <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> záznamy. Z dôvodu konfliktov sa nezaznamenajú epizódy z iného seriálu (počet: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="many">Pre seriál <xliff:g id="SERIESNAME_4">%2$s</xliff:g> bolo naplánovaného <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> záznamu. Z dôvodu konfliktov sa nezaznamenajú epizódy z iného seriálu (počet: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="other">Pre seriál <xliff:g id="SERIESNAME_4">%2$s</xliff:g> bolo naplánovaných <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> záznamov. Z dôvodu konfliktov sa nezaznamenajú epizódy z iného seriálu (počet: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>).</item>
+ <item quantity="one">Pre seriál <xliff:g id="SERIESNAME_1">%2$s</xliff:g> bol naplánovaný <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> záznam. Z dôvodu konfliktov sa nezaznamenajú epizódy z iného seriálu (počet: <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g>).</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Zaznamenaný program sa nenašiel."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Súvisiace nahrávky"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Žiadny popis programu)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="few">%1$d záznamy</item>
<item quantity="many">%1$d záznamu</item>
@@ -349,7 +364,7 @@
<string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"Program <xliff:g id="PROGRAMNAME">%1$s</xliff:g> bol odstránený z rozvrhu nahrávania"</string>
<string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Z dôvodu konfliktu tunerov bude nahratá iba časť obsahu."</string>
<string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Z dôvodu konfliktu tunerov obsah nebude nahratý."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Nemáte naplánované žiadne záznamy.\nZaznamenávanie môžete naplánovať z televízneho programu."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Nemáte naplánované žiadne záznamy.\nZáznam môžete naplánovať z televízneho programu."</string>
<plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
<item quantity="few">%1$d konflikty nahrávania</item>
<item quantity="many">%1$d konfliktu nahrávania</item>
@@ -362,6 +377,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Zastaviť nahrávanie série?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Nahrané epizódy zostanú k dispozícii v knižnici DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Zastaviť"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Momentálne nie sú vysielané žiadne epizódy."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Nie sú k dispozícii žiadne epizódy.\nZaznamenajú sa, keď budú dostupné."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="few">(%1$d minúty)</item>
@@ -375,4 +391,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Dnes: <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Zajtra: <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Skóre"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Zaznamenané programy"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 6e79cacc..7fac034b 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Kontrolniki predvajanja"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Nedavni kanali"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanali"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Možnosti za TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Možnosti za PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Kontrolniki za predvajanje niso na voljo za ta kanal"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Predvajanje ali zaustavitev"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Previjanje naprej"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Podnapisi"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Način prikaza"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Vklopljeno"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Izklopljeno"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multizvok"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Več kanalov"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Nastavitve"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Vir"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Zamenjaj"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Vklopljeno"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Izklopljeno"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Zvok"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Glavno"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Okno PIP-a"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Postavitev"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Spodaj desno"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Zgoraj desno"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Zgoraj levo"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Spodaj levo"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Vzporedno"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Velikost"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Veliko"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Majhno"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Vir vhoda"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antena/kabelska)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Ni informacij o programu"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Ni informacij"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blokiran kanal"</string>
- <string name="default_language" msgid="4122326459624337928">"Neznan jezik"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Neznan jezik"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Podnapisi %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Podnapisi"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Izklopljeno"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Oblikovanje po meri"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Razvrsti po:"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Ta program je blokiran"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ta oddaja nima kategorije vsebine"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Ta program ima kategorijo vsebine <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Vhod ne podpira samodejnega iskanja"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Samodejnega iskanja za »<xliff:g id="TV_INPUT">%s</xliff:g>« ni mogoče začeti"</string>
@@ -94,7 +76,6 @@
<item quantity="other">%1$d dodanih kanalov</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Ni dodanih kanalov"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Sprejemnik"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Starševski nadzor"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Vklopljeno"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Izklopljeno"</string>
@@ -110,6 +91,8 @@
<string name="other_countries" msgid="8342216398676184749">"Druge države"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Brez"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Brez"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Brez kategorije vsebine"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blokiranje oddaj brez kat. vs."</string>
<string name="option_rating_none" msgid="5204552587760414879">"Brez"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Visoke omejitve"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Srednje omejitve"</string>
@@ -126,6 +109,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Vnesite kodo PIN, če želite gledati ta kanal"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Vnesite kodo PIN, če želite gledati to oddajo"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Ta oddaja ima kategorijo vsebine <xliff:g id="RATING">%1$s</xliff:g>. Vnesite kodo PIN, če si želite ogledati to oddajo."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Ta oddaja nima kategorije vsebine. Vnesite kodo PIN, če jo želite gledati."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Vnos kode PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Če želite nastaviti starševski nadzor, ustvarite kodo PIN."</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Vnesite novo kodo PIN"</string>
@@ -139,22 +123,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Koda PIN je bila napačna. Poskusite znova."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Poskusite znova. Koda PIN se ne ujema."</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Vnos poštne številke."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Aplikacija Televizija v živo uporablja poštno številko za posredovanje popolnega programskega vodnika za televizijske kanale."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Vnesite poštno številko"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Neveljavna poštna številka"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Nastavitve"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Prilagajanje seznama kanalov"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Izbira kanalov za programski vodnik"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Viri kanalov"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Na voljo so novi kanali"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Starševski nadzor"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Časovni zamik"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Snemanje med gledanjem, da lahko oddaje v živo zaustavite ali previjete nazaj.\nOpozorilo: zaradi intenzivne rabe shrambe se lahko s tem skrajša življenjska doba notranje shrambe."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Odprtokodne licence"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Odprtokodne licence"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Pošljite povratne informacije"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Različica"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Če želite gledati ta kanal, pritisnite v desno in vnesite kodo PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Če želite gledati ta program, pritisnite v desno in vnesite kodo PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Ta oddaja nima kategorije vsebine.\nČe jo želite gledati, pritisnite desno smerno tipko in vnesite kodo PIN."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Ta program ima kategorijo vsebine <xliff:g id="RATING">%1$s</xliff:g>.\nČe ga želite gledati, pritisnite v desno in vnesite kodo PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Če želite gledati ta kanal, uporabite privzeto aplikacijo za TV v živo."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Če želite gledati to oddajo, uporabite privzeto aplikacijo za TV v živo."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Ta oddaja nima kategorije vsebine.\nČe jo želite gledati, uporabite aplikacijo za TV v živo."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Ta oddaja ima kategorijo vsebine <xliff:g id="RATING">%1$s</xliff:g>.\nČe jo želite gledati, uporabite privzeto aplikacijo za TV v živo."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Oddaja je blokirana"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ta oddaja nima kategorije vsebine"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Ta program ima kategorijo vsebine <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Samo zvok"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Šibek signal"</string>
@@ -189,8 +182,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Pritisnite »IZBIRA«"</b>", če želite dostopati do menija TV-ja."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Ni TV-vhodov"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Ni mogoče najti TV-vhoda"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Slika v sliki ni podprta"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Ni vhoda, ki bi omogočal prikaz s sliko v sliki (PIP)"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Vrsta sprejemnika ni ustrezna. Zaženite aplikacijo Kanali v živo za uporabo TV-vhoda, ki deluje kot sprejemnik."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Nastavljanje kanalov ni uspelo"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Za to dejanje ni bilo mogoče najti nobene aplikacije."</string>
@@ -201,10 +192,10 @@
<string name="setup_sources_text" msgid="4988039637873759839">"Nastavitev virov"</string>
<string name="setup_sources_description" msgid="5695518946225445202">"Kanali v živo združujejo izkušnjo običajnih TV-kanalov in pretočno predvajanje kanalov, ki ga omogočajo aplikacije. \n\nZačnite tako, da nastavite vire kanalov, ki so že nameščeni. V Trgovini Google Play lahko tudi poiščete druge aplikacije, ki omogočajo kanale v živo."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Posnetki in razporedi"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 min"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 min"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minut"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minut"</string>
<string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 h"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 h"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 ure"</string>
<string name="dvr_main_recent" msgid="2553805424822806495">"Nedavno"</string>
<string name="dvr_main_scheduled" msgid="7837260963086408492">"Načrtovano"</string>
<string name="dvr_main_series" msgid="8278256687595691676">"Nanizanka"</string>
@@ -244,6 +235,8 @@
<item quantity="few">%1$d načrtovani posnetki</item>
<item quantity="other">%1$d načrtovan. posnetkov</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Prekliči snemanje"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Ustavi snemanje"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Gledanje"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Predvajaj od začetka"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Nadaljuj predvajanje"</string>
@@ -278,9 +271,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Če je nastavljeno snemanje preveč oddaj ob istem času, bodo posnete samo oddaje z višjo prednostjo."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Shrani"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Enkratna snemanja imajo najvišjo prednost"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Prekliči"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Prekliči"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Pozabi"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Ustavi"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Ogled razporeda snemanja"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Samo to oddajo"</string>
@@ -290,25 +280,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Snemanje tega namesto drugega"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Preklic tega snemanja"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Ogled"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Izbris posnetkov …"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Omogoča snemanje"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Čas snemanja nastavljen"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Posnetek v sporu"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Snemanje"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Snemanje ni uspelo"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Branje oddaj za ustvarjanje razporedov snemanja"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Branje oddaj"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Branje oddaj"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Ogled nedavnih posnetkov"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Posnetek vsebine <xliff:g id="PROGRAMNAME">%1$s</xliff:g> je nepopoln."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Posnetka vsebin <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> in <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> sta nepopolna."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Posnetki vsebin <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> in <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> so nepopolni."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Snemanje vsebine <xliff:g id="PROGRAMNAME">%1$s</xliff:g> se ni dokončalo zaradi pomanjkanja prostora za shranjevanje."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Snemanje vsebin <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> in <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> se ni dokončalo zaradi pomanjkanja prostora za shranjevanje."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Snemanje vsebin <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> in <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> se ni dokončalo zaradi pomanjkanja prostora za shranjevanje."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Digitalni videorekorder potrebuje več shrambe"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Z digitalnim videorekorderjem boste lahko snemali oddaje, vendar v napravi ni dovolj shrambe, potrebne za njegovo delovanje. Priključite zunanji pogon velikosti <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB ali več in upoštevajte navodila, da ga formatirate kot shrambo naprave."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Z digitalnim videorekorderjem boste lahko snemali oddaje, vendar v napravi ni dovolj shrambe, potrebne za njegovo delovanje. Priključite zunanji pogon velikosti <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB ali več in upoštevajte navodila, da ga formatirate kot shrambo naprave."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Ni dovolj prostora za shranjevanje"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Ta program ne bo posnet, ker ni dovolj prostora za shranjevanje. Poskusite izbrisati nekatere obstoječe posnetke."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Manjkajoča shramba"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Del shrambe, ki jo uporablja digitalni videorekorder, manjka. Povežite zunanji pogon, ki ste ga že uporabljali, če želite znova omogočiti digitalni videorekorder. Če shramba ni več na voljo, jo lahko tudi pozabite."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Želite pozabiti shrambo?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Posneta vsebina in razporedi bodo izgubljeni."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Želite ustaviti snemanje?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Posneta vsebina bo shranjena."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Snemanje vsebine <xliff:g id="PROGRAMNAME">%1$s</xliff:g> bo ustavljeno, ker je v sporu s tem programom. Posneta vsebina bo shranjena."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Snemanje je nastavljeno, ampak obstajajo spori"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Snemanje se je začelo, vendar so spori"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Oddaja <xliff:g id="PROGRAMNAME">%1$s</xliff:g> bo posneta."</string>
@@ -328,17 +321,39 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Snemanje iste oddaje je že nastavljeno za ob <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Že posneto"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Ta oddaja je že posneta. Na voljo je v knjižnici digitalnega videorekorderja."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Snemanje serije je načrtovano"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetek je načrtovan za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="two"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetka sta načrtovana za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetki so načrtovani za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetkov je načrtovanih za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetek je načrtovan za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Zaradi sporov jih ne bo posnetih toliko: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>.</item>
+ <item quantity="two"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetka sta načrtovana za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Zaradi sporov jih ne bo posnetih toliko: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetki so načrtovani za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Zaradi sporov jih ne bo posnetih toliko: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetkov je načrtovanih za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Zaradi sporov jih ne bo posnetih toliko: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> posnetek je načrtovan za serijo <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Zaradi sporov ne bo posnetih toliko epizod te serije in drugih serij: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="two"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> posnetka sta načrtovana za serijo <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Zaradi sporov ne bo posnetih toliko epizod te serije in drugih serij: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> posnetki so načrtovani za serijo <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Zaradi sporov ne bo posnetih toliko epizod te serije in drugih serij: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> posnetkov je načrtovanih za serijo <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Zaradi sporov ne bo posnetih toliko epizod te serije in drugih serij: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetek je načrtovan za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Zaradi sporov ne bo posneta 1 epizoda druge serije.</item>
+ <item quantity="two"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetka sta načrtovana za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Zaradi sporov ne bo posneta 1 epizoda druge serije.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetki so načrtovani za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Zaradi sporov ne bo posneta 1 epizoda druge serije.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> posnetkov je načrtovanih za serijo <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Zaradi sporov ne bo posneta 1 epizoda druge serije.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> posnetek je načrtovan za serijo <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Zaradi sporov ne bo posnetih toliko epizod drugih serij: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="two"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> posnetka sta načrtovana za serijo <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Zaradi sporov ne bo posnetih toliko epizod drugih serij: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> posnetki so načrtovani za serijo <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Zaradi sporov ne bo posnetih toliko epizod drugih serij: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> posnetkov je načrtovanih za serijo <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Zaradi sporov ne bo posnetih toliko epizod drugih serij: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Posnetega programa ni bilo mogoče najti."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Sorodni posnetki"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(ni opisa programa)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d posnetek</item>
<item quantity="two">%1$d posnetka</item>
@@ -362,6 +377,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Ustavitev snemanja serije?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Posnete epizode bodo na voljo v knjižnici digitalnega videorekorderja."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Ustavi"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Trenutno se ne predvaja nobena epizoda."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Na voljo ni nobena epizoda.\nPosnete bodo, ko bodo na voljo."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d minuta)</item>
@@ -375,4 +391,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Danes: <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Jutri: <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Ocena"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Posneti programi"</string>
</resources>
diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq-rAL/strings.xml
new file mode 100644
index 00000000..17ea800b
--- /dev/null
+++ b/res/values-sq-rAL/strings.xml
@@ -0,0 +1,356 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Kontrollet e luajtjes"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanalet"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"Opsionet e televizorit"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Kontrollet e luajtjes nuk disponohen për këtë kanal"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Luaj ose ndërprit"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Përparo me shpejtësi"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Rikthe me shpejtësi"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Përpara"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Prapa"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Udhëzuesi i programeve"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Kanale të reja të disponueshme"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"Hap <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Titrat"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Modaliteti i ekranit"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Audioja në shumë gjuhë"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Merr më shumë kanale"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Cilësimet"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"Televizori (antena/kablloja)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Nuk ka informacione për programin"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Nuk ka informacione"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Kanal i bllokuar"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Gjuhë e panjohur"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Titrat %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Titrat"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"Joaktive"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Personalizo formatimin"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Cakto preferencat për të gjithë sistemin për titrat"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Modaliteti i ekranit"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Audioja në shumë gjuhë"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"stereo"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 rrethues"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 rrethues"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d kanale"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Personalizo listën e kanaleve"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Zgjidh grupin"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Anulo zgjedhjen e grupit"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Grupo sipas"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Burimi i kanalit"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Grupo sipas"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Ky program është bllokuar"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ky program është i pavlerësuar"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Ky program është vlerësuar si <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Hyrja nuk e mbështet skanimin automatik"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Skanimi automatik nuk mund të fillojë për \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Preferencat për të gjithë sistemin nuk mund të fillojnë për titrat."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d kanale u shtuan</item>
+ <item quantity="one">%1$d kanal u shtua</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Nuk u shtua asnjë kanal"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Kontrollet prindërore"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Aktive"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Joaktive"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Kanalet u bllokuan"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Bllokoji të gjitha"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Zhblloko të gjitha"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Kanalet e fshehura"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Kufizimet e programeve"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"Ndrysho kodin PIN"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Sistemet e vlerësimit"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Vlerësimet"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Shiko të gjitha sistemet e vlerësimit"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Vende te tjera"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Asnjë"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Asnjë"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"I pavlerësuar"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blloko programet e pavlerësuara"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Asnjë"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Kufizimet e larta"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"Kufizimet mesatare"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Kufizimet e ulëta"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"I personalizuar"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Përmbajtje e përshtatshme për fëmijët"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Përmbajtje e përshtatshme për fëmijë më të rritur"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Përmbajtje e përshtatshme për adoleshentë"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Kufizimet manuale"</string>
+ <string name="option_attribution" msgid="2967657807178951562">"Burimet për përshkrimet e vlerësimeve"</string>
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s dhe vlerësimet dytësore"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Vlerësimet dytësore"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Fut kodin PIN për të parë këtë kanal"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Fut kodin PIN për të shikuar këtë program"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Ky program është vlerësuar si <xliff:g id="RATING">%1$s</xliff:g>. Fut kodin PIN për të shikuar këtë program"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Ky program është i pavlerësuar. Fut kodin tënd PIN për të shikuar këtë program"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"Fut kodin PIN"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Për të caktuar kontrollet prindërore, krijo një kod PIN"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Fut kodin e ri PIN"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"Konfirmo kodin tënd PIN"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Fut kodin PIN aktual"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Ke futur kodin e gabuar PIN 5 herë.\nProvo përsëri pas <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> sekondash.</item>
+ <item quantity="one">Ke futur kodin e gabuar PIN 5 herë.\nProvo përsëri pas <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> sekonde.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"Ai kod PIN ishte i gabuar. Provo përsëri."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Provo përsëri, pasi kodi PIN nuk përputhet"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Fut kodin ZIP."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Aplikacioni \"Kanalet drejtpërdrejt\" do të përdorë kodin ZIP për të ofruar një udhëzues të plotë të programeve për kanalet e televizorit."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Fut kodin ZIP"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Kod ZIP i pavlefshëm"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Cilësimet"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Personalizo listën e kanaleve"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Zgjidh kanalet për udhëzuesin e programeve"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Burimet e kanaleve"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Kanale të reja të disponueshme"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Kontrollet prindërore"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Zhvendosja në kohë"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Regjistro ndërkohë që shikon që të mund t\'i vendosësh në pauzë ose t\'i rikthesh pas programet drejtpërdrejt.\nParalajmërim: Kjo mund të zvogëlojë jetëgjatësinë e hapësirës ruajtëse të brendshme nga përdorimi i lartë i hapësirës ruajtëse."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Licencat me burim të hapur"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Dërgo komentet"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versioni"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Për të shikuar këtë kanal, shtyp \"Djathtas\" për të futur kodin tënd PIN"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Për të shikuar këtë program, shtyp \"Djathtas\" për të futur kodin tënd PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Ky program është i pavlerësuar.\nPër të shikuar këtë program, shtyp \"Djathtas\" dhe fut kodin tënd PIN"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Ky program është vlerësuar si <xliff:g id="RATING">%1$s</xliff:g>.\nPër të shikuar këtë program, shtyp \"Djathtas\" dhe fut kodin tënd PIN."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Për të shikuar këtë kanal, përdor aplikacionin e parazgjedhur të televizionit drejtpërdrejt."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Për të shikuar këtë program, përdor aplikacionin e parazgjedhur të televizionit drejtpërdrejt."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Ky program është i pavlerësuar.\nPër të shikuar këtë program, përdor aplikacionin e parazgjedhur të televizionit drejtpërdrejt."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Ky program është vlerësuar si <xliff:g id="RATING">%1$s</xliff:g>.\nPër të shikuar këtë program, përdor aplikacionin e parazgjedhur të televizionit drejtpërdrejt."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programi është bllokuar"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ky program është i pavlerësuar"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Ky program është vlerësuar si <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Vetëm audio"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Sinjal i dobët"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Nuk ka lidhje interneti"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">Ky kanal nuk mund të luhet deri në <xliff:g id="END_TIME_1">%1$s</xliff:g> pasi po regjistrohen kanale të tjera. \n\nShtyp \"Djathtas\" për të rregulluar planifikimin e regjistrimit.</item>
+ <item quantity="one">Ky kanal nuk mund të luhet deri në <xliff:g id="END_TIME_0">%1$s</xliff:g> pasi po regjistrohet një kanal tjetër. \n\nShtyp \"Djathtas\" për të rregulluar planifikimin e regjistrimit.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Pa titull"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanali u bllokua"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Të reja"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Burimet"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d kanale</item>
+ <item quantity="one">%1$d kanal</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Nuk ka kanale të disponueshme"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Të reja"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Nuk është konfiguruar"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Merr burime të tjera"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Shfleto aplikacionet që ofrojnë kanale drejtpërdrejt"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Burime të reja të kanaleve të disponueshme"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Burime të reja të kanaleve kanë kanale për të ofruar.\nKonfiguroji ato tani ose bëje këtë më vonë te cilësimi i burimeve të kanaleve."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Konfiguro tani"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"Në rregull, e kuptova"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307"><b>"Shtyp \"ZGJIDH\""</b>" për të pasur qasje te menyja e televizorit."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"Nuk u gjet asnjë hyrje e televizorit"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"Hyrja e televizorit nuk mund të gjendet"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Lloji i sintonizuesit nuk është i përshtatshëm. Hap aplikacionin \"Kanalet drejtpërdrejt\" për hyrjen e televizorit për llojin e sintonizuesit."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Sintonizimi dështoi"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Nuk u gjet asnjë aplikacion për të menaxhuar këtë veprim"</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Të gjitha kanalet e burimit janë të fshehura.\nZgjidh të paktën një kanal për ta shikuar."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Videoja papritur nuk është e disponueshme"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"Tasti \"PRAPA\" është për pajisjen e lidhur. Shtyp butonin \"KREU\" për të dalë."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"\"Kanalet drejtpërdrejt\" kanë nevojë për leje për të lexuar listimet e televizorit."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Konfiguro burimet e tua"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Kanalet drejtpërdrejt ndërthurin eksperiencën e kanaleve televizive tradicionale me kanalet në transmetim të ofruara nga aplikacionet. \n\nFillo duke konfiguruar burimet e kanaleve të instaluara tashmë. Ose shfleto në \"Dyqanin e Google Play\" për më shumë aplikacione që ofrojnë kanale drejtpërdrejt."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Regjistrimet dhe planifikimet"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minuta"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minuta"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 orë"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 orë"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Të fundit"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Të planifikuara"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Seritë"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Të tjera"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Kanali nuk mund të regjistrohet."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Programi nuk mund të regjistrohet."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> është planifikuar për t\'u regjistruar"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"Po regjistron <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nga tani deri në <xliff:g id="ENDTIME">%2$s</xliff:g>"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"Planifikimi i plotë"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">%1$d ditë të tjera</item>
+ <item quantity="one">%1$d ditë tjetër</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d minuta</item>
+ <item quantity="one">%1$d minutë</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d regjistrime të reja</item>
+ <item quantity="one">%1$d regjistrim i ri</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d regjistrime</item>
+ <item quantity="one">%1$d regjistrim</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d regjistrime të planifikuara</item>
+ <item quantity="one">%1$d regjistrim i planifikuar</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Anulo regjistrimin"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Ndalo regjistrimin"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Shiko"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Luaj nga fillimi"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Vazhdo luajtjen"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"Fshi"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Fshi regjistrimet"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Rifillo"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"Sezoni <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Shiko planifikimin"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Lexo më shumë"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Fshi regjistrimet"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"Zgjidh episodet që dëshiron të fshish. Ato nuk mund të rikuperohen pasi të fshihen."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"Nuk ka regjistrime për të fshirë."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Zgjidh episodet e shikuara"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Zgjidh të gjitha episodet"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Anulo zgjedhjen për të gjitha episodet"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="WATCHED">%1$d</xliff:g> nga <xliff:g id="DURATION">%2$d</xliff:g> minuta të shikuara"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="WATCHED">%1$d</xliff:g> nga <xliff:g id="DURATION">%2$d</xliff:g> sekonda të shikuara"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Asnjëherë të shikuara"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%1$d nga %2$d episode janë fshirë</item>
+ <item quantity="one">%1$d nga %2$d episod është fshirë</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Me prioritet"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Maksimal"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Shumë të ulët"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"Numri <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Kanalet"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Çdo kanal"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Zgjidh përparësinë"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Kur ka shumë programe për t\'u regjistruar në të njëjtën kohë, vetëm ata me përparësitë më të larta do të regjistrohen."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Ruaj"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Regjistrimet e njëhershme kanë përparësinë më të lartë"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"Ndalo"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Shiko planifikimin e regjistrimeve"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Vetëm këtë regjistrim"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"tani - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"Të gjithë serinë…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Planifiko gjithsesi"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Regjistro këtë më mirë"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Anuloje këtë regjistrim"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Shiko tani"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Fshi regjistrimet…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Mund të regjistrohet"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Regjistrimi u planifikua"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Konflikt në regjistrim"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Regjistrimi"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Regjistrimi dështoi"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Po lexon programet"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Shiko regjistrimet e fundit"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Regjistrimi i <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nuk është i plotë."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Regjistrimet e <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> dhe <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> nuk janë të plota."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Regjistrimet e <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> dhe <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> nuk janë të plota."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Regjistrimi i <xliff:g id="PROGRAMNAME">%1$s</xliff:g> nuk përfundoi për shkak të hapësirës ruajtëse të pamjaftueshme."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Regjistrimet e <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> dhe <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> nuk përfunduan për shkak të hapësirës ruajtëse të pamjaftueshme."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Regjistrimet e <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> dhe <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> nuk përfunduan për shkak të hapësirës ruajtëse të pamjaftueshme."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR-ja ka nevojë për më shumë hapësirë ruajtëse"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Do të mund t\'i regjistrosh programet me DVR. Sidoqoftë, nuk ka hapësirë ruajtëse të mjaftueshme në pajisje tani që DVR-ja të funksionojë. Lidh një njësi të jashtme disku që është <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB ose më shumë dhe ndiq hapat për ta formatuar si hapësirë ruajtëse të pajisjes."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Nuk ka hapësirë ruajtëse të mjaftueshme"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Ky program nuk do të regjistrohet pasi nuk ka hapësirë ruajtëse të mjaftueshme. Provo të fshish disa regjistrime ekzistuese."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Hapësira ruajtëse mungon"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Të ndalohet regjistrimi?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Përmbajtja e regjistruar do të ruhet."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Regjistrimi i <xliff:g id="PROGRAMNAME">%1$s</xliff:g> do të ndalohet pasi është në konflikt me këtë program. Përmbajtja e regjistruar do të ruhet."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Regjistrimi u planifikua, por ka konflikte"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Regjistrimi ka nisur, por ka konflikte"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> do të regjistrohet."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> po regjistrohet."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"Disa pjesë të <xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> nuk do të regjistrohen."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"Disa pjesë të <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> dhe <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> nuk do të regjistrohen."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"Disa pjesë të <xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> dhe një regjistrimi tjetër nuk do të regjistrohen."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other">Disa pjesë të <xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> dhe %3$d planifikime të tjera nuk do të regjistrohen.</item>
+ <item quantity="one">Disa pjesë të <xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> dhe %3$d planifikim tjetër nuk do të regjistrohen.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Çfarë dëshiron të regjistrosh?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Për sa kohë dëshiron të regjistrosh?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Planifikuar tashmë"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"I njëjti program është planifikuar tashmë që të regjistrohet në <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Regjistruar tashmë"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Ky program është regjistruar tashmë. Ai disponohet në bibliotekën DVR."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Regjistrimi i serisë u planifikua"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> regjistrime janë planifikuar për <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> regjistrim është planifikuar për <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> regjistrime janë planifikuar për <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> prej tyre nuk do të regjistrohen për shkak të konflikteve.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> regjistrim është planifikuar për <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Ai nuk do të regjistrohet për shkak të konflikteve.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> regjistrime janë planifikuar për <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episode të kësaj serie dhe serive të tjera nuk do të regjistrohen për shkak të konflikteve.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> regjistrim është planifikuar për <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episode të kësaj serie dhe serive të tjera nuk do të regjistrohen për shkak të konflikteve.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> regjistrime janë planifikuar për <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 episod i serive të tjera nuk do të regjistrohet për shkak të konflikteve.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> regjistrim është planifikuar për <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 episod i serive të tjera nuk do të regjistrohet për shkak të konflikteve.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> regjistrime janë planifikuar për <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episode të serive të tjera nuk do të regjistrohen për shkak të konflikteve.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> regjistrim është planifikuar për <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> episode të serive të tjera nuk do të regjistrohen për shkak të konflikteve.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Programi i regjistruar nuk u gjet."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Regjistrimet e lidhura"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d regjistrime</item>
+ <item quantity="one">%1$d regjistrim</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> u hoq nga planifikimi i regjistrimeve"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Do të regjistrohet pjesërisht për shkak të konflikteve të sintonizuesit."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Nuk do të regjistrohet për shkak të konflikteve të sintonizuesit."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Nuk ka asnjë regjistrim ende të planifikim.\nMund ta planifikosh regjistrimin nga udhëzuesi i programeve."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d konflikte regjistrimi</item>
+ <item quantity="one">%1$d konflikt regjistrimi</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Cilësimet e serive"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Nis regjistrimin e serisë"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Ndalo regjistrimin e serisë"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Të ndalohet regjistrimi i serisë?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Episodet e regjistruara do të jenë të disponueshme në bibliotekën DVR."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Ndalo"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Nuk ka episode në transmetim tani."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Nuk ka episode të disponueshme.\nAto do të regjistrohen pasi të jenë të disponueshme."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d minuta)</item>
+ <item quantity="one">(%1$d minutë) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Sot"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Nesër"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Dje"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> sot"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> nesër"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Rezultati"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Programet e regjistruara"</string>
+</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 0b4c2f3c..ce291eda 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Play контроле"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Недавни канали"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Канали"</string>
<string name="menu_title_options" msgid="7184594626814914022">"ТВ опције"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Опц. сл. у сл."</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Контроле за пуштање нису доступне за овај канал"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Пусти или паузирај"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Премотај унапред"</string>
@@ -35,36 +34,18 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Титлови"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Режим приказа"</string>
<string name="options_item_pip" msgid="3951350386626879645">"Слика у слици"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Укључено"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Искључено"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Вишеструк аудио"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Набави још канала"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Подешавања"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Извор"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Замени"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Укључено"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Искључено"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Звук"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Главни"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Прозор слике у слици"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Распоред"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Доњи десни угао"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Горњи десни угао"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Горњи леви угао"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Доњи леви угао"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Упоредо"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Величина"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Велика"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Мала"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Извор улаза"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"ТВ (антенска/кабловска)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Нема информација о програму"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Нема информација"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Блокирани канал"</string>
- <string name="default_language" msgid="4122326459624337928">"Непознат језик"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Непознат језик"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Опционални титл: %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Опционални титлови"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Искључи"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Прилагоди формат"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Прилагођавање формата"</string>
<string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Изаберите подешавања титлова за цео систем"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"Режим приказа"</string>
<string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Вишеструки аудио"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Групиши према"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Овај програм је блокиран"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Овај програм није оцењен"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Овај програм има оцену <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Улаз не подржава аутоматско скенирање"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Није успело покретање аутоматског скенирања за „<xliff:g id="TV_INPUT">%s</xliff:g>“"</string>
@@ -93,7 +75,6 @@
<item quantity="other">Додато је %1$d канала</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Нема додатих канала"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Тјунер"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Родитељски надзор"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Укључи"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Искључи"</string>
@@ -109,6 +90,8 @@
<string name="other_countries" msgid="8342216398676184749">"Друге земље"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Ништа"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Ништа"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Неоцењено"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Блокирај неоцењене програме"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Ништа"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Велика ограничења"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Средња ограничења"</string>
@@ -125,6 +108,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Унесите PIN да бисте гледали овај канал"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Унесите PIN да бисте гледали овај програм"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Овај програм има оцену <xliff:g id="RATING">%1$s</xliff:g>. Унесите PIN да бисте гледали овај програм"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Овај програм није оцењен. Унесите PIN да бисте гледали овај програм"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Унесите PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Да бисте подесили родитељску контролу, направите PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Унесите нови PIN"</string>
@@ -137,22 +121,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Тај PIN је погрешан. Пробајте поново."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Пробајте поново, PIN се не подудара"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Унесите поштански број"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Апликација Канали уживо ће користити овај поштански број да би пружила комплетан водич за програме за ТВ канале."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Унесите поштански број"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Неважећи поштански број"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Подешавања"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Прилагоди листу канала"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Изаберите канале за водич за програме"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Извори канала"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Доступни су нови канали"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Родитељски надзор"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Контрола времена"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Снимајте док гледате да бисте могли да паузирате или премотате програме уживо.\nУпозорење: Ово може да скрати радни век интерне меморије због њеног интензивног коришћења."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Лиценце отвореног кода"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Лиценце отвореног кода"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Пошаљи повратне информације"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Верзија"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Да бисте гледали овај канал, притисните дугме Десно и унесите PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Да бисте гледали овај програм, притисните дугме Десно и унесите PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Овај програм није оцењен.\nДа бисте гледали овај програм, притисните тастер са стрелицом удесно и унесите PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Овај програм има оцену <xliff:g id="RATING">%1$s</xliff:g>.\nДа бисте гледали овај програм, притисните дугме Десно и унесите PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Да бисте гледали овај канал, користите подразумевану апликацију за ТВ уживо."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Да бисте гледали овај програм, користите подразумевану апликацију за ТВ уживо."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Овај програм није оцењен.\nTДа бисте гледали овај програм, користите подразумевану апликацију за ТВ уживо."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Овај програм има оцену <xliff:g id="RATING">%1$s</xliff:g>.\nДа бисте гледали овај програм, користите подразумевану апликацију за ТВ уживо."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Програм је блокиран"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Овај програм није оцењен"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Овај програм има оцену <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Само аудио"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Слаб сигнал"</string>
@@ -185,8 +178,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Притисните ИЗАБЕРИ"</b>" да бисте приступили TV менију."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Нису пронађени ТВ улази"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Не можемо да пронађемо ТВ улаз"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Слика у слици није подржана"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Нема улаза који може да се прикаже као слика у слици"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Тип тјунера не одговара. Покрените апликацију Канали уживо за тип ТВ улаза са тјунером."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Подешавање није успело"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Није пронађена ниједна апликација која би могла да обави ову радњу."</string>
@@ -235,6 +226,8 @@
<item quantity="few">%1$d снимања су заказана</item>
<item quantity="other">%1$d снимања је заказано</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Откажи снимање"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Заустави снимање"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Пусти"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Пусти од почетка"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Настави репродукцију"</string>
@@ -268,9 +261,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Када истовремено има превише програма за снимање, снимаће се само програми са вишим приоритетом."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Сачувај"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Једнократни снимци имају највиши приоритет"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Откажи"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Откажи"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Заборави"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Заустави"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Прикажи распоред за снимање"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Само ова епизода"</string>
@@ -280,25 +270,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Сними овај програм уместо њега"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Откажи ово снимање"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Пусти одмах"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Избришите снимке…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Подржава снимање"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Снимање је заказано"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Неусаглашеност при снимању"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Снимање"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Снимање није успело"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Читамо програме да бисмо направили распореде"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Читамо програме"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Читамо програме"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Прикажи недавне снимке"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Снимање програма <xliff:g id="PROGRAMNAME">%1$s</xliff:g> није довршено."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Снимање програма <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> и <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> није довршено."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Снимање програма <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> и <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> није довршено."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Нисмо довршили снимање програма <xliff:g id="PROGRAMNAME">%1$s</xliff:g> због недовољног меморијског простора."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Снимање програма <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> и <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> није довршено због недовољног меморијског простора."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Снимање програма <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> и <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> није довршено због недовољног меморијског простора."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR-у треба више меморијског простора"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Моћи ћете да снимате програме помоћу DVR-а. Међутим, тренутно на уређају нема довољно меморијског простора да би DVR функционисао. Повежите спољни диск који има <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB или више и пратите кораке да бисте га форматирали као меморијски простор уређаја."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Моћи ћете да снимате програме помоћу DVR-а. Међутим, тренутно на уређају нема довољно меморијског простора да би DVR функционисао. Повежите спољни диск који има <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB или више и пратите кораке да бисте га форматирали као меморијски простор уређаја."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Нема довољно меморијског простора"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Овај програм неће бити снимљен јер нема довољно меморијског простора. Пробајте да избришете неколико постојећих снимака."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Меморијски простор недостаје"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Недостаје део меморијског простора који DVR користи. Повежите спољни диск који сте раније користили да бисте поново омогућили DVR. Уместо тога можете да заборавите меморијски простор ако више није доступан."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Желите ли да заборавите меморијски простор?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Сав снимљени садржај и распореди ће бити изгубљени."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Зауставити снимање?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Снимљени садржај ће се сачувати."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Снимање програма <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ће се зауставити јер је дошло до неусаглашености са овим програмом. Снимљени садржај ће бити сачуван."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Снимање је заказано, али постоје неусаглашености"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Снимање је почело али има неусаглашености"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Програм <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ће бити снимљен."</string>
@@ -317,17 +310,34 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Снимање истог програма је већ заказано за <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Већ је снимљено"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Овај програм је већ снимљен. Доступан је у DVR филмотеци."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Снимање серије је заказано"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимање је заказано за серијал <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимања су заказана за серијал <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимања је заказано за серијал <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимање је заказано за серијал <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Због преклапања неће бити снимљено: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимања су заказана за серијал <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Због преклапања неће бити снимљено: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимања је заказано за серијал <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Због преклапања неће бити снимљено: <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> снимање је заказано за серијал <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизода(е) овог серијала и других серијала неће бити снимљено због преклапања.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> снимања су заказана за серијал <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизода(е) овог серијала и других серијала неће бити снимљено због преклапања.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> снимања је заказано за серијал <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизода(е) овог серијала и других серијала неће бити снимљено због преклапања.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимање је заказано за серијал <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 епизода другог серијала неће бити снимљена због преклапања.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимања су заказана за серијал <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 епизода другог серијала неће бити снимљена због преклапања.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> снимања је заказано за серијал <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 епизода другог серијала неће бити снимљена због преклапања.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> снимање је заказано за серијал <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизоде(а) других серијала неће бити снимљено због преклапања.</item>
+ <item quantity="few"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> снимања су заказана за серијал <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизоде(а) других серијала неће бити снимљено због преклапања.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> снимања је заказано за серијал <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> епизоде(а) других серијала неће бити снимљено због преклапања.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Снимљени програм није пронађен."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Сродни снимци"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Нема описа програма)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d снимак</item>
<item quantity="few">%1$d снимка</item>
@@ -349,6 +359,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Зауставити снимање серије?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Снимљене епизоде ће остати доступне у DVR библиотеци."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Заустави"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Тренутно се не приказује ниједна епизода."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Нема доступних епизода.\nБиће снимљене када постану доступне."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d минут)</item>
@@ -361,4 +372,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Данас <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Сутра <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Оцена"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Снимљене емисије"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 212fd957..62bbe7fe 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Uppspelningskontroller"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Senaste kanaler"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanaler"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Tv-alternativ"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP-alternativ"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Uppspelningskontrollerna är inte tillgängliga för den här kanalen"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Spela upp eller pausa"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Snabbspola framåt"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Textning"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Visningsläge"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"På"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Av"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Flera ljudkäll."</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Få fler kanaler"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Inställningar"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Källa"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Byt"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"På"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Av"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Ljud"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Primär"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP-fönster"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Layout"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Nere till h."</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Uppe till h."</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Uppe till v."</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Nere till v."</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Sida vid sida"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Storlek"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Stor"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Liten"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Ingångskälla"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"Tv (antenn/kabel)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Ingen programinformation"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Ingen information"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Blockerad kanal"</string>
- <string name="default_language" msgid="4122326459624337928">"Okänt språk"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Okänt språk"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Textning %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Textning"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Av"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Anpassa formatering"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Ordna efter"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Programmet är blockerat"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Det här programmet har ingen åldersgräns"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Det här programmet har kategoriserats som <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Ingången stöder inte automatisk sökning"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Det går inte att starta automatisk sökning för <xliff:g id="TV_INPUT">%s</xliff:g>"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d kanal har lagts till</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Inga kanaler har lagts till"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Mottagare"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Barnfilter"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"På"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Av"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Övriga länder"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Inga"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Inga"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Ingen åldersgräns"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Blockera prog. utan åldersgr."</string>
<string name="option_rating_none" msgid="5204552587760414879">"Inga"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Höga begränsningar"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Medelbegränsningar"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Ange pinkoden om du vill titta på den här kanalen"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Ange pinkoden om du vill titta på det här programmet"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Programmet har klassificerats som <xliff:g id="RATING">%1$s</xliff:g>. Ange pinkoden om du vill titta på programmet"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Det här programmet har ingen åldersgräns. Ange pinkoden om du vill titta på programmet"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Ange din pinkod"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Skapa en pinkod om du vill konfigurera barnfiltret"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Ange en ny pinkod"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Det var fel pinkod. Försök igen."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Försök igen. Pinkoden stämmer inte"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Ange ditt postnummer."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Appen Livekanaler använder postnumret till att ta fram en komplett programguide för TV-kanalerna."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Ange ditt postnummer"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Ogiltigt postnummer"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Inställningar"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Anpassa kanallista"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Välj kanaler för programguiden"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanalkällor"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Det finns nya kanaler"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Innehållsfilter"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Tidsförskjutning"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Spela in medan du tittar så att du kan pausa och spola tillbaka program medan de sänds.\nVarning! Detta kan medföra att internminnets livslängd förkortas eftersom lagringsutrymmet används mycket."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Licenser för öppen källkod"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Öppen källkod"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Skicka feedback"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Version"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Tryck till höger och ange pinkoden om du vill titta på den här kanalen"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Tryck till höger och ange pinkoden om du vill titta på det här programmet"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Det här programmet har ingen åldersgräns.\nOm du vill titta på programmet trycker du på Höger och anger pinkoden."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Det här programmet har kategoriserats som <xliff:g id="RATING">%1$s</xliff:g>\nTryck till höger och ange pinkoden om du vill titta på det här programmet."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Använd standardappen för live-TV om du vill titta på den här kanalen."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Använd standardappen för live-TV om du vill titta på programmet."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Det här programmet har ingen åldersgräns.\nAnvänd standardappen för direktsänd TV om du vill titta på programmet."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Programmet har klassificeringen <xliff:g id="RATING">%1$s</xliff:g>.\nAnvänd standardappen för live-TV om du vill titta på programmet."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Programmet har blockerats"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Det här programmet har ingen åldersgräns"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Det här programmet har kategoriserats som <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Endast ljud"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Svag signal"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Tryck på VÄLJ"</b>" för att öppna TV-menyn."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Ingen tv-ingång hittades"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Det går inte att hitta tv-ingången"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP stöds inte"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Det finns ingen tillgänglig ingång som kan visas med PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Olämplig insignal. Starta appen Livekanaler om du vill kunna ta emot insignaler av tv-kortstyp."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Kanaljusteringen misslyckades"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Ingen app som kan hantera åtgärden hittades"</string>
@@ -191,11 +182,11 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Knappen BACK (bakåt) gäller en ansluten enhet. Avsluta genom att trycka på knappen HOME (start)."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Livekanaler behöver behörighet att läsa TV-tablåer."</string>
<string name="setup_sources_text" msgid="4988039637873759839">"Konfigurera dina källor"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Livekanaler kombinerar det bästa från traditionella TV-kanaler med strömmande kanaler från appar. \n\nKom igång genom att konfigurera de kanalkällor som redan är installerade eller kolla in Google Play Butik för fler appar som erbjuder livekanaler."</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Livekanaler kombinerar det bästa från traditionella TV-kanaler med streamade kanaler från appar. \n\nKom igång genom att konfigurera de kanalkällor som redan är installerade eller kolla in Google Play Butik för fler appar som erbjuder livekanaler."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Inspelningar och scheman"</string>
<string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 minuter"</string>
<string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 minuter"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"En timme"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 timme"</string>
<string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 timmar"</string>
<string name="dvr_main_recent" msgid="2553805424822806495">"Senaste"</string>
<string name="dvr_main_scheduled" msgid="7837260963086408492">"Planerat"</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d schemalagda inspelningar</item>
<item quantity="one">%1$d schemalagd inspelning</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Avbryt inspelning"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Sluta spela in"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Klocka"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Spela upp från början"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Fortsätt spela upp"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"När det finns för många program för att de ska kunna spelas in samtidigt spelas endast de med högst prioritet in."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Spara"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Engångsinspelningar har högsta prioritet"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Avbryt"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Avbryt"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Glöm"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Stoppa"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Visa inspelningsschema"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Bara det här programmet"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Spela in detta i stället"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Avbryt den här inspelningen"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Titta nu"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Radera inspelningar …"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Kan spelas in"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Inspelningen har schemalagts"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Inspelningskonflikt"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Inspelning"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Inspelningen misslyckades"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Läser in program för att inspelningsscheman"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Läser in program"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Läser in program"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Visa de senaste inspelningarna"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Inspelningen av <xliff:g id="PROGRAMNAME">%1$s</xliff:g> är ofullständig."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Inspelningen av <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> och <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> är ofullständig."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Inspelningen av <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> och <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> är ofullständig."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Det gick inte att slutföra inspelningen av <xliff:g id="PROGRAMNAME">%1$s</xliff:g> eftersom det inte finns tillräckligt med lagringsutrymme."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Det gick inte att slutföra inspelningen av <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> och <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> eftersom det inte finns tillräckligt med lagringsutrymme."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Det gick inte att slutföra inspelningen av <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> och <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> eftersom det inte finns tillräckligt med lagringsutrymme."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Mer lagringsutrymme krävs för hårddiskinspelning"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Du kan använda hårddiskinspelning för att spela in program, men just nu finns det inte tillräckligt mycket ledigt lagringsutrymme på enheten för hårddiskinspelning. Anslut en extern enhet på minst <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB och följ anvisningarna för att formatera den som enhetslagring."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Du kan använda hårddiskinspelning för att spela in program, men just nu finns det inte tillräckligt mycket ledigt lagringsutrymme på enheten för hårddiskinspelning. Anslut en extern enhet på minst <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB och följ anvisningarna för att formatera den som enhetslagring."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Otillräckligt lagringsutrymme"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Det här programmet spelas inte in eftersom lagringsutrymmet inte räcker. Du kan göra plats genom att radera gamla inspelningar."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Lagringsutrymmet är inte tillgängligt"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"En del av lagringsutrymmet som används av DVR saknas. Anslut den externa hårddisken du använde innan DVR återaktiverades. Du kan också att välja att glömma bort lagringsutrymmet om det inte längre är tillgängligt."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Ska lagringsutrymmet glömmas bort?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Allt rekommenderat innehåll och alla inspelningsscheman försvinner."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Vill du sluta spela in?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Det inspelade innehållet sparas."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Inspelningen av <xliff:g id="PROGRAMNAME">%1$s</xliff:g> avbryts eftersom den krockar med det här programmet. Det inspelade innehållet sparas."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Inspelningen har schemalagts men innehåller konflikter"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Inspelningen har startat men innehåller konflikter"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> spelas in."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Samma program har schemalagts för inspelning kl. <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Redan inspelat"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Programmet har redan spelats in. Det finns i DVR-biblioteket."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Serieinspelningen har schemalagts"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> inspelningar har schemalagts för <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> inspelning har schemalagts för <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> inspelningar har schemalagts för <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> av dem spelas inte in på grund av programkrockar.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> inspelning har schemalagts för <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Det spelas inte in på grund av programkrockar.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> inspelningar har schemalagts för <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> avsnitt av den här serien och andra serier spelas inte in på grund av programkrockar.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> inspelning har schemalagts för <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> avsnitt av den här serien och andra serier spelas inte in på grund av programkrockar.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> inspelningar har schemalagts för <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 avsnitt av andra serier spelas inte in på grund av programkrockar.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> inspelning har schemalagts för <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 avsnitt av andra serier spelas inte in på grund av programkrockar.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> inspelningar har schemalagts för <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> avsnitt av andra serier spelas inte in på grund av programkrockar.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> inspelning har schemalagts för <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> avsnitt av andra serier spelas inte in på grund av programkrockar.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Det gick inte att hitta det inspelade programmet."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Relaterade inspelningar"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Programbeskrivning saknas)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d inspelningar</item>
<item quantity="one">%1$d inspelning</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Vill du stoppa serieinspelning?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Inspelade avsnitt finns kvar i DVR-biblioteket"</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Stoppa"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Inga avsnitt sänds just nu."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Det finns inga tillgängliga avsnitt.\nDe spelas in när de är tillgängliga."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d minuter)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> i dag"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> i morgon"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Betyg"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Inspelade program"</string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 00038ff4..ac55f0a0 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Vidhibiti vya kucheza"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Vituo vya hivi karibuni"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Vituo"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Chaguo za Runinga"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Chaguo za PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Vidhibiti vya kucheza havipatikani kwa kituo hiki"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Cheza au usitishe"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Peleka mbele kwa kasi"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Manukuu"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Hali ya onyesho"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Imewashwa"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Imezimwa"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Sauti nyingi"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Pata vituo zaidi"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Mipangilio"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Chanzo"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Badili"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Imewashwa"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Imezimwa"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Sauti"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Kuu"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Dirisha la PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Muundo"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Chini kulia"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Juu kulia"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Juu kushoto"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Chini kushoto"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Upande kwa upande"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Ukubwa"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Kubwa"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Ndogo"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Chanzo cha data"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"Runinga (antena/kebo)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Hakuna maelezo ya programu"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Hakuna maelezo"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Kituo kilichozuiwa"</string>
- <string name="default_language" msgid="4122326459624337928">"Lugha Isiyojulikana"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Lugha isiyojulikana"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Manukuu %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Manukuu"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Imezimwa"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Geuza muundo ukufae"</string>
@@ -83,16 +64,16 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Panga kikundi kwa"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Kipindi hiki kimezuiwa"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Kipindi hiki hakijakadiriwa"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Kipindi hiki kimekadiriwa <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Kifaa cha kuingiza sauti hakitumii uchanganuzi wa kiotomatiki"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Haikuweza kuanzisha uchanganuzi kiotomatiki kwa \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Kifaa cha kuingiza sauti hakitumii ukaguzi wa kiotomatiki"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Haikuweza kuanzisha ukaguzi wa kiotomatiki wa \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
<string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Haikuweza kuanzisha mapendeleo ya mfumo mzima kwa manukuu."</string>
<plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
<item quantity="other">Vituo %1$d vimeongezwa</item>
<item quantity="one">Kituo %1$d kimeongezwa </item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Hakuna vituo vimeongezwa"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Kirekebisha mawimbi"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Udhibiti wa wazazi"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Imewashwa"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Imezimwa"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Nchi nyingine"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Hakuna"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Hakuna"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Hakijakadiriwa"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Zuia vipindi ambavyo havijakadiriwa"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Hakuna"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Vizuizi kiwango cha juu"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Vikwazo vya kati"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Weka PIN yako ili uangalie kituo hiki"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Weka PIN yako ili uangalie kipindi hiki"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Kipindi hiki kimepewa ukadiriaji wa <xliff:g id="RATING">%1$s</xliff:g>. Weka PIN yako ili ukitazame"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Kipindi hiki hakijakadiriwa. Andika PIN yako ili ukitazame"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Weka PIN yako"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Ili uweke udhibiti wa wazazi, unda PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Weka PIN mpya"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"PIN uliyoweka si sahihi. Jaribu tena."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Jaribu tena, PIN hailingani"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Andika Msimbo wa Eneo lako"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Programu ya Televisheni Mtandaoni itatumia Msimbo wa eneo lako ili kutoa orodha kamili ya vipindi vya vituo vya televisheni."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Weka Msimbo wa Eneo lako"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Msimbo wa Eneo si Sahihi"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Mipangilio"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Geuza orodha ya vituo utakavyo"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Chagua vituo kwa ajili ya orodha yako ya vipindi"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Vyanzo vya vituo"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Vituo vipya vinapatikana"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Udhibiti wa wazazi"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Kipengele cha kubadilisha wakati"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Rekodi vipindi vinapoendelea kucheza ili uweze kusitisha au kurudisha nyuma vipindi vya moja kwa moja.\nOnyo: Huenda hatua hii ikapunguza muda wa matumizi ya hifadhi ya ndani kutokana na matumizi mengi ya hifadhi."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Leseni za programu huria"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Leseni za programu huria"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Tuma maoni"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Toleo"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Ili uangalie kituo hiki, bonyeza Kulia na uweke PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Ili uangalie kipindi hiki, bonyeza Kulia na uweke PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Kipindi hiki hakijakadiriwa.\nIli ukitazame, bofya \'Sawa\' kisha uandike PIN yako"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Kipindi hiki kimekadiriwa <xliff:g id="RATING">%1$s</xliff:g>.\nIli utazame kipindi hiki, bonyeza Kulia na uweke PIN yako"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Ili kutazama kituo hiki, tumia chaguo-msingi ya programu ya TV ya moja kwa moja."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Ili kutazama kituo hiki, tumia chaguo-msingi ya programu ya TV ya moja kwa moja."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Kipindi hiki hakijakadiriwa.\nIli ukitazame, tumia programu chaguo-msingi ya Televisheni ya Moja kwa Moja."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Programu hii imekadiriwa <xliff:g id="RATING">%1$s</xliff:g>.\nIli kutazama kituo hiki, tumia chaguo-msingi ya programu ya TV ya moja kwa moja."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Kipindi kimezuiwa"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Kipindi hiki hakijakadiriwa"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Kipindi hiki kimekadiriwa <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Sauti pekee"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Mawimbi dhaifu"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Bonyeza CHAGUA "</b>" ili ufikie menyu ya televisheni."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Hakuna vifaa vya kuingiza maudhui ya runinga vinavyopatikana"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Haiwezi kupata vifaa vya kuingiza maudhui kwenye runinga"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP haiwezi kutumika"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Hakuna maudhui yanayoweza kuonyeshwa pamoja na PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Aina ya kirekebishaji haifai. Fungua programu ya Vituo vya Moja kwa Moja ya vifaa vya kuingiza maudhui ya runinga."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Haikuweza kurekebisha"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Hakuna programu iliyopatikana inayoweza kushughulikia kitendo hiki."</string>
@@ -226,6 +217,8 @@
<item quantity="other">Rekodi %1$d zimeratibiwa</item>
<item quantity="one">Rekodi %1$d imeratibiwa</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Ghairi kurekodi"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Acha kurekodi"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Saa"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Cheza kutoka mwanzo"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Endelea kucheza"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Wakati kuna vipindi vingi vya kurekodi kwa wakati mmoja, tutarekodi vipindi vilivyopewa kipaumbele pekee."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Hifadhi"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Rekodi za mara moja hupewa kipaumbele"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Ghairi"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Ghairi"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Sahau"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Komesha"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Angalia ratiba ya kurekodi"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Mpango huu mmoja"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Rekodi hii badala yake"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Ghairi rekodi hii"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Angalia sasa"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Futa rekodi..."</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Inaweza kurekodiwa"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Kurekodi kumeratibiwa"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Hitilafu ya kurekodi"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Inarekodi"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Imeshindwa kurekodi"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Inasoma maelezo ya programu ili kuunda ratiba"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Inasoma programu"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Inasoma ratiba"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Angalia rekodi za hivi majuzi"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Haikumaliza kurekodi <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Haikumaliza kurekodi <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> na <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Haikumaliza kurekodi <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> na <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Haikumaliza kurekodi <xliff:g id="PROGRAMNAME">%1$s</xliff:g> kwa sababu nafasi ya hifadhi haikutosha."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Haikumaliza kurekodi <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> na <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> kwa sababu nafasi ya hifadhi haikutosha."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Haikumaliza kurekodi <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> na <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> kwa sababu nafasi ya hifadhi haikutosha."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR inahitaji nafasi zaidi ya hifadhi"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Utaweza kurekodi vipindi kwa kutumia DVR. Hata hivyo, kwa sasa hakuna hifadhi ya kutosha kwenye kifaa chako ili kuwezesha DVR kufanya kazi. Tafadhali unganisha hifadhi ya nje isiyopungua GB <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> na ufuate hatua za kuiumbiza kuwa hifadhi ya kifaa."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Utaweza kurekodi vipindi kwa kutumia DVR. Hata hivyo, kwa sasa hakuna hifadhi ya kutosha kwenye kifaa chako ili kuwezesha DVR kufanya kazi. Tafadhali unganisha hifadhi ya nje isiyopungua GB <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> na ufuate hatua za kuiumbiza kuwa hifadhi ya kifaa."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Hifadhi haitoshi"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Kipindi hiki hakitarekodiwa kwa sababu hakuna hifadhi ya kutosha. Jaribu kufuta baadhi ya vipindi vilivyopo."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Hifadhi haipo"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Baadhi ya hifadhi inayotumiwa na DVR haipo. Tafadhali unganisha hifadhi ya nje uliyotumia awali ili uwashe upya DVR yako. Vinginevyo, unaweza kuchagua kusahau hifadhi ikiwa haipatikani tena."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Ungependa kusahau hifadhi?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Hatua hii itaondoa maudhui na ratiba zote ulizohifadhi."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Ungependa kuacha kurekodi?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Itahifadhi maudhui uliyorekodi."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Shughuli ya kurekodi kipindi cha <xliff:g id="PROGRAMNAME">%1$s</xliff:g> itasitishwa kwa sababu inakinzana na kipindi hiki. Maudhui yaliyorekodiwa yatahifadhiwa."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Rekodi zimeratibiwa lakini zinakinzana"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Inaendelea kurekodi japo kuna ukinzani"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> itarekodiwa."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Tayari umeratibu kurekodi kipindi hiki saa <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Tayari kimerekodiwa"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Tayari umerekodi kipindi hiki. Kinapatikana katika maktaba ya DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Shughuli ya kurekodi mfululizo imeratibiwa"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">Imeratibu kurekodi vipindi <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> vya <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one">Imeratibu kurekodi kipindi <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> cha <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">Imeratibu kurekodi vipindi <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> vya <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Haitarekodi vipindi <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> kutokana na ukinzani.</item>
+ <item quantity="one">Imeratibu kurekodi kipindi <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> cha <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Haitarekodi kipindi kutokana na ukinzani.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">Imeratibu kurekodi vipindi <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> vya <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Haitarekodi vipindi <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> vya mfululizo huu na mifululizo mingine kutokana na ukinzani.</item>
+ <item quantity="one">Imeratibu kurekodi kipindi <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> cha <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Haitarekodi vipindi <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> vya mfululizo huu na mifululizo mingine kutokana na ukinzani.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">Imeratibu kurekodi vipindi <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> vya <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Haitarekodi kipindi 1 cha mifululizo mingine kutokana na ukinzani.</item>
+ <item quantity="one">Imeratibu kurekodi kipindi <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> cha <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Haitarekodi kipindi 1 cha mifululizo mingine kutokana na ukinzani.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">Imeratibu kurekodi vipindi <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> vya <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. Haitarekodi vipindi <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> vya mifululizo mingine kutokana na ukinzani.</item>
+ <item quantity="one">Imeratibu kurekodi kipindi <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> cha <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Haitarekodi vipindi <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> vya mifululizo mingine kutokana na ukinzani.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Haikupata programu iliyorekodiwa."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Rekodi zinazohusiana"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Hakuna maelezo ya programu)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">Rekodi %1$d</item>
<item quantity="one">Rekodi %1$d</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Ungependa kukomesha kurekodi mfululizo?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Vipindi vilivyorekodiwa vitaendelea kupatikana katika maktaba ya DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Komesha"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Hakuna vipindi vinavyopeperushwa kwa sasa."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Hakuna vipindi vinavyopatikana.\nVitarekodiwa pindi vitakapopatikana."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(Dakika %1$d)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Leo <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Kesho <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Alama"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Vipindi Vilivyorekodiwa"</string>
</resources>
diff --git a/res/values-ta-v23/strings.xml b/res/values-ta-rIN-v23/strings.xml
index 1b94e0c4..1b94e0c4 100644
--- a/res/values-ta-v23/strings.xml
+++ b/res/values-ta-rIN-v23/strings.xml
diff --git a/res/values-ta/arrays.xml b/res/values-ta-rIN/arrays.xml
index 9d2c1f24..9d2c1f24 100644
--- a/res/values-ta/arrays.xml
+++ b/res/values-ta-rIN/arrays.xml
diff --git a/res/values-ta/rating_system_strings.xml b/res/values-ta-rIN/rating_system_strings.xml
index ae80dee6..ae80dee6 100644
--- a/res/values-ta/rating_system_strings.xml
+++ b/res/values-ta-rIN/rating_system_strings.xml
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
new file mode 100644
index 00000000..43e1a717
--- /dev/null
+++ b/res/values-ta-rIN/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"மோனோ"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"ஸ்டீரியோ"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"இயக்கக் கட்டுப்பாடுகள்"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"சேனல்கள்"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"டிவி விருப்பங்கள்"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"இந்தச் சேனலுக்கு இயக்கக் கட்டுப்பாடுகள் இல்லை"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"இயக்கு அல்லது இடைநிறுத்து"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"வேகமாக முன் நகர்த்து"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"வேகமாக பின் நகர்த்து"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"அடுத்து"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"முந்தையது"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"நிகழ்ச்சிக் கையேடு"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"புதிய சேனல்கள் உள்ளன"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g>ஐத் திற"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"விரிவான வசனங்கள்"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"காட்சிப் பயன்முறை"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"மல்டி-ஆடியோ"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"மேலும் சேனல்கள்"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"அமைப்புகள்"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"டிவி (ஆண்டெனா/கேபிள்)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"நிகழ்ச்சி தகவல் இல்லை"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"தகவல் இல்லை"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"தடுக்கப்பட்ட சேனல்"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"தெரியாத மொழி"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"வசனங்கள் %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"விரிவான வசனங்கள்"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"முடக்கு"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"வடிவமைப்பைத் தனிப்பயனாக்கவும்"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"விரிவான வசனங்களுக்கான முன்னுரிமைகளை முறைமை முழுவதும் அமைக்கவும்"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"காட்சிப் பயன்முறை"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"மல்டி-ஆடியோ"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"மோனோ"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ஸ்டீரியோ"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 சரவுண்ட்"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 சரவுண்ட்"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d சேனல்கள்"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"சேனலை தனிப்படுத்து"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"குழுவைத் தேர்வுசெய்க"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"குழுவின் தேர்வைநீக்கு"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"இதன்படி குழுவாக்கு"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"சேனல் மூலம்"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"இதன்படி குழுவாக்கு"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"இந்த நிகழ்ச்சி தடுக்கப்பட்டுள்ளது"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"இந்த நிகழ்ச்சி மதிப்பிடப்படவில்லை"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"இந்த நிகழ்ச்சி <xliff:g id="RATING">%1$s</xliff:g> என மதிப்பிடப்பட்டுள்ளது"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"தன்னியக்க ஸ்கேனை உள்ளீடு ஆதரிக்காது"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"’<xliff:g id="TV_INPUT">%s</xliff:g>’க்கான தன்னியக்க ஸ்கேனைத் தொடங்க முடியவில்லை"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"விரிவான வசனங்களுக்கான சாதன விருப்பத்தேர்வுகளைத் தொடங்க முடியவில்லை."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d சேனல்கள் சேர்க்கப்பட்டன</item>
+ <item quantity="one">%1$d சேனல் சேர்க்கப்பட்டது</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"சேனல்கள் எதுவும் சேர்க்கப்படவில்லை"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"பெற்றோர் கட்டுப்பாடுகள்"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"இயக்கு"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"முடக்கு"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"சேனல்கள் தடுக்கப்பட்டன"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"எல்லாவற்றையும் தடு"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"எல்லாவற்றிலும் தடைநீக்கு"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"மறைக்கப்பட்ட சேனல்கள்"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"நிகழ்ச்சிக் கட்டுப்பாடுகள்"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN ஐ மாற்று"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"மதிப்பிடல் அமைப்புகள்"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"மதிப்பீடுகள்"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"அனைத்து மதிப்பீட்டு அமைப்புகளையும் பார்க்கவும்"</string>
+ <string name="other_countries" msgid="8342216398676184749">"பிற நாடுகள்"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"ஏதுமில்லை"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ஏதுமில்லை"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"மதிப்பிடாதது"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"மதிப்பிடாத நிகழ்ச்சிகளைத் தடு"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"ஏதுமில்லை"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"அதிகக் கட்டுப்பாடுகள்"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"நடுத்தரக் கட்டுப்பாடுகள்"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"குறைவான கட்டுப்பாடுகள்"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"தனிப்பயன்"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"குழந்தைகளுக்கு ஏற்றது"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"குழந்தைகளுக்கு ஏற்றது"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"பதின்ம வயதினருக்கு ஏற்றது"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"கைமுறைக் கட்டுப்பாடுகள்"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s மற்றும் துணை மதிப்பீடுகள்"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"துணை மதிப்பிடல்கள்"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"இந்தச் சேனலைப் பார்க்க பின்னை உள்ளிடவும்"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"இந்த நிகழ்ச்சியைப் பார்க்க பின்னை உள்ளிடவும்"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"இந்த நிகழ்ச்சி <xliff:g id="RATING">%1$s</xliff:g> என மதிப்பிடப்பட்டுள்ளது. நிகழ்ச்சியைப் பார்க்க, உங்கள் பின்னை உள்ளிடவும்"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"இந்த நிகழ்ச்சி மதிப்பிடப்படவில்லை. இதைப் பார்க்க, உங்கள் பின்னை உள்ளிடவும்"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"பின்னை உள்ளிடவும்"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"பெற்றோர் கட்டுப்பாடுகளை அமைக்க, PINஐ உருவாக்கவும்"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"புதிய PINஐ உள்ளிடவும்"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"PINஐ உறுதிசெய்யவும்"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"உங்கள் தற்போதைய PINஐ உள்ளிடவும்"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">பின்னை 5 முறை தவறாக உள்ளிட்டுள்ளீர்கள்.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்.</item>
+ <item quantity="one">பின்னை 5 முறை தவறாக உள்ளிட்டுள்ளீர்கள்.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> வினாடியில் மீண்டும் முயலவும்.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN தவறானது. மீண்டும் முயலவும்."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"மீண்டும் முயலவும், PIN பொருந்தவில்லை"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"அஞ்சல் குறியீட்டை உள்ளிடவும்."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"நேரலைச் சேனல்கள் பயன்பாடானது, டிவி சேனல்களின் முழுமையான நிகழ்ச்சி வழிகாட்டியை வழங்குவதற்கு அஞ்சல் குறியீட்டைப் பயன்படுத்தும்."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"அஞ்சல் குறியீட்டை உள்ளிடவும்"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"தவறான அஞ்சல் குறியீடு"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"அமைப்புகள்"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"சேனல் பட்டியலைத் தனிப்பயனாக்கு"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"நிகழ்ச்சி வழிகாட்டியில் சேர்ப்பதற்கான சேனல்களைத் தேர்வுசெய்க"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"சேனல் மூலங்கள்"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"புதிய சேனல்கள் உள்ளன"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"பெற்றோர் கட்டுப்பாடுகள்"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"டைம்ஷிஃப்ட்"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"நேரலை நிகழ்ச்சிகளைப் பார்க்கும் போதே ரெக்கார்டு செய்யலாம் என்பதால், அவற்றை இடைநிறுத்தலாம் அல்லது ரீவைண்ட் செய்து பார்க்கலாம்.\nஎச்சரிக்கை: இது சேமிப்பகத்தை அதிகளவு பயன்படுத்தும் என்பதால், சாதனச் சேமிப்பகத்தின் ஆயுளைக் குறைக்கக்கூடும்."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"ஓப்பன் சோர்ஸ் உரிமங்கள்"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"கருத்து அனுப்பு"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"பதிப்பு"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"இந்தச் சேனலைப் பார்க்க, வலது பக்கம் அழுத்தி, உங்கள் PINஐ உள்ளிடவும்"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"இந்த நிகழ்ச்சியைப் பார்க்க, வலது பக்கம் அழுத்தி PINஐ உள்ளிடவும்"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"இந்த நிகழ்ச்சி மதிப்பிடப்படவில்லை.\nஇதைப் பார்க்க, \"Right\" என்பதை அழுத்தி, உங்கள் பின்னை உள்ளிடவும்"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"இந்த நிகழ்ச்சி <xliff:g id="RATING">%1$s</xliff:g> என மதிப்பிடப்பட்டுள்ளது.\nஅதைப் பார்க்க, வலது பக்கம் அழுத்தி, பின்னை உள்ளிடவும்."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"இந்தச் சேனலைப் பார்க்க, இயல்புநிலை லைவ் டிவி பயன்பாட்டைப் பயன்படுத்தவும்."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"இந்த நிகழ்ச்சியைப் பார்க்க, இயல்புநிலை லைவ் டிவி பயன்பாட்டைப் பயன்படுத்தவும்."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"இந்த நிகழ்ச்சி மதிப்பிடப்படவில்லை.\nஇதைப் பார்க்க, இயல்பு லைவ் டிவி பயன்பாட்டைப் பயன்படுத்தவும்."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"இந்த நிகழ்ச்சி <xliff:g id="RATING">%1$s</xliff:g> என மதிப்பிடப்பட்டுள்ளது.\nஇந்த நிகழ்ச்சியைப் பார்க்க, இயல்புநிலை லைவ் டிவி பயன்பாட்டைப் பயன்படுத்தவும்."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"நிகழ்ச்சி தடுக்கப்பட்டுள்ளது"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"இந்த நிகழ்ச்சி மதிப்பிடப்படவில்லை"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"இந்த நிகழ்ச்சி <xliff:g id="RATING">%1$s</xliff:g> என மதிப்பிடப்பட்டுள்ளது"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ஆடியோ மட்டும்"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"வலுவற்ற சிக்னல்"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"இணைய இணைப்பு இல்லை"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">மற்ற சேனல்கள் ரெக்கார்டு செய்யப்படுவதால், <xliff:g id="END_TIME_1">%1$s</xliff:g> வரை இந்தச் சேனலை இயக்க முடியாது. \n\nரெக்கார்டு செய்வதற்கான திட்ட அட்டவணையில் மாற்றம் செய்ய, \"Right\" என்பதை அழுத்தவும்.</item>
+ <item quantity="one">மற்றொரு சேனல் ரெக்கார்டு செய்யப்படுவதால், <xliff:g id="END_TIME_0">%1$s</xliff:g> வரை இந்தச் சேனலை இயக்க முடியாது. \n\nரெக்கார்டு செய்வதற்கான திட்ட அட்டவணையில் மாற்றம் செய்ய, \"Right\" என்பதை அழுத்தவும்.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"தலைப்பு இல்லை"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"சேனல் தடுக்கப்பட்டது"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"புதியவை"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"மூலங்கள்"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d சேனல்கள்</item>
+ <item quantity="one">%1$d சேனல்</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"சேனல்கள் எதுவுமில்லை"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"புதியவை"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"அமைக்கப்படவில்லை"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"கூடுதல் ஆதாரங்களைப் பெறுக"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"நேரலை சேனல்களை வழங்கும் பயன்பாடுகளைத் தேடலாம்"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"புதிய சேனல் மூலங்கள் உள்ளன"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"புதிய சேனல் மூலங்களில் பல சேனல்களைப் பெறலாம்.\nஅவற்றை இப்போதே அமைக்கவும் அல்லது சேனல் மூலங்கள் அமைப்பில் பிறகு அமைக்கவும்."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"இப்போது அமை"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"சரி"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"TV மெனுவை அணுக, "<b>"SELECTஐ அழுத்தவும்"</b>"."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"டிவி உள்ளீடு இல்லை"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"டிவி உள்ளீடு இல்லை"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ட்யூனர் வகை பொருந்தவில்லை. ட்யூனர் வகை டிவி உள்ளீட்டிற்கு நேரலைச் சேனல்கள் பயன்பாட்டைத் துவங்கவும்."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ட்யூன் செய்ய முடியவில்லை"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"இந்தச் செயலைச் செய்வதற்கான பயன்பாடு எதுவுமில்லை."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"எல்லா சேனல்களும் மறைக்கப்பட்டுள்ளன.\nபார்க்க, ஒரு சேனலையாவது தேர்ந்தெடுக்கவும்."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"வீடியோ கிடைக்கவில்லை"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"Back விசை இணைத்த சாதனத்திற்கானது. வெளியேற, Home பட்டனை அழுத்துக."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"டிவி பட்டியல்களைப் படிக்க, நேரலைச் சேனல்களுக்கு அனுமதி தேவை."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"மூலங்களை அமைக்கவும்"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"நேரலைச் சேனல்களானது பயன்பாடுகள் வழங்கும் ஸ்ட்ரீமிங் சேனல்களுடன் பாரம்பரிய டிவி சேனல்களின் அனுபவத்தை ஒன்றிணைக்கிறது. \n\nஏற்கனவே நிறுவிய சேனல் மூலங்களை அமைப்பதன் மூலம் தொடங்கவும் அல்லது நேரலைச் சேனல்களை வழங்கும் கூடுதல் பயன்பாடுகளைப் பெற, Google Play ஸ்டோரில் தேடவும்."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"ரெக்கார்டிங்குகள் &amp; திட்ட அட்டவணைகள்"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 நிமிடங்கள்"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 நிமிடங்கள்"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 மணிநேரம்"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 மணிநேரம்"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"சமீபத்தியவை"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"திட்டமிடப்பட்டது"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"தொடர்"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"மற்றவை"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"இந்தச் சேனலை ரெக்கார்டு செய்ய முடியாது."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"இந்த நிகழ்ச்சியை ரெக்கார்டு செய்ய முடியாது."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ரெக்கார்டு செய்வதற்காகத் திட்டமிடப்பட்டது"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"இப்போதிலிருந்து <xliff:g id="ENDTIME">%2$s</xliff:g> வரை <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ரெக்கார்டு செய்யப்படுகிறது"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"முழுத் திட்ட அட்டவணை"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">அடுத்த %1$d நாட்கள்</item>
+ <item quantity="one">அடுத்த %1$d நாள்</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d நிமிடங்கள்</item>
+ <item quantity="one">%1$d நிமிடம்</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d புதிய ரெக்கார்டிங்குகள்</item>
+ <item quantity="one">%1$d புதிய ரெக்கார்டிங்</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d ரெக்கார்டிங்குகள்</item>
+ <item quantity="one">%1$d ரெக்கார்டிங்</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d ரெக்கார்டிங்குகள் திட்டமிடப்பட்டன</item>
+ <item quantity="one">%1$d ரெக்கார்டிங் திட்டமிடப்பட்டது</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"ரெக்கார்டிங்கை ரத்துசெய்"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"ரெக்கார்டிங்கை நிறுத்து"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"இயக்கு"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"முதலிலிருந்து இயக்கு"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"மீண்டும் தொடங்கு"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"நீக்கு"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ரெக்கார்டிங்குகளை நீக்கு"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"மீண்டும்தொடங்கு"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"சீசன் <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"ஷெட்யூலை காட்டு"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"மேலும் படிக்க"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ரெக்கார்டிங்குகளை நீக்கு"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"நீக்க விரும்பும் எபிசோடுகளைத் தேர்ந்தெடுக்கவும். ஒருமுறை நீக்கிவிட்டால், அவற்றை மீட்டெடுக்க முடியாது."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"நீக்குவதற்கான ரெக்கார்டிங்குகள் இல்லை."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"பார்த்த எபிசோடுகளை தேர்ந்தெடு"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"எல்லாம் தேர்ந்தெடு"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"எல்லாம் தேர்வு நீக்கு"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> இல் <xliff:g id="WATCHED">%1$d</xliff:g> நிமிடங்கள் பார்த்துள்ளீர்கள்"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> இல் <xliff:g id="WATCHED">%1$d</xliff:g> வினாடிகள் பார்த்துள்ளீர்கள்"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"இதுவரை பார்க்காதவை"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%2$d இல் %1$d எபிசோடுகள் நீக்கப்பட்டன</item>
+ <item quantity="one">%2$d இல் %1$d எபிசோடு நீக்கப்பட்டது</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"முன்னுரிமை"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"மிக அதிக முன்னுரிமை"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"மிகக்குறைந்த முன்னுரிமை"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"முன்னுரிமை: <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"சேனல்கள்"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"எந்தச் சேனலும்"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"முன்னுரிமையைத் தேர்வுசெய்க"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"ஒரே நேரத்தில் பல நிகழ்ச்சிகளை ரெக்கார்டு செய்ய வேண்டியிருந்தால், அதிக முன்னுரிமைகளைக் கொண்ட நிகழ்ச்சிகள் மட்டுமே ரெக்கார்டு செய்யப்படும்."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"சேமி"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ஒரே முறை ரெக்கார்டு செய்யக்கூடியவற்றுக்கு மிக அதிக முன்னுரிமை வழங்கு"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"நிறுத்து"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ரெக்கார்டிங் ஷெட்யூலைக் காட்டு"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"இந்த நிகழ்ச்சியை மட்டும்"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"இப்போதிலிருந்து <xliff:g id="ENDTIME">%1$s</xliff:g> வரை"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"தொடர் முழுவதும்…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"பரவாயில்லை, திட்டமிடு"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"பதிலாக, இதை ரெக்கார்டு செய்"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"இந்த ரெக்கார்டிங்கை ரத்துசெய்"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"இப்போது காட்டு"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"ரெக்கார்டிங்குகளை நீக்கு…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"ரெக்கார்டு செய்யக்கூடியது"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ரெக்கார்டிங் திட்டமிடப்பட்டது"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ரெக்கார்டிங்கில் முரண்பாடு"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ரெக்கார்ட் செய்யப்படுகிறது"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ரெக்கார்டு செய்ய முடியவில்லை"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"நிகழ்ச்சிகளைப் படிக்கிறது"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"சமீபத்திய ரெக்கார்டிங்குகளைக் காட்டு"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>ஐ ரெக்கார்டு செய்வது முடிவடையவில்லை."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> மற்றும் <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>ஐ ரெக்கார்டு செய்வது முடிவடையவில்லை."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ஆகியவற்றை ரெக்கார்டு செய்வது முடிவடையவில்லை."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"போதுமான சேமிப்பிடம் இல்லாததால், <xliff:g id="PROGRAMNAME">%1$s</xliff:g>ஐ ரெக்கார்டு செய்வது முடிவடையவில்லை."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"போதுமான சேமிப்பிடம் இல்லாததால், <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> மற்றும் <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>ஐ ரெக்கார்டு செய்வது முடிவடையவில்லை."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"போதுமான சேமிப்பிடம் இல்லாததால், <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>, <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ஆகியவற்றை ரெக்கார்டு செய்வது முடிவடையவில்லை."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVRக்கு அதிகச் சேமிப்பிடம் தேவை"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"நீங்கள் DVR மூலம் நிகழ்ச்சிகளைப் பதிவுசெய்ய முடியும். எனினும், DVR சரியாக வேலை செய்வதற்குத் தேவைப்படும் போதுமான சேமிப்பகம் இப்போது சாதனத்தில் இல்லை. <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>ஜி.பை. அல்லது அதற்கும் அதிகமான அளவில் உள்ள வெளிப்புற இயக்ககத்தை இணைக்கவும். பின் அதைச் சாதனச் சேமிப்பகமாகப் பயன்படுத்த, இந்தப் படிகளைப் பின்பற்றவும்."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"போதுமான சேமிப்பிடம் இல்லை"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"போதுமான சேமிப்பிடம் இல்லாததால், இந்த நிகழ்ச்சி ரெக்கார்டு செய்யப்படாது. ஏற்கனவே உள்ள சில ரெக்கார்டிங்குகளை நீக்கவும்."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"சேமிப்பகம் இல்லை"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ரெக்கார்டு செய்வதை நிறுத்தவா?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ரெக்கார்டு செய்த உள்ளடக்கம் சேமிக்கப்படும்."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>ஐ ரெக்கார்டு செய்வது இந்த நிகழ்ச்சியுடன் முரண்படுவதால், ரெக்கார்டிங் நிறுத்தப்படும். ரெக்கார்டு செய்த உள்ளடக்கம் சேமிக்கப்படும்."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ரெக்கார்டிங் திட்டமிடப்பட்டது, ஆனால் முரண்பாடுகள் உள்ளன"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ரெக்கார்டு செய்வது தொடங்கப்பட்டது, ஆனால் முரண்பாடுகள் உள்ளன"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ரெக்கார்டு செய்யப்படும்."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ரெக்கார்டு செய்யப்படுகிறது."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> இன் சில பகுதிகள் ரெக்கார்டு செய்யப்படாது."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ஆகியவற்றின் சில பகுதிகள் ரெக்கார்டு செய்யப்படாது."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> இன் சில பகுதிகளும், ரெக்கார்டு செய்யத் திட்டமிட்டிருந்த மேலும் ஒரு நிகழ்ச்சியும் ரெக்கார்டு செய்யப்படாது."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ஆகியவற்றின் சில பகுதிகளும், ரெக்கார்டு செய்யத் திட்டமிட்டிருந்த மேலும் %3$d நிகழ்ச்சிகளும் ரெக்கார்டு செய்யப்படாது.</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> ஆகியவற்றின் சில பகுதிகளும், ரெக்கார்டு செய்யத் திட்டமிட்டிருந்த மேலும் %3$d நிகழ்ச்சியும் ரெக்கார்டு செய்யப்படாது.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"எதை ரெக்கார்டு செய்ய விரும்புகிறீர்கள்?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"எவ்வளவு நேரம் ரெக்கார்டு செய்ய விரும்புகிறீர்கள்?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ஏற்கனவே திட்டமிடப்பட்டுள்ளது"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>க்கு ரெக்கார்டு செய்வதற்காக இந்த நிகழ்ச்சி ஏற்கனவே திட்டமிடப்பட்டுள்ளது."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ஏற்கனவே ரெக்கார்டு செய்யப்பட்டது"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"இந்த நிகழ்ச்சி ஏற்கனவே ரெக்கார்டு செய்யப்பட்டது. மேலும் DVR நூலகத்தில் கிடைக்கும்."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"தொடர் ரெக்கார்டிங் திட்டமிடப்பட்டது"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> தொடருக்கு <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ரெக்கார்டிங்குகள் திட்டமிடப்பட்டுள்ளன.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> தொடருக்கு <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ரெக்கார்டிங் திட்டமிடப்பட்டுள்ளது.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> தொடருக்கு <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ரெக்கார்டிங்குகள் திட்டமிடப்பட்டுள்ளன. முரண்பாடுகளின் காரணமாக, இந்தத் தொடரின் <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> எபிசோடுகள் ரெக்கார்டு செய்யப்படாது.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> தொடருக்கு <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ரெக்கார்டிங் திட்டமிடப்பட்டுள்ளது. முரண்பாடுகளின் காரணமாக, இது ரெக்கார்டு செய்யப்படாது.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> தொடருக்கு <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ரெக்கார்டிங்குகள் திட்டமிடப்பட்டுள்ளன. முரண்பாடுகளின் காரணமாக, இந்தத் தொடர் மற்றும் பிற தொடரின் <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> எபிசோடுகள் ரெக்கார்டு செய்யப்படாது.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> தொடருக்கு <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ரெக்கார்டிங் திட்டமிடப்பட்டுள்ளது. முரண்பாடுகளின் காரணமாக, இந்தத் தொடர் மற்றும் பிற தொடரின் <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> எபிசோடுகள் ரெக்கார்டு செய்யப்படாது.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> தொடருக்கு <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ரெக்கார்டிங்குகள் திட்டமிடப்பட்டுள்ளன. முரண்பாடுகளின் காரணமாக, பிற தொடரின் ஒரு எபிசோடு ரெக்கார்டு செய்யப்படாது.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> தொடருக்கு <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ரெக்கார்டிங் திட்டமிடப்பட்டுள்ளது. முரண்பாடுகளின் காரணமாக, பிற தொடரின் ஒரு எபிசோடு ரெக்கார்டு செய்யப்படாது.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> தொடருக்கு <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ரெக்கார்டிங்குகள் திட்டமிடப்பட்டுள்ளன. முரண்பாடுகளின் காரணமாக, பிற தொடரின் <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> எபிசோடுகள் ரெக்கார்டு செய்யப்படாது.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> தொடருக்கு <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ரெக்கார்டிங் திட்டமிடப்பட்டுள்ளது. முரண்பாடுகளின் காரணமாக, பிற தொடரின் <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> எபிசோடுகள் ரெக்கார்டு செய்யப்படாது.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"ரெக்கார்டு செய்த நிகழ்ச்சி இல்லை."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"தொடர்புடைய ரெக்கார்டிங்குகள்"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d ரெக்கார்டிங்குகள்</item>
+ <item quantity="one">%1$d ரெக்கார்டிங்</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"ரெக்கார்டிங் திட்ட அட்டவணையிலிருந்து <xliff:g id="PROGRAMNAME">%1$s</xliff:g> அகற்றப்பட்டது"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ட்யூனர் இல்லாததால், பகுதியளவு ரெக்கார்டு செய்யப்படும்."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ட்யூனர் இல்லாததால், ரெக்கார்டு செய்யப்படாது."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ரெக்கார்டு செய்வதற்காக எதுவும் திட்டமிடப்படவில்லை.\nநிகழ்ச்சி வழிகாட்டிக்குச் சென்று, ரெக்கார்டிங்கைத் திட்டமிடலாம்."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d ரெக்கார்டிங் முரண்பாடுகள்</item>
+ <item quantity="one">%1$d ரெக்கார்டிங் முரண்பாடு</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"தொடர் அமைப்புகள்"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"தொடர் ரெக்கார்டிங்கைத் தொடங்கு"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"தொடர் ரெக்கார்டிங்கை நிறுத்து"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"தொடர் ரெக்கார்டிங்கை நிறுத்தவா?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ரெக்கார்டு செய்யப்பட எபிசோடுகள் தொடர்ந்து DVR நூலகத்தில் இருக்கும்."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"நிறுத்து"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"இப்போது எந்த எபிசோடுகளும் நேரலையில் இல்லை."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"எபிசோடுகள் இல்லை.\nஅவை கிடைக்கும் போது ரெக்கார்டு செய்யப்படும்."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d நிமிடங்கள்)</item>
+ <item quantity="one">(%1$d நிமிடம்) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"இன்று"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"நாளை"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"நேற்று"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"இன்று <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"நாளை <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"ஸ்கோர்"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"ரெக்கார்டு செய்த நிகழ்ச்சிகள்"</string>
+</resources>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
deleted file mode 100644
index 7d13e3cf..00000000
--- a/res/values-ta/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"மோனோ"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"ஸ்டீரியோ"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"இயக்கக் கட்டுப்பாடுகள்"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"சமீபத்திய சேனல்கள்"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"டிவி விருப்பங்கள்"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP விருப்பங்கள்"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"இந்தச் சேனலுக்கு இயக்கக் கட்டுப்பாடுகள் இல்லை"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"இயக்கு அல்லது இடைநிறுத்து"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"வேகமாக முன் நகர்த்து"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"வேகமாக பின் நகர்த்து"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"அடுத்து"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"முந்தையது"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"நிகழ்ச்சிக் கையேடு"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"புதிய சேனல்கள் உள்ளன"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g>ஐத் திற"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"விரிவான வசனங்கள்"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"காட்சிப் பயன்முறை"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"இயக்கத்தில்"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"முடக்கத்தில்"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"மல்டி-ஆடியோ"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"மேலும் சேனல்கள்"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"அமைப்புகள்"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"மூலம்"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"மாற்று"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"இயக்கத்தில்"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"முடக்கத்தில்"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"ஒலி"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"முதன்மை"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP சாளரம்"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"தளவமைப்பு"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"கீழ் வலதுபுறம்"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"மேல் வலதுபுறம்"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"மேல் இடதுபுறம்"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"கீழ் இடதுபுறம்"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"அருகருகே"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"அளவு"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"பெரியது"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"சிறியது"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"உள்ளீட்டு மூலம்"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"டிவி (ஆண்டெனா/கேபிள்)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"நிகழ்ச்சி தகவல் இல்லை"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"தகவல் இல்லை"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"தடுக்கப்பட்ட சேனல்"</string>
- <string name="default_language" msgid="4122326459624337928">"தெரியாத மொழி"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"விரிவான வசனங்கள்"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"முடக்கு"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"வடிவமைப்பைத் தனிப்பயனாக்கவும்"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"விரிவான வசனங்களுக்கான முன்னுரிமைகளை முறைமை முழுவதும் அமைக்கவும்"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"காட்சிப் பயன்முறை"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"மல்டி-ஆடியோ"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"மோனோ"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"ஸ்டீரியோ"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 சரவுண்ட்"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 சரவுண்ட்"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d சேனல்கள்"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"சேனலை தனிப்படுத்து"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"குழுவைத் தேர்வுசெய்க"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"குழுவின் தேர்வைநீக்கு"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"இதன்படி குழுவாக்கு"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"சேனல் மூலம்"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"இதன்படி குழுவாக்கு"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"இந்த நிகழ்ச்சி தடுக்கப்பட்டுள்ளது"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"இந்த நிகழ்ச்சி <xliff:g id="RATING">%1$s</xliff:g> என மதிப்பிடப்பட்டுள்ளது"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"தன்னியக்க ஸ்கேனை உள்ளீடு ஆதரிக்காது"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"’<xliff:g id="TV_INPUT">%s</xliff:g>’க்கான தன்னியக்க ஸ்கேனைத் தொடங்க முடியவில்லை"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"விரிவான வசனங்களுக்கான சாதன விருப்பத்தேர்வுகளைத் தொடங்க முடியவில்லை."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d சேனல்கள் சேர்க்கப்பட்டன</item>
- <item quantity="one">%1$d சேனல் சேர்க்கப்பட்டது</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"சேனல்கள் எதுவும் சேர்க்கப்படவில்லை"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ட்யூனர்"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"பெற்றோர் கட்டுப்பாடுகள்"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"இயக்கு"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"முடக்கு"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"சேனல்கள் தடுக்கப்பட்டன"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"எல்லாவற்றையும் தடு"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"எல்லாவற்றிலும் தடைநீக்கு"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"மறைக்கப்பட்ட சேனல்கள்"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"நிகழ்ச்சிக் கட்டுப்பாடுகள்"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN ஐ மாற்று"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"மதிப்பிடல் அமைப்புகள்"</string>
- <string name="option_ratings" msgid="4009116954188688616">"மதிப்பீடுகள்"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"அனைத்து மதிப்பீட்டு அமைப்புகளையும் பார்க்கவும்"</string>
- <string name="other_countries" msgid="8342216398676184749">"பிற நாடுகள்"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"ஏதுமில்லை"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ஏதுமில்லை"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"ஏதுமில்லை"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"அதிகக் கட்டுப்பாடுகள்"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"நடுத்தரக் கட்டுப்பாடுகள்"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"குறைவான கட்டுப்பாடுகள்"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"தனிப்பயன்"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"குழந்தைகளுக்கு ஏற்றது"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"குழந்தைகளுக்கு ஏற்றது"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"பதின்ம வயதினருக்கு ஏற்றது"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"கைமுறைக் கட்டுப்பாடுகள்"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s மற்றும் துணை மதிப்பீடுகள்"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"துணை மதிப்பிடல்கள்"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"இந்தச் சேனலைப் பார்க்க பின்னை உள்ளிடவும்"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"இந்த நிகழ்ச்சியைப் பார்க்க பின்னை உள்ளிடவும்"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"இந்த நிகழ்ச்சி <xliff:g id="RATING">%1$s</xliff:g> என மதிப்பிடப்பட்டுள்ளது. நிகழ்ச்சியைப் பார்க்க, உங்கள் பின்னை உள்ளிடவும்"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"பின்னை உள்ளிடவும்"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"பெற்றோர் கட்டுப்பாடுகளை அமைக்க, PINஐ உருவாக்கவும்"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"புதிய PINஐ உள்ளிடவும்"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"PINஐ உறுதிசெய்யவும்"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"உங்கள் தற்போதைய PINஐ உள்ளிடவும்"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">பின்னை 5 முறை தவறாக உள்ளிட்டுள்ளீர்கள்.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்.</item>
- <item quantity="one">பின்னை 5 முறை தவறாக உள்ளிட்டுள்ளீர்கள்.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> வினாடியில் மீண்டும் முயலவும்.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN தவறானது. மீண்டும் முயலவும்."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"மீண்டும் முயலவும், PIN பொருந்தவில்லை"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"அமைப்புகள்"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"சேனல் பட்டியலைத் தனிப்பயனாக்கு"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"நிகழ்ச்சி வழிகாட்டியில் சேர்ப்பதற்கான சேனல்களைத் தேர்வுசெய்க"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"சேனல் மூலங்கள்"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"புதிய சேனல்கள் உள்ளன"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"பெற்றோர் கட்டுப்பாடுகள்"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"ஓப்பன் சோர்ஸ் உரிமங்கள்"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"ஓப்பன் சோர்ஸ் உரிமங்கள்"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"பதிப்பு"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"இந்தச் சேனலைப் பார்க்க, வலது பக்கம் அழுத்தி, உங்கள் PINஐ உள்ளிடவும்"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"இந்த நிகழ்ச்சியைப் பார்க்க, வலது பக்கம் அழுத்தி PINஐ உள்ளிடவும்"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"இந்த நிகழ்ச்சி <xliff:g id="RATING">%1$s</xliff:g> என மதிப்பிடப்பட்டுள்ளது.\nஅதைப் பார்க்க, வலது பக்கம் அழுத்தி, பின்னை உள்ளிடவும்."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"இந்தச் சேனலைப் பார்க்க, இயல்புநிலை லைவ் டிவி பயன்பாட்டைப் பயன்படுத்தவும்."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"இந்த நிகழ்ச்சியைப் பார்க்க, இயல்புநிலை லைவ் டிவி பயன்பாட்டைப் பயன்படுத்தவும்."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"இந்த நிகழ்ச்சி <xliff:g id="RATING">%1$s</xliff:g> என மதிப்பிடப்பட்டுள்ளது.\nஇந்த நிகழ்ச்சியைப் பார்க்க, இயல்புநிலை லைவ் டிவி பயன்பாட்டைப் பயன்படுத்தவும்."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"நிகழ்ச்சி தடுக்கப்பட்டுள்ளது"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"இந்த நிகழ்ச்சி <xliff:g id="RATING">%1$s</xliff:g> என மதிப்பிடப்பட்டுள்ளது"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ஆடியோ மட்டும்"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"வலுவற்ற சிக்னல்"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"இணைய இணைப்பு இல்லை"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">மற்ற சேனல்கள் ரெக்கார்டு செய்யப்படுவதால், <xliff:g id="END_TIME_1">%1$s</xliff:g> வரை இந்தச் சேனலை இயக்க முடியாது. \n\nரெக்கார்டு செய்வதற்கான திட்ட அட்டவணையில் மாற்றம் செய்ய, \"Right\" என்பதை அழுத்தவும்.</item>
- <item quantity="one">மற்றொரு சேனல் ரெக்கார்டு செய்யப்படுவதால், <xliff:g id="END_TIME_0">%1$s</xliff:g> வரை இந்தச் சேனலை இயக்க முடியாது. \n\nரெக்கார்டு செய்வதற்கான திட்ட அட்டவணையில் மாற்றம் செய்ய, \"Right\" என்பதை அழுத்தவும்.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"தலைப்பு இல்லை"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"சேனல் தடுக்கப்பட்டது"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"புதியவை"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"மூலங்கள்"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d சேனல்கள்</item>
- <item quantity="one">%1$d சேனல்</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"சேனல்கள் எதுவுமில்லை"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"புதியவை"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"அமைக்கப்படவில்லை"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"கூடுதல் ஆதாரங்களைப் பெறுக"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"நேரலை சேனல்களை வழங்கும் பயன்பாடுகளைத் தேடலாம்"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"புதிய சேனல் மூலங்கள் உள்ளன"</string>
- <string name="new_sources_description" msgid="749649005588426813">"புதிய சேனல் மூலங்களில் பல சேனல்களைப் பெறலாம்.\nஅவற்றை இப்போதே அமைக்கவும் அல்லது சேனல் மூலங்கள் அமைப்பில் பிறகு அமைக்கவும்."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"இப்போது அமை"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"சரி"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"TV மெனுவை அணுக, "<b>"SELECTஐ அழுத்தவும்"</b>"."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"டிவி உள்ளீடு இல்லை"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"டிவி உள்ளீடு இல்லை"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP ஆதரிக்கப்படவில்லை"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP உடன் காண்பிக்கத்தக்க உள்ளீடு எதுவுமில்லை"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ட்யூனர் வகை பொருந்தவில்லை. ட்யூனர் வகை டிவி உள்ளீட்டிற்கு நேரலைச் சேனல்கள் பயன்பாட்டைத் துவங்கவும்."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"ட்யூன் செய்ய முடியவில்லை"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"இந்தச் செயலைச் செய்வதற்கான பயன்பாடு எதுவுமில்லை."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"எல்லா சேனல்களும் மறைக்கப்பட்டுள்ளன.\nபார்க்க, ஒரு சேனலையாவது தேர்ந்தெடுக்கவும்."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"வீடியோ கிடைக்கவில்லை"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"Back விசை இணைத்த சாதனத்திற்கானது. வெளியேற, Home பட்டனை அழுத்துக."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"டிவி பட்டியல்களைப் படிக்க, நேரலைச் சேனல்களுக்கு அனுமதி தேவை."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"மூலங்களை அமைக்கவும்"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"நேரலைச் சேனல்களானது பயன்பாடுகள் வழங்கும் ஸ்ட்ரீமிங் சேனல்களுடன் பாரம்பரிய டிவி சேனல்களின் அனுபவத்தை ஒன்றிணைக்கிறது. \n\nஏற்கனவே நிறுவிய சேனல் மூலங்களை அமைப்பதன் மூலம் தொடங்கவும் அல்லது நேரலைச் சேனல்களை வழங்கும் கூடுதல் பயன்பாடுகளைப் பெற, Google Play ஸ்டோரில் தேடவும்."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"ரெக்கார்டிங்குகள் &amp; திட்ட அட்டவணைகள்"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 நிமிடங்கள்"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 நிமிடங்கள்"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 மணிநேரம்"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 மணிநேரம்"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"சமீபத்தியவை"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"திட்டமிடப்பட்டது"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"தொடர்"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"மற்றவை"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"இந்தச் சேனலை ரெக்கார்டு செய்ய முடியாது."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"இந்த நிகழ்ச்சியை ரெக்கார்டு செய்ய முடியாது."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ரெக்கார்டு செய்வதற்காகத் திட்டமிடப்பட்டது"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"இப்போதிலிருந்து <xliff:g id="ENDTIME">%2$s</xliff:g> வரை <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ரெக்கார்டு செய்யப்படுகிறது"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"முழுத் திட்ட அட்டவணை"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">அடுத்த %1$d நாட்கள்</item>
- <item quantity="one">அடுத்த %1$d நாள்</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d நிமிடங்கள்</item>
- <item quantity="one">%1$d நிமிடம்</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d புதிய ரெக்கார்டிங்குகள்</item>
- <item quantity="one">%1$d புதிய ரெக்கார்டிங்</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d ரெக்கார்டிங்குகள்</item>
- <item quantity="one">%1$d ரெக்கார்டிங்</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d ரெக்கார்டிங்குகள் திட்டமிடப்பட்டன</item>
- <item quantity="one">%1$d ரெக்கார்டிங் திட்டமிடப்பட்டது</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"இயக்கு"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"முதலிலிருந்து இயக்கு"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"மீண்டும் தொடங்கு"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"நீக்கு"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ரெக்கார்டிங்குகளை நீக்கு"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"மீண்டும்தொடங்கு"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"சீசன் <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"ஷெட்யூலை காட்டு"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"மேலும் படிக்க"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ரெக்கார்டிங்குகளை நீக்கு"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"நீக்க விரும்பும் எபிசோடுகளைத் தேர்ந்தெடுக்கவும். ஒருமுறை நீக்கிவிட்டால், அவற்றை மீட்டெடுக்க முடியாது."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"நீக்குவதற்கான ரெக்கார்டிங்குகள் இல்லை."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"பார்த்த எபிசோடுகளை தேர்ந்தெடு"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"எல்லாம் தேர்ந்தெடு"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"எல்லாம் தேர்வு நீக்கு"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> இல் <xliff:g id="WATCHED">%1$d</xliff:g> நிமிடங்கள் பார்த்துள்ளீர்கள்"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> இல் <xliff:g id="WATCHED">%1$d</xliff:g> வினாடிகள் பார்த்துள்ளீர்கள்"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"இதுவரை பார்க்காதவை"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%2$d இல் %1$d எபிசோடுகள் நீக்கப்பட்டன</item>
- <item quantity="one">%2$d இல் %1$d எபிசோடு நீக்கப்பட்டது</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"முன்னுரிமை"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"மிக அதிக முன்னுரிமை"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"மிகக்குறைந்த முன்னுரிமை"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"முன்னுரிமை: <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"சேனல்கள்"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"எந்தச் சேனலும்"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"முன்னுரிமையைத் தேர்வுசெய்க"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"ஒரே நேரத்தில் பல நிகழ்ச்சிகளை ரெக்கார்டு செய்ய வேண்டியிருந்தால், அதிக முன்னுரிமைகளைக் கொண்ட நிகழ்ச்சிகள் மட்டுமே ரெக்கார்டு செய்யப்படும்."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"சேமி"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ஒரே முறை ரெக்கார்டு செய்யக்கூடியவற்றுக்கு மிக அதிக முன்னுரிமை வழங்கு"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"ரத்துசெய்"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"ரத்துசெய்"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"நீக்கு"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"நிறுத்து"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ரெக்கார்டிங் ஷெட்யூலைக் காட்டு"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"இந்த நிகழ்ச்சியை மட்டும்"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"இப்போதிலிருந்து <xliff:g id="ENDTIME">%1$s</xliff:g> வரை"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"தொடர் முழுவதும்…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"பரவாயில்லை, திட்டமிடு"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"பதிலாக, இதை ரெக்கார்டு செய்"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"இந்த ரெக்கார்டிங்கை ரத்துசெய்"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"இப்போது காட்டு"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"ரெக்கார்டு செய்யக்கூடியது"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ரெக்கார்டிங் திட்டமிடப்பட்டது"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ரெக்கார்டிங்கில் முரண்பாடு"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ரெக்கார்ட் செய்யப்படுகிறது"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ரெக்கார்டு செய்ய முடியவில்லை"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"ரெக்கார்டிங் ஷெட்யூல்களை உருவாக்க, நிகழ்ச்சிகளைப் படிக்கிறது"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"நிகழ்ச்சிகளைப் படிக்கிறது"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVRக்கு அதிகச் சேமிப்பிடம் தேவை"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"நீங்கள் DVR மூலம் நிகழ்ச்சிகளைப் பதிவுசெய்ய முடியும். எனினும், DVR சரியாக வேலை செய்வதற்குத் தேவைப்படும் போதுமான சேமிப்பகம் இப்போது சாதனத்தில் இல்லை. <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>ஜி.பை. அல்லது அதற்கும் அதிகமான அளவில் உள்ள வெளிப்புற இயக்ககத்தை இணைக்கவும். பின் அதைச் சாதனச் சேமிப்பகமாகப் பயன்படுத்த, இந்தப் படிகளைப் பின்பற்றவும்."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"சேமிப்பகம் இல்லை"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR பயன்படுத்தும் சேமிப்பகம் இல்லை. DVRஐ மீண்டும் இயக்கும் முன், நீங்கள் பயன்படுத்தும் வெளிப்புற டிரைவை இணைக்கவும். மாற்றுவழியாக, சேமிப்பகத்தை இனி பயன்படுத்த மாட்டீர்கள் எனில், அதை நீக்கும்படியும் தேர்ந்தெடுக்கலாம்."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"சேமிப்பகத்தை நீக்கவா?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"பதிவுசெய்த உள்ளடக்கத்தையும் திட்ட அட்டவணைகளையும் இழப்பீர்கள்."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ரெக்கார்டு செய்வதை நிறுத்தவா?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ரெக்கார்டு செய்த உள்ளடக்கம் சேமிக்கப்படும்."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ரெக்கார்டிங் திட்டமிடப்பட்டது, ஆனால் முரண்பாடுகள் உள்ளன"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ரெக்கார்டு செய்வது தொடங்கப்பட்டது, ஆனால் முரண்பாடுகள் உள்ளன"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ரெக்கார்டு செய்யப்படும்."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ரெக்கார்டு செய்யப்படுகிறது."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> இன் சில பகுதிகள் ரெக்கார்டு செய்யப்படாது."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> ஆகியவற்றின் சில பகுதிகள் ரெக்கார்டு செய்யப்படாது."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> இன் சில பகுதிகளும், ரெக்கார்டு செய்யத் திட்டமிட்டிருந்த மேலும் ஒரு நிகழ்ச்சியும் ரெக்கார்டு செய்யப்படாது."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> ஆகியவற்றின் சில பகுதிகளும், ரெக்கார்டு செய்யத் திட்டமிட்டிருந்த மேலும் %3$d நிகழ்ச்சிகளும் ரெக்கார்டு செய்யப்படாது.</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> ஆகியவற்றின் சில பகுதிகளும், ரெக்கார்டு செய்யத் திட்டமிட்டிருந்த மேலும் %3$d நிகழ்ச்சியும் ரெக்கார்டு செய்யப்படாது.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"எதை ரெக்கார்டு செய்ய விரும்புகிறீர்கள்?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"எவ்வளவு நேரம் ரெக்கார்டு செய்ய விரும்புகிறீர்கள்?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ஏற்கனவே திட்டமிடப்பட்டுள்ளது"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>க்கு ரெக்கார்டு செய்வதற்காக இந்த நிகழ்ச்சி ஏற்கனவே திட்டமிடப்பட்டுள்ளது."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ஏற்கனவே ரெக்கார்டு செய்யப்பட்டது"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"இந்த நிகழ்ச்சி ஏற்கனவே ரெக்கார்டு செய்யப்பட்டது. மேலும் DVR நூலகத்தில் கிடைக்கும்."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"ரெக்கார்டு செய்த நிகழ்ச்சி இல்லை."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"தொடர்புடைய ரெக்கார்டிங்குகள்"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(நிகழ்ச்சி விளக்கம் இல்லை)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d ரெக்கார்டிங்குகள்</item>
- <item quantity="one">%1$d ரெக்கார்டிங்</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"ரெக்கார்டிங் திட்ட அட்டவணையிலிருந்து <xliff:g id="PROGRAMNAME">%1$s</xliff:g> அகற்றப்பட்டது"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ட்யூனர் இல்லாததால், பகுதியளவு ரெக்கார்டு செய்யப்படும்."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ட்யூனர் இல்லாததால், ரெக்கார்டு செய்யப்படாது."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ரெக்கார்டு செய்வதற்காக எதுவும் திட்டமிடப்படவில்லை.\nநிகழ்ச்சி வழிகாட்டிக்குச் சென்று, ரெக்கார்டிங்கைத் திட்டமிடலாம்."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d ரெக்கார்டிங் முரண்பாடுகள்</item>
- <item quantity="one">%1$d ரெக்கார்டிங் முரண்பாடு</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"தொடர் அமைப்புகள்"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"தொடர் ரெக்கார்டிங்கைத் தொடங்கு"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"தொடர் ரெக்கார்டிங்கை நிறுத்து"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"தொடர் ரெக்கார்டிங்கை நிறுத்தவா?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ரெக்கார்டு செய்யப்பட எபிசோடுகள் தொடர்ந்து DVR நூலகத்தில் இருக்கும்."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"நிறுத்து"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"எபிசோடுகள் இல்லை.\nஅவை கிடைக்கும் போது ரெக்கார்டு செய்யப்படும்."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d நிமிடங்கள்)</item>
- <item quantity="one">(%1$d நிமிடம்) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"இன்று"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"நாளை"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"நேற்று"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"இன்று <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"நாளை <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"ஸ்கோர்"</string>
-</resources>
diff --git a/res/values-te-v23/strings.xml b/res/values-te-rIN-v23/strings.xml
index ac59e7af..ac59e7af 100644
--- a/res/values-te-v23/strings.xml
+++ b/res/values-te-rIN-v23/strings.xml
diff --git a/res/values-te/arrays.xml b/res/values-te-rIN/arrays.xml
index de6abf32..de6abf32 100644
--- a/res/values-te/arrays.xml
+++ b/res/values-te-rIN/arrays.xml
diff --git a/res/values-te/rating_system_strings.xml b/res/values-te-rIN/rating_system_strings.xml
index 6179802b..6179802b 100644
--- a/res/values-te/rating_system_strings.xml
+++ b/res/values-te-rIN/rating_system_strings.xml
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
new file mode 100644
index 00000000..f6b8e538
--- /dev/null
+++ b/res/values-te-rIN/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"మోనో"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"స్టీరియో"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"ప్లే నియంత్రణలు"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"ఛానెల్‌లు"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"టీవీ ఎంపికలు"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"ఈ ఛానెల్ యొక్క ప్లే నియంత్రణలు అందుబాటులో లేవు"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ప్లే చేస్తుంది లేదా పాజ్ చేస్తుంది"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ఫాస్ట్ ఫార్వార్డ్ చేస్తుంది"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"రివైండ్ చేస్తుంది"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"తదుపరి"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"మునుపటి"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"ప్రోగ్రామ్ గైడ్"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"కొత్త ఛానె. ఉన్నప్పుడు"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g>ని తెరువు"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"సంవృత శీర్షికలు"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"ప్రదర్శన మోడ్"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"బహుళ-ఆడియో"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"మరిన్ని ఛానెల్‌లను పొందండి"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"సెట్టింగ్‌లు"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"టీవీ (యాంటెన్నా/కేబుల్)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"కార్యక్రమ సమాచారం లేదు"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"సమాచారం లేదు"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"బ్లాక్ చేసిన ఛానెల్"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"భాష తెలియదు"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"ఉపశీర్షికలు %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"సంవృత శీర్షికలు"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ఆఫ్ చేయి"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"ఆకృతీకరణను అనుకూలీకరించు"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"సంవృత శీర్షికల కోసం సిస్టమ్-వ్యాప్త ప్రాధాన్యతలను సెట్ చేయి"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ప్రదర్శన మోడ్"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"బహుళ-ఆడియో"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"మోనో"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"స్టీరియో"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 సరౌండ్"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 సరౌండ్"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ఛానెల్‌లు"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ఛానెల్‌ జాబితా అనుకూలీ."</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"సమూహాన్ని ఎంచుకోండి"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"సమూహం ఎంపిక తీసివేయి"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ఈ ప్రకారం సమూహం చేయి"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ఛానెల్ మూలం"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"ఈ ప్రకారం సమూహం చేయి"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"ఈ కార్యక్రమం బ్లాక్ చేయబడింది"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"ఈ కార్యక్రమం రేట్ చేయబడలేదు"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"ఈ కార్యక్రమం <xliff:g id="RATING">%1$s</xliff:g> అని రేట్ చేయబడింది"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"స్వయంచాలకంగా స్కాన్ చేయడానికి ఇన్‌పుట్ మద్దతు ఇవ్వలేదు"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' కోసం ఆటో-స్కాన్‌ని ప్రారంభించడం సాధ్యపడలేదు"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"సంవృత శీర్షికల కోసం సిస్టమ్-వ్యాప్త ప్రాధాన్యతలను ప్రారంభించడం సాధ్యపడలేదు."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d ఛానెల్‌లు జోడించబడ్డాయి</item>
+ <item quantity="one">%1$d ఛానెల్ జోడించబడింది</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"ఛానెల్‌లు జోడించబడలేదు"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"తల్లిదండ్రుల నియంత్రణలు"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ఆన్ చేయి"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ఆఫ్ చేయి"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"ఛానె. బ్లాక్ చేయబ."</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"అన్నీ బ్లాక్ చేయి"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"అన్నీ అన్‌బ్లాక్ చే."</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"దాచబడిన ఛానెల్‌లు"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"ప్రోగ్రామ్ పరిమితులు"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"పిన్‌ను మార్చు"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"రేటింగ్ సిస్టమ్‌లు"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"రేటింగ్‌లు"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"అన్ని రేటింగ్ సిస్టమ్‌లను చూడండి"</string>
+ <string name="other_countries" msgid="8342216398676184749">"ఇతర దేశాలు"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"ఏదీ లేదు"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ఏదీ లేదు"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"రేట్ చేయనిది"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"రేట్ చేయని కార్యక్రమాలను బ్లాక్ చేయండి"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"ఏదీ లేదు"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"అధిక పరిమితులు"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"మధ్యస్థ పరిమితులు"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"తక్కువ పరిమితులు"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"అనుకూలం"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"కంటెంట్ పిల్లలకు తగినది"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"కంటెంట్ యుక్తవయస్సు పిల్లలకు తగినది"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"కంటెంట్ టీనేజ్ వాళ్లకు తగినది"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"మాన్యువల్ పరిమితులు"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s, సబ్-రేటింగ్‌లు"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"సబ్-రేటింగ్‌లు"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ఈ ఛానెల్‌ని చూడటానికి మీ పిన్‌ని నమోదు చేయండి"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"ఈ కార్యక్రమాన్ని చూడటానికి మీ పిన్‌ని నమోదు చేయండి"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ఈ కార్యక్రమానికి <xliff:g id="RATING">%1$s</xliff:g> అని రేట్ చేయబడింది. ఈ కార్యక్రమాన్ని చూడటానికి మీ PINని నమోదు చేయండి"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"ఈ కార్యక్రమం రేట్ చేయబడలేదు. ఈ కార్యక్రమాన్ని చూడటానికి మీ PINని నమోదు చేయండి"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"మీ పిన్‌ని నమోదు చేయండి"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"తల్లిదండ్రుల నియంత్రణలను సెట్ చేయడానికి, పిన్‌ని సృష్టించండి"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"కొత్త పిన్‌ని నమోదు చేయండి"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"మీ పిన్‌ను నిర్ధారించండి"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"మీ ప్రస్తుత పిన్‌ని నమోదు చేయండి"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">మీరు 5 సార్లు తప్పు PIN నమోదు చేసారు.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> సెకన్లు ఆగి, ఆ తర్వాత మళ్లీ ప్రయత్నించండి.</item>
+ <item quantity="one">మీరు 5 సార్లు తప్పు PIN నమోదు చేసారు.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> సెకను ఆగి, ఆ తర్వాత మళ్లీ ప్రయత్నించండి.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"ఆ పిన్ తప్పు. మళ్లీ ప్రయత్నించండి."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"మళ్లీ ప్రయత్నించండి, పిన్ సరిపోలలేదు"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"మీ జిప్ కోడ్‌ను నమోదు చేయండి."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"ప్రత్యక్ష ప్రసార ఛానెల్‌ల అనువర్తనం టీవీ ఛానెల్‌లకి సంబంధించిన పూర్తి ప్రోగ్రామ్ గైడ్‌ను అందించడానికి జిప్ కోడ్‌ను ఉపయోగిస్తుంది."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"మీ జిప్ కోడ్‌ను నమోదు చేయండి"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"జిప్ కోడ్ చెల్లదు"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"సెట్టింగ్‌లు"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ఛానెల్‌ జాబితా అనుకూలీకరించండి"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"మీ ప్రోగ్రామ్ గైడ్ కోసం ఛానెల్‌లను ఎంచుకోండి"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ఛానెల్ సోర్స్‌లు"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"కొత్త ఛానెల్‌లు అందుబాటులో ఉన్నాయి"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"తల్లిదండ్రుల నియంత్రణలు"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"టైమ్‌షిఫ్ట్"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"ప్రత్యక్ష ప్రసార కార్యక్రమాలను చూస్తున్నప్పుడు రికార్డ్ కూడా చేయండి, ఇలా చేయడం ద్వారా మీరు కోరుకున్నప్పుడు వాటిని పాజ్ లేదా రివైండ్ చేయవచ్చు.\nహెచ్చరిక: ఇది నిల్వను అధికంగా ఉపయోగించడం ద్వారా అంతర్గత నిల్వ జీవితకాలాన్ని తగ్గించవచ్చు."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"ఓపెన్ సోర్స్ లైసెన్స్‌లు"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"అభిప్రాయాన్ని పంపు"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"సంస్కరణ"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"ఈ ఛానెల్‌ను చూడటానికి, కుడివైపు బటన్ నొక్కి, మీ పిన్‌ని నమోదు చేయండి"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"ఈ ప్రోగ్రామ్‌ని చూడటానికి, కుడివైపు బటన్ నొక్కి, మీ పిన్‌ని నమోదు చేయండి"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"ఈ కార్యక్రమం రేట్ చేయబడలేదు.\nఈ కార్యక్రమాన్ని చూడటానికి, కుడి వైపున నొక్కి, మీ PINని నమోదు చేయండి"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"ఈ కార్యక్రమం <xliff:g id="RATING">%1$s</xliff:g> అని రేట్ చేయబడింది.\nఈ కార్యక్రమాన్ని చూడటానికి, కుడివైపు బటన్ నొక్కి, మీ PINని నమోదు చేయండి."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ఈ ఛానెల్‌ను చూడటానికి, డిఫాల్ట్ లైవ్ టీవీ అనువర్తనాన్ని ఉపయోగించండి."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ఈ కార్యక్రమాన్ని చూడటానికి, డిఫాల్ట్ లైవ్ టీవీ అనువర్తనాన్ని ఉపయోగించండి."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"ఈ కార్యక్రమం రేట్ చేయబడలేదు.\nఈ కార్యక్రమాన్ని చూడటానికి, డిఫాల్ట్ ప్రత్యక్ష TV అప్లికేషన్‌ను ఉపయోగించండి."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ఈ కార్యక్రమానికి <xliff:g id="RATING">%1$s</xliff:g> అని రేట్ చేయబడింది.\nఈ కార్యక్రమాన్ని చూడటానికి, డిఫాల్ట్ లైవ్ టీవీ అనువర్తనాన్ని ఉపయోగించండి."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"కార్యక్రమం బ్లాక్ చేయబడింది"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"ఈ కార్యక్రమం రేట్ చేయబడలేదు"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ఈ కార్యక్రమం <xliff:g id="RATING">%1$s</xliff:g> అని రేట్ చేయబడింది"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ఆడియో మాత్రమే"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"సిగ్నల్ బలహీనంగా ఉంది"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ఇంటర్నెట్ కనెక్షన్ లేదు"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">ఇతర ఛానెల్‌లు రికార్డ్ అవుతున్నందున ఈ ఛానెల్‌ని <xliff:g id="END_TIME_1">%1$s</xliff:g> వరకు ప్లే చేయలేరు. \n\nరికార్డింగ్ షెడ్యూల్‌ను సర్దుబాటు చేయడానికి కుడివైపు నొక్కండి.</item>
+ <item quantity="one">మరొక ఛానెల్ రికార్డ్ అవుతున్నందున ఈ ఛానెల్‌ని <xliff:g id="END_TIME_0">%1$s</xliff:g> వరకు ప్లే చేయలేరు. \n\nరికార్డింగ్ షెడ్యూల్‌ను సర్దుబాటు చేయడానికి కుడివైపు నొక్కండి.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"శీర్షిక లేదు"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ఛానెల్ బ్లాక్ చేయబడింది"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"కొత్తవి"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"మూలాలు"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d ఛానెల్‌లు</item>
+ <item quantity="one">%1$d ఛానెల్</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"ఛానెల్‌లు ఏవీ అందుబాటులో లేవు"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"కొత్తవి"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"సెటప్ చేయలేదు"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"మరిన్ని మూలాధారాలను పొందండి"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"ప్రత్యక్ష ప్రసార ఛానెల్‌లను అందించే అనువర్తనాలను బ్రౌజ్ చేయండి"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"కొత్త ఛానెల్ మూలాలు అందుబాటులో ఉన్నాయి"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"కొత్త ఛానెల్ మూలాలు అందించడానికి ఛానెల్‌లను కలిగి ఉన్నాయి.\nవాటిని ఇప్పుడే సెటప్ చేయండి లేదా ఛానెల్ మూలాల సెట్టింగ్‌లో దీన్ని తర్వాత చేయండి."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"ఇప్పుడే సెటప్ చేయి"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"సరే, అర్థమైంది"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"టీవీ మెనుని ప్రాప్యత చేయడానికి "<b>"ఎంచుకోండి నొక్కండి"</b>"."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"టీవీ ఇన్‌పుట్ కనుగొనబడలేదు"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"టీవీ ఇన్‌పుట్‌ను కనుగొనడం సాధ్యపడదు"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ట్యూనర్ రకం తగినది కాదు. దయచేసి ట్యూనర్ రకం టీవీ ఇన్‌పుట్ కోసం లైవ్ ఛానెల్‌లు అనువర్తనాన్ని ప్రారంభించండి."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ట్యూన్ విఫలమైంది"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"ఈ చర్యను నిర్వహించడానికి అనువర్తనం ఏదీ కనుగొనబడలేదు."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"అన్ని మూల ఛానెల్‌లు దాచబడ్డాయి.\nచూడటానికి కనీసం ఒక ఛానెల్‌ను ఎంచుకోండి."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"వీడియో ఊహించని విధంగా అందుబాటులో లేకుండా పోయింది"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"BACK కీ కనెక్ట్ చేయబడిన పరికరం కోసం ఉద్దేశించినది. నిష్క్రమించడానికి HOME బటన్‌ను నొక్కండి."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"టీవీ జాబితాలను చదవడానికి ప్రత్యక్ష ప్రసార ఛానెల్‌లకు అనుమతి అవసరం."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"మీ మూలాధారాలను సెటప్ చేయండి"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"ప్రత్యక్ష ప్రసార ఛానెల్‌లు అనువర్తనాల ద్వారా అందించబడే ప్రసార ఛానెల్‌ల్లో సాంప్రదాయక టీవీ ఛానెల్‌ల అనుభూతి కలగలిపి అందించబడతాయి. \n\nఇప్పటికే ఇన్‌స్టాల్ చేసుకున్న ఛానెల్ మూలాధారాలను సెటప్ చేయడం ద్వారా ప్రారంభించండి. లేదా ప్రత్యక్ష ప్రసార ఛానెల్‌లను ఆఫర్ చేసే మరిన్ని అనువర్తనాల కోసం Google Play స్టోర్‌లో బ్రౌజ్ చేయండి."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"రికార్డింగ్‌లు &amp; షెడ్యూల్‌లు"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 నిమిషాలు"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 నిమిషాలు"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 గంట"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 గంటలు"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"ఇటీవలివి"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"షెడ్యూల్ చేసినవి"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"సిరీస్"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"ఇతరం"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ఛానెల్‌ను రికార్డ్ చేయడం సాధ్యపడదు."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"కార్యక్రమాన్ని రికార్డ్ చేయడం సాధ్యపడదు."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> రికార్డ్ చేయడం కోసం షెడ్యూల్ చేయబడింది"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ఇప్పటి నుండి <xliff:g id="ENDTIME">%2$s</xliff:g> వరకు <xliff:g id="PROGRAMNAME">%1$s</xliff:g> రికార్డ్ చేస్తుంది"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"పూర్తి షెడ్యూల్"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">తదుపరి %1$d రోజులు</item>
+ <item quantity="one">తదుపరి %1$d రోజు</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d నిమిషాలు</item>
+ <item quantity="one">%1$d నిమిషం</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d కొత్త రికార్డింగ్‌లు</item>
+ <item quantity="one">%1$d కొత్త రికార్డింగ్</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d రికార్డింగ్‌లు</item>
+ <item quantity="one">%1$d రికార్డింగ్</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d రికార్డింగ్‌లు చేయాలి</item>
+ <item quantity="one">%1$d రికార్డింగ్ చేయాలి</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"రికార్డింగ్‌ను రద్దు చేయి"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"రికార్డింగ్‌ను ఆపివేయి"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"చూడండి"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"మొదటి నుండి ప్లే చేయి"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"ప్లే చేయడం కొనసాగించు"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"తొలగించు"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"రికార్డింగ్‌లను తొలగించు"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"పునఃప్రారంభించు"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"సీజన్ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"షెడ్యూల్ చూడండి"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"మరింత చదవండి"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"రికార్డింగ్‌లు తొలగించు"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"మీరు తొలగించాలనుకునే ఎపిసోడ్‌లను ఎంచుకోండి. వీటిని ఒకసారి తొలగించాక తిరిగి పునరుద్ధరించలేరు."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"తొలగించడానికి రికార్డింగ్‌లు ఏవీ లేవు."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"చూసిన ఎపిసోడ్‌లను ఎంచుకోండి"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"అన్ని ఎపిసోడ్‌లను ఎంచుకోండి"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"అన్ని ఎపిసోడ్‌ల ఎంపిక తీసివేయి"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> నిమిషాల్లో <xliff:g id="WATCHED">%1$d</xliff:g> సమయం చూసారు"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> సెకన్లలో <xliff:g id="WATCHED">%1$d</xliff:g> సమయం చూసారు"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"ఎప్పుడూ చూడలేదు"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%2$dలో %1$d ఎపిసోడ్‌లు తొలగించబడ్డాయి</item>
+ <item quantity="one">%2$dలో %1$d ఎపిసోడ్ తొలగించబడింది</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ప్రాధాన్యత"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"అత్యధికం"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"అతి తక్కువ"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"వద్దు. <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ఛానెల్‌లు"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ఏదైనా"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"ప్రాధాన్యతను ఎంచుకోండి"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"ఒకే సమయంలో చాలా ఎక్కువ కార్యక్రమాలు రికార్డ్ చేయాల్సినప్పుడు, అధిక ప్రాధాన్యతలు గలవి మాత్రమే రికార్డ్ చేయబడతాయి."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"సేవ్ చేయి"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ఒక పర్యాయ రికార్డింగ్‌లు అత్యధిక ప్రాధాన్యతను కలిగి ఉంటాయి"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"ఆపివేయి"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"రికార్డింగ్ షెడ్యూల్ చూడండి"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"ఈ ఒక్క కార్యక్రమం"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ఇప్పటి నుండి - <xliff:g id="ENDTIME">%1$s</xliff:g> వరకు"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"మొత్తం సిరీస్…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"ఏదేమైనా షెడ్యూల్ చేయి"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"బదులుగా దీన్ని రికార్డ్ చేయి"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ఈ రికార్డింగ్‌ను రద్దు చేయి"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"ఇప్పుడే చూడండి"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"రికార్డింగ్‌లను తొలగించు…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"రికార్డ్ చేయవచ్చు"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"రికార్డింగ్ షెడ్యూల్ చేయబడింది"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"రికార్డింగ్ వైరుధ్యం"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"రికార్డ్ అవుతోంది"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"రికార్డింగ్ విఫలమైంది"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"కార్యక్రమాలను చదువుతోంది"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"ఇటీవలి రికార్డింగ్‌లను వీక్షించండి"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> రికార్డింగ్ అసంపూర్ణంగా ఉంది."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> మరియు <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> రికార్డింగ్‌లు అసంపూర్ణంగా ఉన్నాయి."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> మరియు <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> రికార్డింగ్‌లు అసంపూర్ణంగా ఉన్నాయి."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"తగినంత నిల్వ లేని కారణంగా, <xliff:g id="PROGRAMNAME">%1$s</xliff:g> రికార్డింగ్ పూర్తి కాలేదు."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"తగినంత నిల్వ లేని కారణంగా, <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> మరియు <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> రికార్డింగ్‌లు పూర్తి కాలేదు."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"తగినంత నిల్వ లేని కారణంగా, <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> మరియు <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> రికార్డింగ్‌లు పూర్తి కాలేదు."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVRకు మరింత నిల్వ అవసరం"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"మీరు DVRతో కార్యక్రమాలను రికార్డ్ చేయగలుగుతారు. అయితే, ప్రస్తుతం DVR పని చేయడానికి మీ పరికరంలో తగినంత నిల్వ ఖాళీ లేదు. దయచేసి <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB లేదా అంతకంటే ఎక్కువ ఖాళీ స్థలం గల బయటి డ్రైవ్‌ను కనెక్ట్ చేసి, ఆపై దాన్ని పరికర నిల్వగా ఫార్మాట్ చేయడానికి సూచనలను అనుసరించండి."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"తగినంత నిల్వ లేదు"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"తగినంత నిల్వ లేనందున ఈ కార్యక్రమం రికార్డ్ చేయబడదు. ఇప్పటికే ఉన్న కొన్ని రికార్డింగ్‌లను తొలగించడానికి ప్రయత్నించండి."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"నిల్వ కనిపించడం లేదు"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"రికార్డింగ్ ఆపివేయాలా?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"రికార్డ్ అయిన కంటెంట్ సేవ్ చేయబడుతుంది."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> యొక్క రికార్డింగ్‌కి ఈ కార్యక్రమంతో వైరుధ్యం తలెత్తినందున అది ఆపివేయబడుతుంది. రికార్డ్ చేసిన కంటెంట్ సేవ్ చేయబడుతుంది."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"రికార్డింగ్ షెడ్యూల్ చేయబడింది కానీ మిగిలిన వాటితో వైరుధ్యాలను కలిగి ఉంది"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"రికార్డింగ్ ప్రారంభమైంది, కానీ వైరుధ్యాలను కలిగి ఉంది"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> రికార్డ్ చేయబడుతుంది."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> రికార్డ్ అవుతోంది."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g>లో కొన్ని భాగాలు రికార్డ్ చేయబడవు."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> మరియు <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>లో కొన్ని భాగాలు రికార్డ్ చేయబడవు."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>లో కొన్ని భాగాలు మరియు మరొక షెడ్యూల్ రికార్డ్ చేయబడవు."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g>లో కొన్ని భాగాలు మరియు మరో %3$d షెడ్యూల్‌లు రికార్డ్ చేయబడవు.</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g>లో కొన్ని భాగాలు మరియు మరో %3$d షెడ్యూల్ రికార్డ్ చేయబడవు.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"మీరు ఏమి రికార్డ్ చేయాలనుకుంటున్నారు?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"మీరు ఎంత సమయం రికార్డ్ చేయాలనుకుంటున్నారు?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ఇప్పటికే షెడ్యూల్ చేయబడింది"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"ఇదే కార్యక్రమం ఇప్పటికే <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>కి రికార్డ్ చేయడానికి షెడ్యూల్ చేయబడింది."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ఇప్పటికే రికార్డ్ అయింది"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ఈ ప్రోగ్రామ్ ఇప్పటికే రికార్డ్ అయింది. ఇది DVR లైబ్రరీలో అందుబాటులో ఉంది."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"సిరీస్ రికార్డింగ్ షెడ్యూల్ చేయబడింది"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g>కి <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> రికార్డింగ్‌లు షెడ్యూల్ చేయబడ్డాయి.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g>కి <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> రికార్డింగ్ షెడ్యూల్ చేయబడింది.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g>కి <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> రికార్డింగ్‌లు షెడ్యూల్ చేయబడ్డాయి. వైరుధ్యాల కారణంగా వాటిలో <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> రికార్డ్ చేయబడవు.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g>కి <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> రికార్డింగ్ షెడ్యూల్ చేయబడింది. వైరుధ్యాల కారణంగా ఇది రికార్డ్ చేయబడదు.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g>కి <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> రికార్డింగ్‌లు షెడ్యూల్ చేయబడ్డాయి. వైరుధ్యాల కారణంగా ఈ సిరీస్ మరియు మరో సిరీస్‌లోని <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ఎపిసోడ్‌లు రికార్డ్ చేయబడవు.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g>కి <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> రికార్డింగ్ షెడ్యూల్ చేయబడింది. వైరుధ్యాల కారణంగా ఈ సిరీస్ మరియు మరో సిరీస్‌లోని <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ఎపిసోడ్‌లు రికార్డ్ చేయబడవు.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g>కి <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> రికార్డింగ్‌లు షెడ్యూల్ చేయబడ్డాయి. వైరుధ్యాల కారణంగా మరో సిరీస్‌లోని 1 ఎపిసోడ్ రికార్డ్ చేయబడదు.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g>కి <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> రికార్డింగ్ షెడ్యూల్ చేయబడింది. వైరుధ్యాల కారణంగా మరో సిరీస్‌లోని 1 ఎపిసోడ్ రికార్డ్ చేయబడదు.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g>కి <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> రికార్డింగ్‌లు షెడ్యూల్ చేయబడ్డాయి. వైరుధ్యాల కారణంగా మరో సిరీస్‌లోని <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ఎపిసోడ్‌లు రికార్డ్ చేయబడవు.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g>కి <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> రికార్డింగ్ షెడ్యూల్ చేయబడింది. వైరుధ్యాల కారణంగా మరో సిరీస్‌లోని <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ఎపిసోడ్‌లు రికార్డ్ చేయబడవు.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"రికార్డ్ చేసిన కార్యక్రమం కనుగొనబడలేదు."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"సంబంధిత రికార్డింగ్‌లు"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d రికార్డింగ్‌లు</item>
+ <item quantity="one">%1$d రికార్డింగ్</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> రికార్డింగ్ షెడ్యూల్ నుండి తీసివేయబడింది"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ట్యూనర్ వైరుధ్యాల కారణంగా పాక్షికంగా రికార్డ్ చేయబడుతుంది."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ట్యూనర్ వైరుధ్యాల కారణంగా రికార్డ్ చేయబడదు."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ఇంకా షెడ్యూల్ చేసిన రికార్డింగ్‌లు ఏవీ లేవు.\nమీరు కార్యక్రమాల గైడ్ నుండి రికార్డింగ్‌ను షెడ్యూల్ చేయవచ్చు."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d రికార్డింగ్ వైరుధ్యాలు ఉన్నాయి</item>
+ <item quantity="one">%1$d రికార్డింగ్ వైరుధ్యం ఉంది</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"సిరీస్ సెట్టింగ్‌లు"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"సిరీస్ రికార్డింగ్ ఆరంభించు"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"సిరీస్ రికార్డింగ్ ఆపివేయి"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"సిరీస్ రికార్డింగ్‌ను ఆపివేయాలా?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"రికార్డ్ అయిన ఎపిసోడ్‌లు DVR లైబ్రరీలో అలాగే అందుబాటులో ఉంటాయి."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"ఆపివేయి"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ప్రస్తుతం ఎపిసోడ్‌లు ఏవీ ప్రసారంలో లేవు."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ఎపిసోడ్‌లు ఏవీ అందుబాటులో లేవు.\nఇవి అందుబాటులోకి వచ్చిన వెంటనే రికార్డ్ చేయబడతాయి."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d నిమిషాలు)</item>
+ <item quantity="one">(%1$d నిమిషం) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"ఈ రోజు"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"రేపు"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"నిన్న"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ఈ రోజు"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> రేపు"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"స్కోర్"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"రికార్డ్ చేసిన కార్యక్రమాలు"</string>
+</resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
deleted file mode 100644
index 274be2ce..00000000
--- a/res/values-te/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"మోనో"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"స్టీరియో"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"ప్లే నియంత్రణలు"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"ఇటీవలి ఛానెళ్లు"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"టీవీ ఎంపికలు"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP ఎంపికలు"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"ఈ ఛానెల్ యొక్క ప్లే నియంత్రణలు అందుబాటులో లేవు"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"ప్లే చేస్తుంది లేదా పాజ్ చేస్తుంది"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"ఫాస్ట్ ఫార్వార్డ్ చేస్తుంది"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"రివైండ్ చేస్తుంది"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"తదుపరి"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"మునుపటి"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"ప్రోగ్రామ్ గైడ్"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"కొత్త ఛానె. ఉన్నప్పుడు"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g>ని తెరువు"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"సంవృత శీర్షికలు"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"ప్రదర్శన మోడ్"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"ఆన్‌లో ఉంది"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"ఆఫ్‌లో ఉంది"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"బహుళ-ఆడియో"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"మరిన్ని ఛానెల్‌లను పొందండి"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"సెట్టింగ్‌లు"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"మూలం"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"మార్చు"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"ఆన్‌లో ఉంది"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"ఆఫ్‌లో ఉంది"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"ధ్వని"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"ప్రధానమైనది"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP విండో"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"లేఅవుట్"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"దిగువ కుడివైపు"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"ఎగువ కుడివైపు"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"ఎగువ ఎడమవైపు"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"దిగువ ఎడమవైపు"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"పక్కపక్కన"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"పరిమాణం"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"పెద్దది"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"చిన్నది"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"ఇన్‌పుట్ మూలం"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"టీవీ (యాంటెన్నా/కేబుల్)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"కార్యక్రమ సమాచారం లేదు"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"సమాచారం లేదు"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"బ్లాక్ చేసిన ఛానెల్"</string>
- <string name="default_language" msgid="4122326459624337928">"భాష తెలియదు"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"సంవృత శీర్షికలు"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"ఆఫ్ చేయి"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"ఆకృతీకరణను అనుకూలీకరించు"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"సంవృత శీర్షికల కోసం సిస్టమ్-వ్యాప్త ప్రాధాన్యతలను సెట్ చేయి"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ప్రదర్శన మోడ్"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"బహుళ-ఆడియో"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"మోనో"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"స్టీరియో"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 సరౌండ్"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 సరౌండ్"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ఛానెల్‌లు"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"ఛానెల్‌ జాబితా అనుకూలీ."</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"సమూహాన్ని ఎంచుకోండి"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"సమూహం ఎంపిక తీసివేయి"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"ఈ ప్రకారం సమూహం చేయి"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"ఛానెల్ మూలం"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"ఈ ప్రకారం సమూహం చేయి"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"ఈ కార్యక్రమం బ్లాక్ చేయబడింది"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"ఈ కార్యక్రమం <xliff:g id="RATING">%1$s</xliff:g> అని రేట్ చేయబడింది"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"స్వయంచాలకంగా స్కాన్ చేయడానికి ఇన్‌పుట్ మద్దతు ఇవ్వలేదు"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' కోసం ఆటో-స్కాన్‌ని ప్రారంభించడం సాధ్యపడలేదు"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"సంవృత శీర్షికల కోసం సిస్టమ్-వ్యాప్త ప్రాధాన్యతలను ప్రారంభించడం సాధ్యపడలేదు."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d ఛానెల్‌లు జోడించబడ్డాయి</item>
- <item quantity="one">%1$d ఛానెల్ జోడించబడింది</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"ఛానెల్‌లు జోడించబడలేదు"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ట్యూనర్"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"తల్లిదండ్రుల నియంత్రణలు"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"ఆన్ చేయి"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ఆఫ్ చేయి"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"ఛానె. బ్లాక్ చేయబ."</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"అన్నీ బ్లాక్ చేయి"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"అన్నీ అన్‌బ్లాక్ చే."</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"దాచబడిన ఛానెల్‌లు"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"ప్రోగ్రామ్ పరిమితులు"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"పిన్‌ను మార్చు"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"రేటింగ్ సిస్టమ్‌లు"</string>
- <string name="option_ratings" msgid="4009116954188688616">"రేటింగ్‌లు"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"అన్ని రేటింగ్ సిస్టమ్‌లను చూడండి"</string>
- <string name="other_countries" msgid="8342216398676184749">"ఇతర దేశాలు"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"ఏదీ లేదు"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ఏదీ లేదు"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"ఏదీ లేదు"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"అధిక పరిమితులు"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"మధ్యస్థ పరిమితులు"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"తక్కువ పరిమితులు"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"అనుకూలం"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"కంటెంట్ పిల్లలకు తగినది"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"కంటెంట్ యుక్తవయస్సు పిల్లలకు తగినది"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"కంటెంట్ టీనేజ్ వాళ్లకు తగినది"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"మాన్యువల్ పరిమితులు"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s, సబ్-రేటింగ్‌లు"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"సబ్-రేటింగ్‌లు"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ఈ ఛానెల్‌ని చూడటానికి మీ పిన్‌ని నమోదు చేయండి"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"ఈ కార్యక్రమాన్ని చూడటానికి మీ పిన్‌ని నమోదు చేయండి"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"ఈ కార్యక్రమానికి <xliff:g id="RATING">%1$s</xliff:g> అని రేట్ చేయబడింది. ఈ కార్యక్రమాన్ని చూడటానికి మీ PINని నమోదు చేయండి"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"మీ పిన్‌ని నమోదు చేయండి"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"తల్లిదండ్రుల నియంత్రణలను సెట్ చేయడానికి, పిన్‌ని సృష్టించండి"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"కొత్త పిన్‌ని నమోదు చేయండి"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"మీ పిన్‌ను నిర్ధారించండి"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"మీ ప్రస్తుత పిన్‌ని నమోదు చేయండి"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">మీరు 5 సార్లు తప్పు PIN నమోదు చేసారు.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> సెకన్లు ఆగి, ఆ తర్వాత మళ్లీ ప్రయత్నించండి.</item>
- <item quantity="one">మీరు 5 సార్లు తప్పు PIN నమోదు చేసారు.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> సెకను ఆగి, ఆ తర్వాత మళ్లీ ప్రయత్నించండి.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"ఆ పిన్ తప్పు. మళ్లీ ప్రయత్నించండి."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"మళ్లీ ప్రయత్నించండి, పిన్ సరిపోలలేదు"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"సెట్టింగ్‌లు"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"ఛానెల్‌ జాబితా అనుకూలీకరించండి"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"మీ ప్రోగ్రామ్ గైడ్ కోసం ఛానెల్‌లను ఎంచుకోండి"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"ఛానెల్ సోర్స్‌లు"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"కొత్త ఛానెల్‌లు అందుబాటులో ఉన్నాయి"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"తల్లిదండ్రుల నియంత్రణలు"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"ఓపెన్ సోర్స్ లైసెన్స్‌లు"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"ఓపెన్ సోర్స్ లైసెన్స్‌లు"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"సంస్కరణ"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"ఈ ఛానెల్‌ను చూడటానికి, కుడివైపు బటన్ నొక్కి, మీ పిన్‌ని నమోదు చేయండి"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"ఈ ప్రోగ్రామ్‌ని చూడటానికి, కుడివైపు బటన్ నొక్కి, మీ పిన్‌ని నమోదు చేయండి"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"ఈ కార్యక్రమం <xliff:g id="RATING">%1$s</xliff:g> అని రేట్ చేయబడింది.\nఈ కార్యక్రమాన్ని చూడటానికి, కుడివైపు బటన్ నొక్కి, మీ PINని నమోదు చేయండి."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"ఈ ఛానెల్‌ను చూడటానికి, డిఫాల్ట్ లైవ్ టీవీ అనువర్తనాన్ని ఉపయోగించండి."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"ఈ కార్యక్రమాన్ని చూడటానికి, డిఫాల్ట్ లైవ్ టీవీ అనువర్తనాన్ని ఉపయోగించండి."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"ఈ కార్యక్రమానికి <xliff:g id="RATING">%1$s</xliff:g> అని రేట్ చేయబడింది.\nఈ కార్యక్రమాన్ని చూడటానికి, డిఫాల్ట్ లైవ్ టీవీ అనువర్తనాన్ని ఉపయోగించండి."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"కార్యక్రమం బ్లాక్ చేయబడింది"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"ఈ కార్యక్రమం <xliff:g id="RATING">%1$s</xliff:g> అని రేట్ చేయబడింది"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"ఆడియో మాత్రమే"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"సిగ్నల్ బలహీనంగా ఉంది"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"ఇంటర్నెట్ కనెక్షన్ లేదు"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">ఇతర ఛానెల్‌లు రికార్డ్ అవుతున్నందున ఈ ఛానెల్‌ని <xliff:g id="END_TIME_1">%1$s</xliff:g> వరకు ప్లే చేయలేరు. \n\nరికార్డింగ్ షెడ్యూల్‌ను సర్దుబాటు చేయడానికి కుడివైపు నొక్కండి.</item>
- <item quantity="one">మరొక ఛానెల్ రికార్డ్ అవుతున్నందున ఈ ఛానెల్‌ని <xliff:g id="END_TIME_0">%1$s</xliff:g> వరకు ప్లే చేయలేరు. \n\nరికార్డింగ్ షెడ్యూల్‌ను సర్దుబాటు చేయడానికి కుడివైపు నొక్కండి.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"శీర్షిక లేదు"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"ఛానెల్ బ్లాక్ చేయబడింది"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"కొత్తవి"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"మూలాలు"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d ఛానెల్‌లు</item>
- <item quantity="one">%1$d ఛానెల్</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"ఛానెల్‌లు ఏవీ అందుబాటులో లేవు"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"కొత్తవి"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"సెటప్ చేయలేదు"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"మరిన్ని మూలాధారాలను పొందండి"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"ప్రత్యక్ష ప్రసార ఛానెల్‌లను అందించే అనువర్తనాలను బ్రౌజ్ చేయండి"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"కొత్త ఛానెల్ మూలాలు అందుబాటులో ఉన్నాయి"</string>
- <string name="new_sources_description" msgid="749649005588426813">"కొత్త ఛానెల్ మూలాలు అందించడానికి ఛానెల్‌లను కలిగి ఉన్నాయి.\nవాటిని ఇప్పుడే సెటప్ చేయండి లేదా ఛానెల్ మూలాల సెట్టింగ్‌లో దీన్ని తర్వాత చేయండి."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"ఇప్పుడే సెటప్ చేయి"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"సరే, అర్థమైంది"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"టీవీ మెనుని ప్రాప్యత చేయడానికి "<b>"ఎంచుకోండి నొక్కండి"</b>"."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"టీవీ ఇన్‌పుట్ కనుగొనబడలేదు"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"టీవీ ఇన్‌పుట్‌ను కనుగొనడం సాధ్యపడదు"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIPకి మద్దతు లేదు"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIPతో చూపబడే ఇన్‌పుట్ ఏదీ అందుబాటులో లేదు"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"ట్యూనర్ రకం తగినది కాదు. దయచేసి ట్యూనర్ రకం టీవీ ఇన్‌పుట్ కోసం లైవ్ ఛానెల్‌లు అనువర్తనాన్ని ప్రారంభించండి."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"ట్యూన్ విఫలమైంది"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"ఈ చర్యను నిర్వహించడానికి అనువర్తనం ఏదీ కనుగొనబడలేదు."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"అన్ని మూల ఛానెల్‌లు దాచబడ్డాయి.\nచూడటానికి కనీసం ఒక ఛానెల్‌ను ఎంచుకోండి."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"వీడియో ఊహించని విధంగా అందుబాటులో లేకుండా పోయింది"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"BACK కీ కనెక్ట్ చేయబడిన పరికరం కోసం ఉద్దేశించినది. నిష్క్రమించడానికి HOME బటన్‌ను నొక్కండి."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"టీవీ జాబితాలను చదవడానికి ప్రత్యక్ష ప్రసార ఛానెల్‌లకు అనుమతి అవసరం."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"మీ మూలాధారాలను సెటప్ చేయండి"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"ప్రత్యక్ష ప్రసార ఛానెల్‌లు అనువర్తనాల ద్వారా అందించబడే ప్రసార ఛానెల్‌ల్లో సాంప్రదాయక టీవీ ఛానెల్‌ల అనుభూతి కలగలిపి అందించబడతాయి. \n\nఇప్పటికే ఇన్‌స్టాల్ చేసుకున్న ఛానెల్ మూలాధారాలను సెటప్ చేయడం ద్వారా ప్రారంభించండి. లేదా ప్రత్యక్ష ప్రసార ఛానెల్‌లను ఆఫర్ చేసే మరిన్ని అనువర్తనాల కోసం Google Play స్టోర్‌లో బ్రౌజ్ చేయండి."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"రికార్డింగ్‌లు &amp; షెడ్యూల్‌లు"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 నిమిషాలు"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 నిమిషాలు"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 గంట"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 గంటలు"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"ఇటీవలివి"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"షెడ్యూల్ చేసినవి"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"సిరీస్"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"ఇతరం"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"ఛానెల్‌ను రికార్డ్ చేయడం సాధ్యపడదు."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"కార్యక్రమాన్ని రికార్డ్ చేయడం సాధ్యపడదు."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> రికార్డ్ చేయడం కోసం షెడ్యూల్ చేయబడింది"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"ఇప్పటి నుండి <xliff:g id="ENDTIME">%2$s</xliff:g> వరకు <xliff:g id="PROGRAMNAME">%1$s</xliff:g> రికార్డ్ చేస్తుంది"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"పూర్తి షెడ్యూల్"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">తదుపరి %1$d రోజులు</item>
- <item quantity="one">తదుపరి %1$d రోజు</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d నిమిషాలు</item>
- <item quantity="one">%1$d నిమిషం</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d కొత్త రికార్డింగ్‌లు</item>
- <item quantity="one">%1$d కొత్త రికార్డింగ్</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d రికార్డింగ్‌లు</item>
- <item quantity="one">%1$d రికార్డింగ్</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d రికార్డింగ్‌లు చేయాలి</item>
- <item quantity="one">%1$d రికార్డింగ్ చేయాలి</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"చూడండి"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"మొదటి నుండి ప్లే చేయి"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"ప్లే చేయడం కొనసాగించు"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"తొలగించు"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"రికార్డింగ్‌లను తొలగించు"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"పునఃప్రారంభించు"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"సీజన్ <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"షెడ్యూల్ చూడండి"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"మరింత చదవండి"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"రికార్డింగ్‌లు తొలగించు"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"మీరు తొలగించాలనుకునే ఎపిసోడ్‌లను ఎంచుకోండి. వీటిని ఒకసారి తొలగించాక తిరిగి పునరుద్ధరించలేరు."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"తొలగించడానికి రికార్డింగ్‌లు ఏవీ లేవు."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"చూసిన ఎపిసోడ్‌లను ఎంచుకోండి"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"అన్ని ఎపిసోడ్‌లను ఎంచుకోండి"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"అన్ని ఎపిసోడ్‌ల ఎంపిక తీసివేయి"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> నిమిషాల్లో <xliff:g id="WATCHED">%1$d</xliff:g> సమయం చూసారు"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> సెకన్లలో <xliff:g id="WATCHED">%1$d</xliff:g> సమయం చూసారు"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"ఎప్పుడూ చూడలేదు"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%2$dలో %1$d ఎపిసోడ్‌లు తొలగించబడ్డాయి</item>
- <item quantity="one">%2$dలో %1$d ఎపిసోడ్ తొలగించబడింది</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ప్రాధాన్యత"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"అత్యధికం"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"అతి తక్కువ"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"వద్దు. <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"ఛానెల్‌లు"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"ఏదైనా"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"ప్రాధాన్యతను ఎంచుకోండి"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"ఒకే సమయంలో చాలా ఎక్కువ కార్యక్రమాలు రికార్డ్ చేయాల్సినప్పుడు, అధిక ప్రాధాన్యతలు గలవి మాత్రమే రికార్డ్ చేయబడతాయి."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"సేవ్ చేయి"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"ఒక పర్యాయ రికార్డింగ్‌లు అత్యధిక ప్రాధాన్యతను కలిగి ఉంటాయి"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"రద్దు చేయి"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"రద్దు చేయి"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"విస్మరించు"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"ఆపివేయి"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"రికార్డింగ్ షెడ్యూల్ చూడండి"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"ఈ ఒక్క కార్యక్రమం"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ఇప్పటి నుండి - <xliff:g id="ENDTIME">%1$s</xliff:g> వరకు"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"మొత్తం సిరీస్…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"ఏదేమైనా షెడ్యూల్ చేయి"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"బదులుగా దీన్ని రికార్డ్ చేయి"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"ఈ రికార్డింగ్‌ను రద్దు చేయి"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"ఇప్పుడే చూడండి"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"రికార్డ్ చేయవచ్చు"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"రికార్డింగ్ షెడ్యూల్ చేయబడింది"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"రికార్డింగ్ వైరుధ్యం"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"రికార్డ్ అవుతోంది"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"రికార్డింగ్ విఫలమైంది"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"రికార్డింగ్ షెడ్యూళ్లను రూపొందించడానికి కార్యక్రమాలను చదువుతోంది"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"కార్యక్రమాలను చదువుతోంది"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVRకు మరింత నిల్వ అవసరం"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"మీరు DVRతో కార్యక్రమాలను రికార్డ్ చేయగలుగుతారు. అయితే, ప్రస్తుతం DVR పని చేయడానికి మీ పరికరంలో తగినంత నిల్వ ఖాళీ లేదు. దయచేసి <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB లేదా అంతకంటే ఎక్కువ ఖాళీ స్థలం గల బయటి డ్రైవ్‌ను కనెక్ట్ చేసి, ఆపై దాన్ని పరికర నిల్వగా ఫార్మాట్ చేయడానికి సూచనలను అనుసరించండి."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"నిల్వ కనిపించడం లేదు"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR ద్వారా ఉపయోగించబడిన కొంత నిల్వ కనిపించడం లేదు. దయచేసి DVRని పునఃప్రారంభించడానికి మీరు ఇంతకుముందు ఉపయోగించిన బయటి డిస్క్‌ను కనెక్ట్ చేయండి. లేదంటే, అది అందుబాటులో లేని పక్షంలో మీరు ఆ నిల్వను విస్మరించమని ఎంచుకోవచ్చు."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"నిల్వను విస్మరించాలా?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"మీ మొత్తం రికార్డ్ చేసిన కంటెంట్‌ను మరియు షెడ్యూల్‌లను కోల్పోతారు."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"రికార్డింగ్ ఆపివేయాలా?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"రికార్డ్ అయిన కంటెంట్ సేవ్ చేయబడుతుంది."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"రికార్డింగ్ షెడ్యూల్ చేయబడింది కానీ మిగిలిన వాటితో వైరుధ్యాలను కలిగి ఉంది"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"రికార్డింగ్ ప్రారంభమైంది, కానీ వైరుధ్యాలను కలిగి ఉంది"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> రికార్డ్ చేయబడుతుంది."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> రికార్డ్ అవుతోంది."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g>లో కొన్ని భాగాలు రికార్డ్ చేయబడవు."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> మరియు <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>లో కొన్ని భాగాలు రికార్డ్ చేయబడవు."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>లో కొన్ని భాగాలు మరియు మరొక షెడ్యూల్ రికార్డ్ చేయబడవు."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g>లో కొన్ని భాగాలు మరియు మరో %3$d షెడ్యూల్‌లు రికార్డ్ చేయబడవు.</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g>లో కొన్ని భాగాలు మరియు మరో %3$d షెడ్యూల్ రికార్డ్ చేయబడవు.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"మీరు ఏమి రికార్డ్ చేయాలనుకుంటున్నారు?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"మీరు ఎంత సమయం రికార్డ్ చేయాలనుకుంటున్నారు?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"ఇప్పటికే షెడ్యూల్ చేయబడింది"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"ఇదే కార్యక్రమం ఇప్పటికే <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>కి రికార్డ్ చేయడానికి షెడ్యూల్ చేయబడింది."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"ఇప్పటికే రికార్డ్ అయింది"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"ఈ ప్రోగ్రామ్ ఇప్పటికే రికార్డ్ అయింది. ఇది DVR లైబ్రరీలో అందుబాటులో ఉంది."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"రికార్డ్ చేసిన కార్యక్రమం కనుగొనబడలేదు."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"సంబంధిత రికార్డింగ్‌లు"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(కార్యక్రమం వివరణ లేదు)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d రికార్డింగ్‌లు</item>
- <item quantity="one">%1$d రికార్డింగ్</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> రికార్డింగ్ షెడ్యూల్ నుండి తీసివేయబడింది"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ట్యూనర్ వైరుధ్యాల కారణంగా పాక్షికంగా రికార్డ్ చేయబడుతుంది."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ట్యూనర్ వైరుధ్యాల కారణంగా రికార్డ్ చేయబడదు."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ఇంకా షెడ్యూల్ చేసిన రికార్డింగ్‌లు ఏవీ లేవు.\nమీరు కార్యక్రమాల గైడ్ నుండి రికార్డింగ్‌ను షెడ్యూల్ చేయవచ్చు."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d రికార్డింగ్ వైరుధ్యాలు ఉన్నాయి</item>
- <item quantity="one">%1$d రికార్డింగ్ వైరుధ్యం ఉంది</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"సిరీస్ సెట్టింగ్‌లు"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"సిరీస్ రికార్డింగ్ ఆరంభించు"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"సిరీస్ రికార్డింగ్ ఆపివేయి"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"సిరీస్ రికార్డింగ్‌ను ఆపివేయాలా?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"రికార్డ్ అయిన ఎపిసోడ్‌లు DVR లైబ్రరీలో అలాగే అందుబాటులో ఉంటాయి."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"ఆపివేయి"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ఎపిసోడ్‌లు ఏవీ అందుబాటులో లేవు.\nఇవి అందుబాటులోకి వచ్చిన వెంటనే రికార్డ్ చేయబడతాయి."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d నిమిషాలు)</item>
- <item quantity="one">(%1$d నిమిషం) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"ఈ రోజు"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"రేపు"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"నిన్న"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ఈ రోజు"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> రేపు"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"స్కోర్"</string>
-</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 8424e9bb..09bf9bd4 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"โมโน"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"สเตอริโอ"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"การควบคุมการเล่น"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"ช่องล่าสุด"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"ช่อง"</string>
<string name="menu_title_options" msgid="7184594626814914022">"ตัวเลือกทีวี"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"ตัวเลือกของ PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"ไม่มีการควบคุมการเล่นสำหรับช่องนี้"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"เล่นหรือหยุดชั่วคราว"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"กรอไปข้างหน้า"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"คำบรรยาย"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"โหมดการแสดงผล"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"เปิด"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"ปิด"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"หลายเสียง"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"รับชมช่องต่างๆ มากขึ้น"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"ดูช่องอื่นๆ"</string>
<string name="options_item_settings" msgid="7623205838542400074">"การตั้งค่า"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"แหล่งที่มา"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"สลับ"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"เปิด"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"ปิด"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"เสียง"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"หลัก"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"หน้าต่าง PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"การจัดวาง"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"ขวาล่าง"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"ขวาบน"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"ซ้ายบน"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"ซ้ายล่าง"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"แสดงคู่กัน"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"ขนาด"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"ใหญ่"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"เล็ก"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"แหล่งที่มาอินพุต"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (สายอากาศ/เคเบิล)"</string>
<string name="no_program_information" msgid="1049844207745145132">"ไม่มีข้อมูลโปรแกรม"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"ไม่มีข้อมูล"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"ช่องที่ถูกบล็อก"</string>
- <string name="default_language" msgid="4122326459624337928">"ภาษาที่ไม่รู้จัก"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"ภาษาที่ไม่รู้จัก"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"คำอธิบายภาพ %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"คำบรรยาย"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"ปิด"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"กำหนดค่าการจัดรูปแบบ"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"จัดกลุ่มตาม"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"โปรแกรมนี้ถูกบล็อก"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"รายการนี้ไม่ได้รับการจัดประเภท"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"โปรแกรมนี้เรต <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"อินพุตไม่สนับสนุนการสแกนอัตโนมัติ"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"ไม่สามารถเริ่มการสแกนอัตโนมัติสำหรับ \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
@@ -92,7 +74,6 @@
<item quantity="one">เพิ่มแล้ว %1$d ช่อง</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"ไม่ได้เพิ่มช่อง"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ตัวรับสัญญาณ"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"ควบคุมโดยผู้ปกครอง"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"เปิด"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"ปิด"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"ประเทศอื่นๆ"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"ไม่มี"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"ไม่มี"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"ไม่ได้จัดประเภท"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"บล็อกเกมที่ไม่ได้จัดประเภท"</string>
<string name="option_rating_none" msgid="5204552587760414879">"ไม่มี"</string>
<string name="option_rating_high" msgid="8898400296730158893">"ข้อจำกัดสูง"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"ข้อจำกัดปานกลาง"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"ป้อน PIN ของคุณเพื่อดูช่องนี้"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"ป้อน PIN ของคุณเพื่อดูโปรแกรมนี้"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"รายการนี้จัดอยู่ในประเภท <xliff:g id="RATING">%1$s</xliff:g> ป้อน PIN เพื่อดูรายการนี้"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"รายการนี้ไม่ได้รับการจัดประเภท ป้อน PIN เพื่อดูรายการนี้"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"ป้อน PIN ของคุณ"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"หากต้องการตั้งค่าการควบคุมโดยผู้ปกครอง โปรดสร้าง PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"ป้อน PIN ใหม่"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"PIN ไม่ถูกต้อง ลองอีกครั้ง"</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"ลองอีกครั้ง PIN ไม่ตรงกัน"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"ป้อนรหัสไปรษณีย์ของคุณ"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"แอป Live TV จะใช้รหัสไปรษณีย์สำหรับการจัดส่งคู่มือรายการทีวีช่องต่างๆ ฉบับเต็ม"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"ป้อนรหัสไปรษณีย์ของคุณ"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"รหัสไปรษณีย์ไม่ถูกต้อง"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"การตั้งค่า"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"กำหนดค่ารายการช่อง"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"เลือกช่องสำหรับคู่มือรายการทีวีของคุณ"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"แหล่งที่มาของช่อง"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"มีช่องใหม่ให้บริการ"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"การควบคุมโดยผู้ปกครอง"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"ไทม์ชิฟท์"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"บันทึกขณะดูเพื่อให้สามารถหยุดชั่วคราวหรือกรอกลับรายการสดได้\nคำเตือน: การดำเนินการนี้อาจลดอายุการใช้งานของพื้นที่เก็บข้อมูลภายในเนื่องจากการใช้งานหนัก"</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"ใบอนุญาตโอเพนซอร์ส"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"ใบอนุญาตโอเพนซอร์ส"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"ส่งความคิดเห็น"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"เวอร์ชัน"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"หากต้องการดูช่องนี้ ให้กดขวาและป้อน PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"หากต้องการดูโปรแกรมนี้ ให้กดขวาและป้อน PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"รายการนี้ไม่ได้รับการจัดประเภท\nหากต้องการดูรายการนี้ ให้กด \"สิทธิ์\" และป้อน PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"โปรแกรมนี้เรต <xliff:g id="RATING">%1$s</xliff:g>\nในการดูโปรแกรมนี้ โปรดกดขวาและป้อน PIN"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"หากต้องการดูช่องนี้ ให้ใช้แอปทีวีออนไลน์ที่เป็นค่าเริ่มต้น"</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"หากต้องการดูโปรแกรมนี้ ให้ใช้แอปทีวีออนไลน์ที่เป็นค่าเริ่มต้น"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"รายการนี้ไม่ได้รับการจัดประเภท\nหากต้องการดูรายการนี้ ให้ใช้แอป Live TV เริ่มต้น"</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"โปรแกรมนี้ได้รับคะแนน <xliff:g id="RATING">%1$s</xliff:g>\nหากต้องการดูโปรแกรมนี้ ให้ใช้แอปทีวีออนไลน์ที่เป็นค่าเริ่มต้น"</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"ระบบบล็อกโปรแกรมไว้"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"รายการนี้ไม่ได้รับการจัดประเภท"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"โปรแกรมนี้เรต <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"เฉพาะเสียง"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"สัญญาณไม่ดี"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"กด \"เลือก\""</b>" เพื่อเข้าถึงเมนู TV"</string>
<string name="msg_no_input" msgid="3897674146985427865">"ไม่พบอินพุต TV"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"ไม่พบอินพุต TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"ไม่สนับสนุน PIP"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"ไม่มีอินพุตที่พร้อมใช้งานซึ่งสามารถแสดงด้วย PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"ประเภทตัวรับสัญญาณไม่เหมาะสม โปรดเปิดแอป Live TV สำหรับอินพุต TV ที่เป็นประเภทตัวรับสัญญาณ"</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"การรับสัญญาณล้มเหลว"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"ไม่พบแอปสำหรับการทำงานนี้"</string>
@@ -226,6 +217,8 @@
<item quantity="other">กำหนดเวลาบันทึกแล้ว %1$d รายการ</item>
<item quantity="one">กำหนดเวลาบันทึกแล้ว %1$d รายการ</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"ยกเลิกการบันทึก"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"หยุดบันทึก"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"ดู"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"เล่นจากจุดเริ่มต้น"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"เล่นต่อจากที่ค้างไว้"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"เมื่อต้องบันทึกรายการหลายรายการพร้อมกันมากเกินไป ระบบจะบันทึกเฉพาะรายการที่มีลำดับความสำคัญสูงกว่าเท่านั้น"</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"บันทึก"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"การบันทึกครั้งเดียวมีความสำคัญสูงสุด"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"ยกเลิก"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"ยกเลิก"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"ไม่จำ"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"หยุด"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"ดูกำหนดการบันทึก"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"โปรแกรมนี้เท่านั้น"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"บันทึกรายการนี้แทน"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"ยกเลิกการบันทึกนี้"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"ดูตอนนี้"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"ลบรายการที่บันทึกไว้…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"สามารถบันทึกได้"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"กำหนดเวลาบันทึกแล้ว"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ตารางบันทึกชนกัน"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"กำลังบันทึก"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"การบันทึกล้มเหลว"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"กำลังอ่านรายการเพื่อสร้างกำหนดเวลาการบันทึก"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"กำลังอ่านรายการ"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"กำลังอ่านรายการ"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"ดูการบันทึกล่าสุด"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"การบันทึก <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ไม่สมบูรณ์"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"การบันทึก <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> และ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ไม่สมบูรณ์"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"การบันทึก <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> และ <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ไม่สมบูรณ์"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"การบันทึก <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ไม่สมบูรณ์ เนื่องจากพื้นที่เก็บข้อมูลไม่เพียงพอ"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"การบันทึก <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> และ <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ไม่สมบูรณ์ เนื่องจากพื้นที่เก็บข้อมูลไม่เพียงพอ"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"การบันทึก <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> และ <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> ไม่สมบูรณ์ เนื่องจากพื้นที่เก็บข้อมูลไม่เพียงพอ"</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR ต้องการพื้นที่เก็บข้อมูลเพิ่มเติม"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"คุณจะสามารถบันทึกรายการด้วย DVR ได้ อย่างไรก็ตาม ตอนนี้อุปกรณ์ของคุณมีพื้นที่เก็บข้อมูลไม่เพียงพอสำหรับให้ DVR ทำงาน โปรดเชื่อมต่อไดรฟ์ภายนอกที่มีขนาด <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB ขึ้นไป และทำตามขั้นตอนเพื่อฟอร์แมตไดรฟ์ให้เป็นพื้นที่เก็บข้อมูลของอุปกรณ์"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"คุณจะสามารถบันทึกรายการด้วย DVR ได้ อย่างไรก็ตาม ตอนนี้อุปกรณ์ของคุณมีพื้นที่เก็บข้อมูลไม่เพียงพอสำหรับให้ DVR ทำงาน โปรดเชื่อมต่อไดรฟ์ภายนอกที่มีขนาด <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB ขึ้นไป และทำตามขั้นตอนเพื่อฟอร์แมตไดรฟ์ให้เป็นพื้นที่เก็บข้อมูลของอุปกรณ์"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"พื้นที่เก็บข้อมูลไม่เพียงพอ"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"ไม่สามารถบันทึกรายการนี้ได้เนื่องจากพื้นที่เก็บข้อมูลไม่เพียงพอ โปรดลองลบบางรายการที่บันทึกไว้"</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"พื้นที่เก็บข้อมูลหายไป"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"พื้นที่เก็บข้อมูลบางส่วนที่ DVR ใช้หายไป โปรดเชื่อมต่อไดรฟ์ภายนอกที่คุณใช้ก่อนเปิดใช้ DVR อีกครั้ง หรือคุณอาจเลือกไม่จำพื้นที่เก็บข้อมูลหากพื้นที่เก็บข้อมูลไม่พร้อมใช้งานอีกต่อไป"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"ไม่จำพื้นที่เก็บข้อมูลใช่ไหม"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"เนื้อหาและกำหนดการทั้งหมดที่คุณบันทึกไว้จะหายไป"</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"หยุดบันทึกใช่ไหม"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ระบบจะเก็บเนื้อหาที่บันทึกไว้"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"การบันทึก <xliff:g id="PROGRAMNAME">%1$s</xliff:g> จะหยุดลงเนื่องจากตารางบันทึกชนกับรายการนี้ เนื้อหาที่บันทึกแล้วจะได้รับการเก็บไว้"</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"กำหนดการบันทึกรายการชนกัน"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"เริ่มบันทึกรายการแล้ว แต่กำหนดการชนกัน"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"ระบบจะบันทึก <xliff:g id="PROGRAMNAME">%1$s</xliff:g>"</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"มีกำหนดบันทึกรายการเดียวกันนี้แล้วเวลา <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>"</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"บันทึกไว้แล้ว"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"บันทึกรายการนี้ไว้แล้ว สามารถดูได้ที่ห้องสมุด DVR"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"กำหนดเวลาบันทึกซีรีส์แล้ว"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">กำหนดเวลาบันทึกแล้ว <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> รายการสำหรับ <xliff:g id="SERIESNAME_3">%2$s</xliff:g></item>
+ <item quantity="one">กำหนดเวลาบันทึกแล้ว <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> รายการสำหรับ <xliff:g id="SERIESNAME_1">%2$s</xliff:g></item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">กำหนดเวลาบันทึกแล้ว <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> รายการสำหรับ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> รายการจะไม่มีการบันทึกเนื่องจากตารางบันทึกชนกัน</item>
+ <item quantity="one">กำหนดเวลาบันทึกแล้ว <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> รายการสำหรับ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> จะไม่มีการบันทึกเนื่องจากเนื่องจากตารางบันทึกชนกัน</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">กำหนดเวลาบันทึกแล้ว <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> รายการสำหรับ <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ซีรีส์นี้และซีรีส์อื่น <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ตอนจะไม่มีการบันทึกเนื่องจากตารางบันทึกชนกัน</item>
+ <item quantity="one">กำหนดเวลาบันทึกแล้ว <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> รายการสำหรับ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ซีรีส์นี้และซีรีส์อื่น <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ตอนจะไม่มีการบันทึกเนื่องจากตารางบันทึกชนกัน</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">กำหนดเวลาบันทึกแล้ว <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> รายการสำหรับ <xliff:g id="SERIESNAME_3">%2$s</xliff:g> ซีรีส์อื่น 1 ตอนจะไม่มีการบันทึกเนื่องจากตารางบันทึกชนกัน</item>
+ <item quantity="one">กำหนดเวลาบันทึกแล้ว <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> รายการสำหรับ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ซีรีส์อื่น 1 ตอนจะไม่มีการบันทึกเนื่องจากตารางบันทึกชนกัน</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">กำหนดเวลาบันทึกแล้ว <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> รายการสำหรับ <xliff:g id="SERIESNAME_4">%2$s</xliff:g> ซีรีส์อื่น <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ตอนจะไม่มีการบันทึกเนื่องจากตารางบันทึกชนกัน</item>
+ <item quantity="one">กำหนดเวลาบันทึกแล้ว <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> รายการสำหรับ <xliff:g id="SERIESNAME_1">%2$s</xliff:g> ซีรีส์อื่น <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ตอนจะไม่มีการบันทึกเนื่องจากตารางบันทึกชนกัน</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"ไม่พบโปรแกรมที่บันทึกไว้"</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"การบันทึกที่เกี่ยวข้อง"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(ไม่มีรายละเอียดรายการ)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">การบันทึก %1$d รายการ</item>
<item quantity="one">การบันทึก %1$d รายการ</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"หยุดบันทึกซีรีส์ไหม"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"ตอนที่บันทึกไว้จะยังคงอยู่ในไลบรารี DVR"</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"หยุด"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ไม่มีตอนใดออกอากาศในตอนนี้"</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"ไม่มีตอนที่พร้อมรับชม\nระบบจะเริ่มบันทึกเมื่อมีตอนที่พร้อมรับชม"</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d นาที)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> วันนี้"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> พรุ่งนี้"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"คะแนน"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"รายการที่บันทึกไว้"</string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index a925aee6..cc19b272 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Mga kontrol sa Play"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Kamakailang channel"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Mga Channel"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Opsyon sa TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Mga opsyon sa PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Hindi available para sa channel na ito ang mga kontrol ng laro"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"I-play o i-pause"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"I-fast forward"</string>
@@ -35,37 +34,19 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Closed captions"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Display mode"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Naka-on"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Naka-off"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Multi-audio"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Higit pa channel"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Mga Setting"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Pinagmulan"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Pagpalitin"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Naka-on"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Naka-off"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Tunog"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Pangunahin"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP window"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Layout"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Kanang ibaba"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Kanang itaas"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Kaliwang itaas"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Kaliwang ibaba"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Magkatabi"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Laki"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Malaki"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Maliit"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Pinagmulan ng input"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenna/cable)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Walang impormasyon ng programa"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Walang impormasyon"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Naka-block na channel"</string>
- <string name="default_language" msgid="4122326459624337928">"Hindi kilalang wika"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Hindi kilalang wika"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Mga closed caption %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Mga closed caption"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Naka-off"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Customize formatting"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"I-set kagustuhan para sa closed captions"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"I-customize ang pag-format"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"I-set ang kagustuhan sa closed captions para sa buong system"</string>
<string name="side_panel_title_display_mode" msgid="6346286034015991229">"Display mode"</string>
<string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Multi-audio"</string>
<string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Ipangkat ayon sa"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Naka-block ang programang ito"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Hindi na-rate ang programang ito"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Ang programang ito ay na-rate na <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Hindi sinusuportahan ng input ang auto-scan"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Hindi maumpisahan ang auto-scan para sa \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
@@ -92,7 +74,6 @@
<item quantity="other">Nagdagdag ng %1$d na channel</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Wala naidagdag na channel"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Parental controls"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Naka-on"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Naka-off"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Iba pang bansa"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Wala"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Wala"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Hindi na-rate"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"I-block ang mga programang hindi na-rate"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Wala"</string>
<string name="option_rating_high" msgid="8898400296730158893">"High restrictions"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Bahagyang pinaghihigpitan"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Ilagay iyong PIN upang mapanood ang channel na ito"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Ilagay iyong PIN upang mapanood ang programang ito"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"May rating na <xliff:g id="RATING">%1$s</xliff:g> ang programang ito. Ilagay ang iyong PIN upang mapanood ang programang ito"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Hindi na-rate ang programang ito. Ilagay ang iyong PIN upang mapanood ang programang ito"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Ilagay ang iyong PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Upang itakda ang mga parental control, gumawa ng PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Ilagay ang bagong PIN"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Mali ang PIN na iyon. Subukang muli."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Subukang muli, hindi tumutugma ang PIN"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Ilagay ang iyong ZIP Code."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Gagamitin ng app na Mga Live Channel ang ZIP Code upang magbigay ng kumpletong gabay sa programa para sa mga channel sa TV."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Ilagay ang iyong ZIP Code"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Di-wasto ang ZIP Code"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Mga Setting"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"I-customize lista ng channel"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Pumili ng mga channel para sa gabay sa programa"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Mga pinagmulan ng channel"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"May mga bagong channel"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Mga kontrol ng magulang"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Mag-record habang nanonood upang ma-pause o ma-rewind mo ang mga live na programa.\nBabala: Maaari nitong mabawasan ang itatagal ng internal storage dahil sa labis-labis na paggamit ng storage."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Mga open source na lisensya"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Mga lisensyang open source"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Magpadala ng feedback"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Bersyon"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Upang mapanood ang channel na ito, pindutin ang Kanan at ilagay ang iyong PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Upang mapanood ang programang ito, pindutin ang Kanan at ilagay ang iyong PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Hindi na-rate ang programang ito.\nUpang mapanood ang programang ito, pindutin ang Kanan at ilagay ang iyong PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Ang programang ito ay na-rate na <xliff:g id="RATING">%1$s</xliff:g>.\nUpang mapanood ang programang ito, pindutin ang Kanan at ilagay ang iyong PIN."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Upang mapanood ang channel na ito, gamitin ang default na Live TV app."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Upang mapanood ang programang ito, gamitin ang default na Live TV app."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Hindi na-rate ang programang ito.\nUpang mapanood ang programang ito, gamitin ang default na Live TV app."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Ang programang ito ay binigyan ng rating na <xliff:g id="RATING">%1$s</xliff:g>.\nUpang mapanood ang programang ito, gamitin ang default na Live TV app."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Naka-block ang programa"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Hindi na-rate ang programang ito"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Ang programang ito ay na-rate na <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Audio lang"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Mahinang signal"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Pindutin ang SELECT"</b>" upang i-access ang menu ng TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Walang nahanap na TV input"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Hindi mahanap ang TV input"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"Hindi sinusuportahan ang PIP"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Walang available na input na maipapakita sa PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Hindi naaangkop ang uri ng tuner. Pakilunsad ang app na Mga Live na Channel para sa uri ng tuner na input ng TV."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Hindi na-tune"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Walang nakitang app na gagawa sa aksyong ito."</string>
@@ -226,6 +217,8 @@
<item quantity="one">%1$d recording ang nakaiskedyul</item>
<item quantity="other">%1$d na recording ang nakaiskedyul</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Kanselahin ang pag-record"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Ihinto ang pag-record"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Panoorin"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"I-play mula sa simula"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Ituloy ang pag-play"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Kapag masyadong maraming programa ang ire-record nang sabay-sabay, tanging ang may mas mataas na priyoridad lang ang mare-record."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"I-save"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Ang mga isang beses na pagre-record ang may pinakamataas na priyoridad"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Kanselahin"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Kanselahin"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Kalimutan"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Ihinto"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Tingnan, iskedyul ng recording"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Ang isang programang ito"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Ito na lang ang i-record"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Kanselahin ang pag-record na ito"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Panoorin ngayon"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"I-delete ang mga recording…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Mare-record"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Nakaiskedyul ang recording"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"May conflict sa pagre-record"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Nagre-record"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Hindi na-record"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Nagbabasa ng mga program upang makagawa ng mga iskedyul ng pagre-record"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Binabasa ang mga programa"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Binabasa ang mga programa"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Tingnan ang mga kamakailang recording"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Hindi natapos ang pag-record sa <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Hindi natapos ang mga pag-record sa <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> at <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Hindi natapos ang mga pag-record sa <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> at <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Hindi natapos ang pag-record sa <xliff:g id="PROGRAMNAME">%1$s</xliff:g> dahil sa hindi sapat na storage."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Hindi natapos ang mga pag-record sa <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> at <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> dahil sa hindi sapat na storage."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Hindi natapos ang mga pag-record sa <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> at <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> dahil sa hindi sapat na storage."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Kailangan ng DVR ng higit pang storage"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Makakapag-record ka ng mga program gamit ang DVR. Gayunpaman, walang sapat na storage sa iyong device ngayon upang gumana ang DVR. Mangyaring magkonekta ng external drive na <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB o mas malaki at sundin ang mga hakbang upang i-format ito bilang storage ng device."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Makakapag-record ka ng mga program gamit ang DVR. Gayunpaman, walang sapat na storage sa iyong device ngayon upang gumana ang DVR. Mangyaring magkonekta ng external drive na <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB o mas malaki at sundin ang mga hakbang upang i-format ito bilang storage ng device."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Hindi sapat ang storage"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Hindi mare-record ang program na ito dahil walang sapat na storage. Subukang mag-delete ng ilang dati nang recording."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Nawawala ang storage"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"May nawawalang bahagi ng storage na ginagamit ng DVR. Pakikonekta ang external na drive na ginamit mo dati upang muling i-enable ang DVR. O kaya, maaari mo ring piliing kalimutan ang storage kung hindi na ito available."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Kalimutan ang storage?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Mawawala ang lahat ng na-record mong content at iskedyul."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Ihinto ang pagre-record?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Mase-save ang na-record na content."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Ihihinto na ang pag-record ng <xliff:g id="PROGRAMNAME">%1$s</xliff:g> dahil kasabay ito ng palabas na ito. Ise-save ang na-record na content."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Naiskedyul na ang pagre-record ngunit may mga hindi pagkakatugma"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Nagsimula na ang pagre-record ngunit may mga hindi pagkakatugma"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Mare-record ang <xliff:g id="PROGRAMNAME">%1$s</xliff:g>."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Naiskedyul na ang parehong programa na ma-record sa <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Na-record na"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Na-record na ang programang ito. Available ito sa DVR library."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Naiskedyul na ang pag-record ng series"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recording ang naiskedyul para sa <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> na recording ang naiskedyul para sa <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recording ang naiskedyul para sa <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Hindi mare-record ang <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> sa mga ito dahil sa may mga nakaiskedyul na.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> na recording ang naiskedyul para sa <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. Hindi mare-record ang <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> sa mga ito dahil sa may mga nakaiskedyul na.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> recording ang naiskedyul para sa <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episode ng series na ito at ng iba pang series ang hindi mare-record dahil may mga nakaiskedyul na.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> na recording ang naiskedyul para sa <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> na episode ng series na ito at ng iba pang series ang hindi mare-record dahil may mga nakaiskedyul na.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> recording ang naiskedyul para sa <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 episode ng iba pang series ang hindi mare-record dahil sa may mga nakaiskedyul na.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> na recording ang naiskedyul para sa <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 episode ng iba pang series ang hindi mare-record dahil sa may mga nakaiskedyul na.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> recording ang naiskedyul para sa <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> episode ng iba pang series ang hindi mare-record dahil sa may mga nakaiskedyul na.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> na recording ang naiskedyul para sa <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> na episode ng iba pang series ang hindi mare-record dahil sa may mga nakaiskedyul na.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Hindi nakita ang na-record na programa."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Mga nauugnay na recording"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Walang paglalarawan ng program)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d recording</item>
<item quantity="other">%1$d na recording</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Gusto mo bang ihinto ang pagre-record ng mga serye?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Mananatiling available sa library ng DVR ang mga na-record na episode."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Ihinto"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Walang ipinapalabas na episode ngayon."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Walang available na mga episode.\nMare-record ang mga ito kapag available na ang mga ito."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d minuto)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ngayong araw"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> bukas"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Marka"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Mga Na-record na Programa"</string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 8162fbfa..d8f92210 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Oynatma denetimleri"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Son kanallar"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanallar"</string>
<string name="menu_title_options" msgid="7184594626814914022">"TV seçenekleri"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP seçenekleri"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Bu kanal için oynatma denetimleri kullanılamıyor"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Oynat veya duraklat"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"İleri sar"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Altyazılar"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Görüntü modu"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Açık"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Kapalı"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Çoklu ses"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Daha çok kanal al"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Ayarlar"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Kaynak"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Değiştir"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Açık"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Kapalı"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Ses"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Ana"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP penceresi"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Düzen"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Sağ alt"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Sağ üst"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Sol üst"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Sol alt"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Yan yana"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Boyut"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Büyük"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Küçük"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Giriş kaynağı"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (anten/kablo)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Hiçbir program bilgisi yok"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Bilgi yok"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Engellenen kanal"</string>
- <string name="default_language" msgid="4122326459624337928">"Bilinmeyen dil"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Bilinmeyen dil"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Altyazılar %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Altyazılar"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Kapalı"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Biçimi özelleştir"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Gruplama ölçütü"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Bu program engellendi"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Bu program derecelendirilmedi"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Bu program <xliff:g id="RATING">%1$s</xliff:g> olarak derecelendirilmiştir"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Giriş, otomatik taramayı desteklemiyor"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\"<xliff:g id="TV_INPUT">%s</xliff:g>\" için otomatik tarama başlatılamıyor"</string>
@@ -92,7 +74,6 @@
<item quantity="one">%1$d kanal eklendi</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Hiçbir kanal eklenmedi"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Ebeveyn denetimi"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Açık"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Kapalı"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Diğer ülkeler"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Yok"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Yok"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Derecelendirilmedi"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Derecelendirilmemiş programları engelle"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Yok"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Yüksek kısıtlama"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Orta düzey kısıtlama"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Bu kanalı izlemek için PIN\'inizi girin"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Bu programı izlemek için PIN\'inizi girin"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Bu program <xliff:g id="RATING">%1$s</xliff:g> olarak derecelendirildi. Bu programı izlemek için PIN kodunuzu girin."</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Bu program derecelendirilmedi. Programı izlemek için PIN kodunuzu girin."</string>
<string name="pin_enter_pin" msgid="249314665028035038">"PIN\'inizi girin"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Ebeveyn denetimlerini ayarlamak için PIN oluşturun"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Yeni PIN\'i girin"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Girdiğiniz PIN hatalıydı. Tekrar deneyin."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Tekrar deneyin, PIN eşleşmiyor"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Posta Kodunuzu girin."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Canlı Kanallar uygulaması, TV kanalları için eksiksiz bir program rehberi sunmak üzere Posta Kodu\'nu kullanacaktır."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Posta Kodunuzu girin"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Geçersiz Posta Kodu"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Ayarlar"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Kanal listesini özelleştir"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Program rehberiniz için kanalları seçin"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanal kaynakları"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Yeni kanallar mevcut"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Ebeveyn denetimleri"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Zaman kaydırma"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"İzlerken kaydedin. Böylece canlı programları duraklatabilir veya geri sarabilirsiniz. \nUyarı: Bu özellik depolama alanını yoğun bir şekilde kullandığından dahili depolama alanının kullanım ömrü azalabilir."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Açık kaynak lisansları"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Açık kaynak lisansları"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Geri bildirim gönder"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Sürüm"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Bu kanalı izlemek için Sağ tuşuna basın ve PIN\'inizi girin"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Bu programı izlemek için Sağ tuşuna basın ve PIN\'inizi girin"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Bu program derecelendirilmedi.\nProgramı izlemek için Sağ\'a basın ve PIN\'inizi girin."</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Bu program <xliff:g id="RATING">%1$s</xliff:g> olarak derecelendirilmiştir.\nBu programı izlemek için Sağ tuşuna basın ve PIN\'inizi girin."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Bu kanalı izlemek için varsayılan Canlı TV uygulamasını kullanın."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Bu programı izlemek için varsayılan Canlı TV uygulamasını kullanın."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Bu program derecelendirilmedi.\nProgramı izlemek için varsayılan Canlı TV uygulamasını kullanın."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Bu program <xliff:g id="RATING">%1$s</xliff:g> olarak derecelendirildi.\nBu programı izlemek için varsayılan Canlı TV uygulamasını kullanın."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Program engellendi"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Bu program derecelendirilmedi"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Bu program <xliff:g id="RATING">%1$s</xliff:g> olarak derecelendirilmiştir"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Yalnızca ses"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Zayıf sinyal"</string>
@@ -171,7 +164,7 @@
<string name="setup_input_new" msgid="3337725672277046798">"Yeni"</string>
<string name="setup_input_setup_now" msgid="1772000402336958967">"Yapılandırılmadı"</string>
<string name="setup_store_action_title" msgid="4083402039720973414">"Daha fazla kaynak al"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Canlı kanallar sunan uygulamalara göz atın"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Canlı kanal uygulamalarına göz atın"</string>
<string name="new_sources_title" msgid="3878933676500061895">"Kullanılabilir yeni kanal kaynakları mevcut"</string>
<string name="new_sources_description" msgid="749649005588426813">"Yeni kanal kaynaklarında sunulan kanallar var.\nBunları şimdi ayarlayın veya daha sonra kanal kaynakları ayarında yapılandırın."</string>
<string name="new_sources_action_setup" msgid="177693761664016811">"Şimdi ayarla"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307">"TV menüsüne erişmek için "<b>"SEÇ\'e basın"</b>"."</string>
<string name="msg_no_input" msgid="3897674146985427865">"TV girişi bulunamadı"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"TV girişi bulunamadı"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP desteklenmiyor"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP ile göstermeye uygun giriş yok"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Kanal tarayıcı türü uygun değil. TV girişi kanal tarayıcı türü için lütfen Canlı Yayın Kanalları uygulamasını başlatın."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Tarama işlemi başarısız oldu"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Bu işlemi gerçekleştirecek uygulama bulunamadı."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d kayıt planlandı</item>
<item quantity="one">%1$d kayıt planlandı</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Kaydı iptal et"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Kaydı durdur"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"İzle"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Baştan oynat"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Oynatmaya devam et"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Aynı anda kaydedilecek çok sayıda program olduğundan, yalnızca yüksek öncelikli programlar kaydedilir."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Kaydet"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Bir kerelik kayıtlar en yüksek önceliğe sahip"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"İptal"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"İptal"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Unut"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Durdur"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Kayıt programını görüntüle"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Yalnızca bu program"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Onun yerine bunu kaydet"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Bu kaydı iptal et"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Şimdi izle"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Kayıtları sil…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Kaydedilebilir"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Kayıt programlandı"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Kayıt çakışması"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Kaydediliyor"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Kaydedilemedi"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Kayıt planlarını oluşturmak için programlar okunuyor"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Program bilgisi okunuyor"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Program bilgisi okunuyor"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Son kayıtları görüntüleyin"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> kaydı tam değil."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ve <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> kayıtları tam değil."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ve <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> kayıtları tam değil."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Kullanılabilir depolama alanı yeterli olmadığından <xliff:g id="PROGRAMNAME">%1$s</xliff:g> kaydı tamamlanamadı."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Kullanılabilir depolama alanı yeterli olmadığından <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ve <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> kayıtları tamamlanamadı."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Kullanılabilir depolama alanı yeterli olmadığından <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ve <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> kayıtları tamamlanamadı."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR için daha fazla depolama alanı gerekiyor"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Programları DVR ile kaydedebileceksiniz. Ancak şu anda cihazınızda DVR\'nin çalışması için yeterli miktarda boş depolama alanı yok. Lütfen <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB veya daha büyük kapasiteye sahip harici sürücü bağlayın ve bu sürücüyü cihaz depolama alanı olarak biçimlendirmek için adımları uygulayın."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Programları DVR ile kaydedebileceksiniz. Ancak şu anda cihazınızda DVR\'nin çalışması için yeterli miktarda boş depolama alanı yok. Lütfen <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB veya daha büyük kapasiteye sahip harici sürücü bağlayın ve bu sürücüyü cihaz depolama alanı olarak biçimlendirmek için adımları uygulayın."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Yeterli depolama alanı yok"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Yeterli depolama alanı olmadığı için bu program kaydedilmeyecek. Mevcut kayıtlardan bazılarını silmeyi deneyin."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Kayıp depolama birimi"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"DVR tarafından kullanılan bazı depolama alanları kayıp. DVR\'yi yeniden etkinleştirmeden önce lütfen kullandığınız harici sürücüyü bağlayın. Ayrıca bu depolama alanı artık kullanılmıyorsa unutulmasını da seçebilirsiniz."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Depolama alanı unutulsun mu?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Kaydedilen tüm içeriğiniz ve programlarınız kaybolacaktır."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Kayıt durudurulsun mu?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Kaydedilen içerik saklanacak."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> kaydı, bu programla çakıştığından durdurulacak. Kaydedilen içerik saklanacak."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Kayıt programlandı, ancak çakışmalar var"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Kayıt işlemi başladı, ancak çakışmalar var"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> kaydedilecek."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Aynı program şu tarihte ve saatte kaydedilecek şekilde zaten programlandı: <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Zaten kaydedildi"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Bu program zaten kaydedildi. DVR kitaplığında bulabilirsiniz."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Dizi kaydı programlandı"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> için <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> kayıt programlandı.</item>
+ <item quantity="one"> <xliff:g id="SERIESNAME_1">%2$s</xliff:g> için <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> kayıt programlandı.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> için <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> kayıt programlandı. Çakışma nedeniyle bu kayıtların <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> tanesi yapılmayacak.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> için <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> kayıt programlandı. Çakışma nedeniyle bu kayıt yapılmayacak.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> için <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> kayıt programlandı. Çakışma nedeniyle bu dizinin ve diğer dizilerin <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> bölümü kaydedilmeyecek.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> için <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> kayıt programlandı. Çakışma nedeniyle bu dizinin ve diğer dizilerin <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> bölümü kaydedilmeyecek.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> için <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> kayıt programlandı. Çakışma nedeniyle diğer dizinin 1 bölümü kaydedilmeyecek.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> için <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> kayıt programlandı. Çakışma nedeniyle diğer dizinin 1 bölümü kaydedilmeyecek.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> için <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> kayıt programlandı. Çakışma nedeniyle diğer dizinin <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> bölümü kaydedilmeyecek.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> için <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> kayıt programlandı. Çakışma nedeniyle diğer dizinin <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> bölümü kaydedilmeyecek.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Kaydedilen program bulunamadı."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"İlgili kayıtlar"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Program açıklaması yok)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d kayıt</item>
<item quantity="one">%1$d kayıt</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Dizinin kaydı durdurulsun mu?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Kaydedilen bölümler DVR kitaplığında kalmaya devam edecektir."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Durdur"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Şu anda yayınlanan bir bölüm yok."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Kaydedilebilecek bir bölüm yok.\nBölümler kullanıma sunulduğunda kaydedilecektir."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d dakika)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Bugün <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Yarın <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Puanı"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Kayıtlı Programlar"</string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index b9d91a7a..1d673dfc 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"моно"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"стерео"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Керування відтворенням"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Останні канали"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Канали"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Опції ТБ"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Опції PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Елементи керування відтворенням, яких немає в цьому каналі"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Відтворити або призупинити"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Перемотати вперед"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Субтитри"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Режим показу"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Увімкнено"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Вимкнено"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Кілька аудіо"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Більше каналів"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Налаштування"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Джерело"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Заміна"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Увімкнено"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Вимкнено"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Звук"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Основне вікно"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Вікно PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Схема"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Унизу праворуч"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Угорі праворуч"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Угорі ліворуч"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Унизу ліворуч"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Поруч"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Розмір"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Великий розмір"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Малий розмір"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Джерело сигналу"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"ТБ (ефірне або кабельне)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Немає інформації про програму"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Немає інформації."</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Заблокований канал"</string>
- <string name="default_language" msgid="4122326459624337928">"Невідома мова"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Невідома мова"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Субтитри (%1$d)"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Субтитри"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Вимкнути"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Налаштувати формат"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Параметри групування"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Цю телепередачу заблоковано"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Ця передача без вікових обмежень"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Ця телепередача належить до категорії <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Джерело вхідного сигналу не підтримує автоматичне сканування"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Не вдалось автоматично просканувати джерело сигналу \"<xliff:g id="TV_INPUT">%s</xliff:g>\""</string>
@@ -94,7 +76,6 @@
<item quantity="other">Додано %1$d каналу</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Немає каналів"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Тюнер"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Контроль батьків"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Увімкнути"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Вимкнути"</string>
@@ -110,6 +91,8 @@
<string name="other_countries" msgid="8342216398676184749">"Інші країни"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Немає"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Немає"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Без вікових обмежень"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Блокувати передачі без вікових обмежень"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Немає"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Суворі обмеження"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Помірні обмеження"</string>
@@ -126,6 +109,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Введіть PIN-код, щоб дивитися цей канал"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Введіть PIN-код, щоб дивитися цю телепередачу"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Вікові обмеження для цієї передачі: <xliff:g id="RATING">%1$s</xliff:g>. Щоб дивитися її, введіть PIN-код"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Це передача без вікових обмежень. Щоб дивитися її, введіть PIN-код"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Введіть PIN-код"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Щоб налаштувати батьківський контроль, створіть PIN-код"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Введіть новий PIN-код"</string>
@@ -139,22 +123,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Цей PIN-код неправильний. Повторіть спробу."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"PIN-коди не збігаються. Повторіть спробу"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Введіть поштовий індекс."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Додаток Телеканали показує повну програму телепередач на основі поштового індексу."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Введіть поштовий індекс"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Недійсний поштовий індекс"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Налаштування"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Налаштувати список каналів"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Вибрати канали для програми телепередач"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Джерела каналів"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Доступні нові канали"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Батьківський контроль"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Зміщення в часі"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Записуйте передачі під час перегляду, щоб потім призупиняти або перемотувати їх.\nЗастереження. Це може зменшити обсяг внутрішньої пам’яті через її інтенсивне використання."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Ліцензії відкритого коду"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Ліцензії ПЗ з відкритим кодом"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Надіслати відгук"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Версія"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Щоб дивитися цей канал, натисніть стрілку праворуч і введіть PIN-код"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Щоб дивитися цю телепередачу, натисніть стрілку праворуч і введіть PIN-код"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Це передача без вікових обмежень.\nЩоб дивитися її, натисніть стрілку вправо та введіть PIN-код"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Ця телепередача належить до категорії <xliff:g id="RATING">%1$s</xliff:g>.\nЩоб дивитися її, натисніть стрілку праворуч і введіть PIN-код."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Щоб дивитися цей канал, відкрийте додаток для прямих трансляцій за умовчанням."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Щоб дивитися цю телепередачу, відкрийте додаток для прямих трансляцій за умовчанням."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Це передача без вікових обмежень.\nЩоб дивитися її, відкрийте додаток для прямих трансляцій за умовчанням."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Категорія цієї телепередачі – <xliff:g id="RATING">%1$s</xliff:g>.\nЩоб дивитися її, відкрийте додаток для прямих трансляцій за умовчанням."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Телепередачу заблоковано"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Ця передача без вікових обмежень"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Ця телепередача належить до категорії <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Лише аудіо"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Слабкий сигнал"</string>
@@ -179,7 +172,7 @@
<string name="setup_input_new" msgid="3337725672277046798">"Нові"</string>
<string name="setup_input_setup_now" msgid="1772000402336958967">"Не налаштовано"</string>
<string name="setup_store_action_title" msgid="4083402039720973414">"Отримати більше джерел"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Переглянути додатки, у яких пропонуються канали в прямому ефірі"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Переглянути додатки, у яких можна дивитися телеканали в прямому ефірі"</string>
<string name="new_sources_title" msgid="3878933676500061895">"Доступні нові джерела каналів"</string>
<string name="new_sources_description" msgid="749649005588426813">"Нові джерела пропонують канали.\nНалаштуйте їх зараз або зробіть це пізніше в налаштуваннях джерел каналів."</string>
<string name="new_sources_action_setup" msgid="177693761664016811">"Налаштувати"</string>
@@ -189,8 +182,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Натисніть \"ВИБРАТИ\""</b>", щоб відкрити меню телевізора."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Не знайдено джерел вхідного телесигналу"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Не вдається знайти джерело вхідного телесигналу"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP не підтримується"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Немає джерел вхідного сигналу для PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Тюнер не підтримується. Щоб використовувати тюнер, запустіть додаток Live TV."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Не вдалося налаштувати"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Не знайдено додатка для цієї дії."</string>
@@ -199,7 +190,7 @@
<string name="msg_back_key_guide" msgid="7404682718828721924">"Клавіша \"НАЗАД\" діє на підключеному пристрої. Натисніть \"ГОЛОВНИЙ ЕКРАН\", щоб вийти."</string>
<string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Додатку Live TV потрібен дозвіл переглядати програму телепередач."</string>
<string name="setup_sources_text" msgid="4988039637873759839">"Налаштуйте джерела"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"У телеканалах поєднуються зручність традиційних каналів і трансляція каналів із додатків. \n\nЩоб почати, налаштуйте вже встановлені джерела каналів. Або пошукайте в магазині Google Play інші додатки з телеканалами."</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Телеканали об\'єднують звичайні канали й потокові трансляції з додатків. \n\nПочніть із налаштування вже наявних джерел каналів або пошукайте в магазині Google Play інші додатки з телеканалами."</string>
<string name="channels_item_dvr" msgid="8911915252648532469">"Записи та графіки"</string>
<string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 хвилин"</string>
<string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 хвилин"</string>
@@ -244,6 +235,8 @@
<item quantity="many">Заплановано %1$d записів</item>
<item quantity="other">Заплановано %1$d запису</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Скасувати запис"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Припинити запис"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Переглянути"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Відтворити з початку"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Відновити відтворення"</string>
@@ -278,9 +271,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Якщо є забагато програм для одночасного запису, записуватимуться лише програми з вищим пріоритетом."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Зберегти"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Одноразові записи мають найвищий пріоритет"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Скасувати"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Скасувати"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Забути"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Припинити"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Переглянути розклад запису"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Лише ця передача"</string>
@@ -290,25 +280,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Натомість записати цю передачу"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Скасувати цей запис"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Дивитися"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Видалити записи…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Можна записати"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Запис заплановано"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Конфлікт запису"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Запис"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Не записано"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Читаються назви передач для створення розкладів"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Читання даних програм"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Читання інформації про передачі"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Переглянути нещодавні записи"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Запис передачі \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" не завершено."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Запис передач \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\" і \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" не завершено."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Запис передач \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\", \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" і \"<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>\" не завершено."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Запис передачі \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" не завершено. Замало місця."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Запис передач \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\" і \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" не завершено. Замало місця."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Запис передач \"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>\", \"<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>\" і \"<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>\" не завершено. Замало місця."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"Пристрою DVR потрібно більше пам’яті"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"За допомогою пристрою DVR можна записувати програми, однак на ньому недостатньо пам’яті. Підключіть зовнішній диск ємністю <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> Гб або більше та дотримуйтеся вказівок, щоб відформатувати його як пам’ять пристрою."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"За допомогою пристрою DVR можна записувати програми, однак на ньому недостатньо пам’яті. Підключіть зовнішній диск ємністю <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> ГБ або більше та дотримуйтеся вказівок, щоб відформатувати його як пам’ять пристрою."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Замало пам’яті"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Замало пам’яті. Цю передачу не буде записано. Спробуйте видалити деякі наявні записи."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Немає пам’яті"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Немає деякої пам’яті, яку використовує DVR. Щоб знову ввімкнути DVR, під’єднайте зовнішній диск, який ви використовували раніше. Можна також забути пам’ять, якщо вона недоступна."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Забути пам’ять?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Увесь записаний вміст і розклади буде втрачено."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Припинити запис?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Записаний вміст буде збережено."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Запис серіалу \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" буде зупинено через конфлікти з ним. Записаний вміст буде збережено."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Запис заплановано, однак є конфлікти"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Запис почався, однак є конфлікти"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"Програму \"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>\" буде записано."</string>
@@ -328,17 +321,39 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Цю передачу вже заплановано записати о <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>"</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Уже записано"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Цю передачу вже записано. Вона доступна в бібліотеці DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Заплановано запис серіалу"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> запис серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\".</item>
+ <item quantity="few">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записи серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\".</item>
+ <item quantity="many">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записів серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\".</item>
+ <item quantity="other">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> запису серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\".</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> запис серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Через конфлікти не буде записано <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> із них.</item>
+ <item quantity="few">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записи серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Через конфлікти не буде записано <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> з них.</item>
+ <item quantity="many">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записів серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Через конфлікти не буде записано <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> із них.</item>
+ <item quantity="other">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> запису серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Через конфлікти не буде записано <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> із них.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one">Заплановано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> запис серіалу \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Через конфлікти не буде записано стільки серій цього й іншого серіалів: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="few">Заплановано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записи серіалу \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Через конфлікти не буде записано стільки серій цього й іншого серіалів: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="many">Заплановано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записів серіалу \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Через конфлікти не буде записано стільки серій цього й іншого серіалів: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="other">Заплановано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> запису серіалу \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Через конфлікти не буде записано стільки серій цього й іншого серіалів: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> запис серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Через конфлікти не буде записано 1 серію іншого серіалу.</item>
+ <item quantity="few">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записи серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Через конфлікти не буде записано 1 серію іншого серіалу.</item>
+ <item quantity="many">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> записів серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Через конфлікти не буде записано 1 серію іншого серіалу.</item>
+ <item quantity="other">Заплановано <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> запису серіалу \"<xliff:g id="SERIESNAME_3">%2$s</xliff:g>\". Через конфлікти не буде записано 1 серію іншого серіалу.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one">Заплановано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> запис серіалу \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Через конфлікти не буде записано стільки серій іншого серіалу: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="few">Заплановано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записи серіалу \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Через конфлікти не буде записано стільки серій іншого серіалу: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="many">Заплановано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> записів серіалу \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Через конфлікти не буде записано стільки серій іншого серіалу: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ <item quantity="other">Заплановано <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> запису серіалу \"<xliff:g id="SERIESNAME_4">%2$s</xliff:g>\". Через конфлікти не буде записано стільки серій іншого серіалу: <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g>.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Не вдалося знайти записані програми."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Пов’язані записи"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Немає опису програми)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d запис</item>
<item quantity="few">%1$d записи</item>
@@ -362,6 +377,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Припинити запис серій?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Записані серії можна переглянути в бібліотеці DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Припинити"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Зараз серії не транслюються."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Немає серій.\nСерії буде записано, щойно вони з’являться."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d хвилина)</item>
@@ -375,4 +391,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"Сьогодні о <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Завтра о <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Оцінка"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Записані передачі"</string>
</resources>
diff --git a/res/values-ur-v23/strings.xml b/res/values-ur-rPK-v23/strings.xml
index 22ec8b49..22ec8b49 100644
--- a/res/values-ur-v23/strings.xml
+++ b/res/values-ur-rPK-v23/strings.xml
diff --git a/res/values-ur/arrays.xml b/res/values-ur-rPK/arrays.xml
index f54b4914..f54b4914 100644
--- a/res/values-ur/arrays.xml
+++ b/res/values-ur-rPK/arrays.xml
diff --git a/res/values-ur/rating_system_strings.xml b/res/values-ur-rPK/rating_system_strings.xml
index 07f99a99..07f99a99 100644
--- a/res/values-ur/rating_system_strings.xml
+++ b/res/values-ur-rPK/rating_system_strings.xml
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
new file mode 100644
index 00000000..36fed928
--- /dev/null
+++ b/res/values-ur-rPK/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"مونو"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"اسٹیریو"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"پلے کنٹرولز"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"چینلز"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"‏TV کے اختیارات"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"چلانے کے کنٹرولز اس چینل کیلئے غیر دستیاب ہیں"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"چلائیں یا موقوف کریں"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"تیزی سے فارورڈ کریں"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"ریوائینڈ کریں"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"آگے"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"پچھلا"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"پروگرام گائیڈ"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"نئے چینلز دستیاب ہیں"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> کھولیں"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"سب ٹائٹلز"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"ڈسپلے وضع"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"کثیر آڈیو"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"مزید چینلز حاصل کریں"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"ترتیبات"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"‏TV (اینٹینا/کیبل)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"پروگرام کی معلومات نہیں"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"کوئی معلومات نہیں ہے"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"مسدود چینل"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"نامعلوم زبان"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"‏سب ٹائٹلز ‎%1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"سب ٹائٹلز"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"آف"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"فارمیٹنگ کسٹمائز کریں"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"سب ٹائٹل کیلئے سسٹم وار ترجیحات سیٹ کریں"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ڈسپلے وضع"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"کثیر آڈیو"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"مونو"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"اسٹیریو"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 گھیر"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 گھیر"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"‏‎%d چینلز"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"چینل لسٹ کسٹمائز کریں"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"گروپ منتخب کریں"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"گروپ غیر منتخب کریں"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"گروپ بلحاظ"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"چینل ماخذ"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"گروپ بلحاظ"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"یہ پروگرام مسدود ہے"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"یہ پروگرام درجہ بند نہیں ہے"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"اس پروگرام کی درجہ بندی <xliff:g id="RATING">%1$s</xliff:g> کی گئی ہے"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"ان پٹ آٹو اسکین کو سپورٹ نہیں کرتا"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' کیلئے آٹو اسکین شروع کرنے سے قاصر ہے"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"سب ٹائٹلز کیلئے سسٹم وار ترجیحات شروع کرنے سے قاصر ہے۔"</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">‏%1$d چینل شامل ہو گئے</item>
+ <item quantity="one">‏%1$d چینل شامل ہو گیا</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"کوئی چینلز شامل نہیں کیے گئے"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"پیرنٹل کنٹرولز"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"آن"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"آف"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"چینلز مسدود کر دیے"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"سبھی کو مسدود کریں"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"سبھی غیر مسدود کریں"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"مخفی چینلز"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"پروگرام پابندیاں"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"‏PIN تبدیل کریں"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"درجہ بندی کے سسٹمز"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"درجہ بندیاں"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"درجہ بندی کے سبھی سسٹمز دیکھیں"</string>
+ <string name="other_countries" msgid="8342216398676184749">"دیگر ممالک"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"کوئی نہیں"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"کوئی نہیں"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"غیر درجہ بند"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"غیردرجہ بند پروگرام مسدود کریں"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"کوئی نہیں"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"زیادہ پابندیاں"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"متوسط پابندیاں"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"کم پابندیاں"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"حسب ضرورت"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"بچوں کیلئے مناسب مواد"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"بڑی عمر کے بچوں کیلئے مناسب مواد"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"نوعمروں کیلئے مناسب مواد"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"دستی پابندیاں"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"‏%1$s اور ذیلی درجہ بندیاں"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"ذیلی درجہ بندیاں"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"‏یہ چینل دیکھنے کیلئے اپنا PIN درج کریں"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"‏یہ پروگرام دیکھنے کیلئے اپنا PIN درج کریں"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"‏اس پروگرام کی درجہ بندی <xliff:g id="RATING">%1$s</xliff:g> ہوئی ہے۔ اس پروگرام کو دیکھنے کیلئے اپنی PIN درج کریں"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"‏یہ پروگرام درجہ بند نہیں ہے۔ اس پروگرام کو دیکھنے کے لیے اپنا PIN درج کریں"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"‏اپنا PIN درج کریں"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"‏پیرنٹل کنٹرولز سیٹ کرنے کیلئے، ایک PIN بنائیں"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"‏نیا PIN درج کریں"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"‏اپنے PIN کی توثیق کریں"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"‏اپنا موجودہ PIN درج کریں"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">‏آپ نے 5 بار غلط PIN درج کی۔\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> سیکنڈز بعد دوبارہ کوشش کریں۔</item>
+ <item quantity="one">‏آپ نے 5 بار غلط PIN درج کی۔\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> سیکنڈ بعد دوبارہ کوشش کریں۔</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"‏وہ PIN غلط تھا۔ دوبارہ کوشش کریں۔"</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"‏دوبارہ کوشش کریں، PIN مماثل نہیں ہے"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"اپنا زپ کوڈ درج کریں۔"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"‏لائیو چینلز ایپ TV چینلز کیلئے ایک مکمل پروگرام گائیڈ فراہم کرنے کیلئے زپ کوڈ استعمال کرے گی۔"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"اپنا زپ کوڈ درج کریں"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"غلط زپ کوڈ"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"ترتیبات"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"چینل فہرست حسب ضرورت بنائیں"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"اپنی پروگرام گائیڈ کیلئے چینلز منتخب کریں"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"چینل کے مآخذ"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"نئے چینلز دستیاب ہیں"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"پیرنٹل کنٹرولز"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"ٹائم شفٹ"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"دیکھنے کے دوران ریکارڈ کریں تاکہ آپ لائیو پروگرامز کو موقوف یا ریوائنڈ کر سکیں۔\nتنبیہ: اس کے باعث اسٹوریج کے بے تحاشا استعمال کی وجہ سے شاید اندرونی اسٹوریج کی زندگی کم ہو جائے۔"</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"اوپن سورس لائسنسز"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"تاثرات بھیجیں"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"ورژن"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"‏یہ چینل دیکھنے کیلئے Right دبائیں اور اپنا PIN درج کریں"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"‏یہ پروگرام دیکھنے کیلئے Right دبائیں اور اپنا PIN درج کریں"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"‏یہ پروگرام درجہ بند نہیں ہے۔\nاس پروگرام کو دیکھنے کے لیے، دائیں جانب دبا کر اپنا PIN درج کریں"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"‏اس پروگرام کی درجہ بندی <xliff:g id="RATING">%1$s</xliff:g> کی گئی ہے۔\nاس پروگرام کو دیکھنے کیلئے Right دبائیں اور اپنا PIN درج کریں"</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"‏اس چینل کو دیکھنے کیلئے ڈیفالٹ لائیو TV ایپ استعمال کریں۔"</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"‏اس پروگرام کو دیکھنے کیلئے ڈیفالٹ لائیو TV ایپ استعمال کریں۔"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"‏یہ پروگرام درجہ بند نہیں ہے۔\nاس پروگرام کو دیکھنے کے لیے، ڈیفالٹ لائیو TV ایپ استعمال کریں۔"</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"‏اس پروگرام کی درجہ بندی <xliff:g id="RATING">%1$s</xliff:g> کی گئی ہے۔\nاس پروگرام کو دیکھنے کیلئے ڈیفالٹ لائیو TV ایپ استعمال کریں۔"</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"پروگرام مسدود ہے"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"یہ پروگرام درجہ بند نہیں ہے"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"اس پروگرام کی درجہ بندی <xliff:g id="RATING">%1$s</xliff:g> کی گئی ہے"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"صرف آڈیو"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"کمزور سگنل"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"کوئی انٹرنیٹ کنکشن نہیں ہے"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">یہ چینل <xliff:g id="END_TIME_1">%1$s</xliff:g> تک نہیں چلایا جا سکتا کیونکہ دوسرے چینلز کو ریکارڈ کیا جا رہا ہے۔ \n\nریکارڈنگ کا شیڈول ایڈجسٹ کرنے کیلئے دائیں طرف دبائیں۔</item>
+ <item quantity="one">یہ چینل <xliff:g id="END_TIME_0">%1$s</xliff:g> تک نہیں چلایا جا سکتا کیونکہ ایک اور چینل کو ریکارڈ کیا جا رہا ہے۔ \n\nریکارڈنگ کا شیڈول ایڈجسٹ کرنے کیلئے دائیں طرف دبائیں۔</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"کوئی عنوان نہیں ہے"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"چینل مسدود کر دیا گیا"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"نئے"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"مآخذ"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">‏%1$d چینلز</item>
+ <item quantity="one">‏%1$d چینل</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"کوئی چینلز دستیاب نہیں ہیں"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"نئے"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"ترتیب نہیں دیا گیا"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"مزید مآخذ حاصل کریں"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"لائیو چینلز کی پیشکش کرنے والی ایپس براؤز کریں"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"نئے چینل ماخذین دستیاب ہیں"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"نئے چینل ماخذین کے پاس پیشکش کیلئے چینل ہیں۔\nانہیں ابھی سیٹ اپ کریں یا چینل ماخذ ترتیب میں بعد میں کریں۔"</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"ابھی سیٹ اپ کریں"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"ٹھیک ہے، سمجھ آ گئی"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"‏TV مینو تک رسائی حاصل کرنے کیلئے "<b>"منتخب کریں کو دبائیں"</b>"۔"</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"‏کوئی TV ان پٹ نہیں ملا"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"‏TV ان پٹ تلاش نہیں کیا جا سکتا"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"‏ٹیونر کی قسم مناسب نہیں ہے۔ براہ کرم ٹیونر کی قسم والے TV ان پٹ کیلئے لائیو چینلز ایپ شروع کریں۔"</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"ٹیون کرنا ناکام ہوگیا"</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"اس کارروائی کو نمٹانے کیلئے کوئی ایپ نہیں ملی۔"</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"سبھی ماخذ چینلز مخفی ہیں۔ \nدیکھنے کیلئے کم از کم ایک چینل منتخب کریں۔"</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ویڈیو غیر متوقع طور پر دستیاب نہیں ہے"</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"‏BACK کلید منسلک آلہ کیلئے ہے۔ باہر نکلنے کیلئے HOME بٹن دبائیں۔"</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"‏لائیو چینلز کو TV فہرستیں پڑھنے کیلئے اجازت کی ضرورت ہے۔"</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"اپنے ذرائع سیٹ اپ کریں"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"‏لائیو چینلز روایتی TV چینلز کے تجربے کو ایپس کی جانب سے فراہم کردہ اسٹریمنگ چینلز سے ملاتے ہیں۔ \n\nپہلے سے انسٹال شدہ چینل ماخذین کو سیٹ اپ کر کے شروع کریں۔ یا لائیو چینلز کی پیشکش کرنے والی مزید ایپس کیلئے Google Play اسٹور براؤز کریں۔"</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"ریکارڈنگز اور شیڈولز"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 منٹ"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 منٹ"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 گھنٹہ"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 گھنٹے"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"حالیہ"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"شیڈول کردہ"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"سلسلہ"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"دیگر"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"چینل ریکارڈ نہیں ہو سکتا۔"</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"پروگرام ریکارڈ نہیں ہو سکتا۔"</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> کی ریکارڈنگ کیلئے شیڈول بن گیا ہے"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"اب سے لے کر <xliff:g id="ENDTIME">%2$s</xliff:g> تک <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ریکارڈ ہو رہا ہے"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"پورا شیڈول"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">‏اگلے ‎%1$d دن</item>
+ <item quantity="one">‏اگلا ‎%1$d دن</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">‏%1$d منٹس</item>
+ <item quantity="one">‏%1$d منٹ</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">‏%1$d نئی ریکارڈنگز</item>
+ <item quantity="one">‏%1$d نئی ریکارڈنگ</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">‏%1$d ریکارڈنگز</item>
+ <item quantity="one">‏%1$d ریکارڈنگ</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">‏%1$d ریکارڈنگز کا شیڈول بن گیا</item>
+ <item quantity="one">‏%1$d ریکارڈنگ کا شیڈول بن گيا</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"ریکارڈنگ منسوخ کریں"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"ریکارڈنگ روکیں"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"دیکھیں"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"شروع سے چلائیں"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"چلانا دوبارہ شروع کریں"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"حذف کریں"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ریکارڈنگز حذف کریں"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"دوبارہ شروع کریں"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"سیزن <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"شیڈول دیکھیں"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"مزید پڑھیں"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ریکارڈنگز حذف کریں"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"وہ ایپی سوڈز منتخب کریں جو آپ حذف کرنا چاہتے ہیں۔ ایک بار حذف ہونے کے بعد ان کو بازیاب نہیں کیا جا سکتا۔"</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"حذف کرنے کیلئے کوئی ریکارڈنگ نہیں ہے۔"</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"دیکھی گئی ایپی سوڈز منتخب کریں"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"تمام ایپی سوڈز منتخب کریں"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"تمام ایپی سوڈز غیر منتخب کریں"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> میں سے <xliff:g id="WATCHED">%1$d</xliff:g> منٹ کی دیکھ لیں"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> میں سے <xliff:g id="WATCHED">%1$d</xliff:g> سیکنڈ کی دیکھ لیں"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"کبھی نہیں دیکھیں"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">‏%2$d میں سے ‎%1$d ایپی سوڈز حذف ہو گئیں</item>
+ <item quantity="one">‏%2$d میں سے ‎%1$d ایپی سوڈ حذف ہو گئی</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ترجیح"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"سب سے اعلی"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"سب سے کم"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"نہیں۔ <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"چینلز"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"کوئی بھی"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"ترجیح کا انتخاب کریں"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"جب ایک وقت میں بہت سارے پروگرامز ریکارڈ کرنے ہوں تو صرف اعلی ترجیح والے پروگرامز ریکارڈ کیے جائیں گے۔"</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"محفوظ کریں"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"یک وقتی ریکارڈنگز کو سب سے اعلی ترجیح حاصل ہوتی ہے"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"روکیں"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ریکارڈنگ کا شیڈول ملاحظہ کریں"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"یہ واحد پروگرام"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ابھی - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"پوری سیریز…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"کسی بھی طرح شیڈول بنائیں"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"اس کی بجائے یہ ریکارڈ کریں"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"اس ریکارڈنگ کو منسوخ کریں"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"ابھی دیکھیں"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"ریکارڈنگز حذف کریں…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"قابل ریکارڈ"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ریکارڈنگ کا شیڈول"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ریکارڈنگ شیڈول میں تصادم"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ریکارڈ ہو رہا ہے"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ریکارڈنگ ناکام ہو گئی"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"پروگرامز پڑھے جا رہے ہیں"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"حالیہ ریکارڈنگز ملاحظہ کریں"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> کی ریکارڈنگ نامکمل ہے۔"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> اور <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> کی ریکارڈنگز نامکمل ہیں۔"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>، <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> اور <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> کی ریکارڈنگز نامکمل ہیں۔"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"ناکافی اسٹوریج کی وجہ سے <xliff:g id="PROGRAMNAME">%1$s</xliff:g> کی ریکارڈنگ مکمل نہیں ہوئی۔"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"ناکافی اسٹوریج کی وجہ سے <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> اور <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> کی ریکارڈنگز مکمل نہیں ہوئیں۔"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"ناکافی اسٹوریج کی وجہ سے <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>، <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> اور <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> کی ریکارڈنگز مکمل نہیں ہوئیں۔"</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"‏DVR کو مزید اسٹوریج درکار ہے"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"‏آپ DVR کے ساتھ پروگرامز ریکارڈ کر سکیں گے۔ تاہم آپ کے آلہ پر DVR کے کام کرنے کیلئے ابھی کافی اسٹوریج نہیں ہے۔ براہ کرم ایک بیرونی ڈرائیو منسلک کریں جو GB <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> یا اس سے بڑی ہو اور اسے آلہ کی اسٹوریج کے بطور فارمیٹ کرنے کیلئے مراحل کی پیروی کریں۔"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"اسٹوریج کافی نہیں ہے"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"یہ پروگرام ریکارڈ نہیں ہوگا کیونکہ اسٹوریج کافی نہیں ہے۔ کچھ موجودہ ریکارڈنگز حذف کرنے کی کوشش کریں۔"</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"اسٹوریج غائب ہے"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ریکارڈنگ روکیں؟"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ریکارڈ شدہ مواد محفوظ ہو جائے گا۔"</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> کی ریکارڈنگ روک دی جائے گی کیونکہ یہ اس پروگرام کے ساتھ متضاد ہے۔ ریکارڈ کردہ مواد محفوظ ہو جائے گا۔"</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ریکارڈنگ کا شیڈول لیکن تضادات"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ریکارڈنگ شروع ہو گئی ہے لیکن اس میں تضادات ہیں"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ریکارڈ ہوجائے گا۔"</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ریکارڈ ہو رہا ہے۔"</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> کے کچھ حصے ریکارڈ نہیں ہوں گے۔"</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> اور <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> کے کچھ حصے ریکارڈ نہیں ہوں گے۔"</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>، <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> کے کچھ حصے اور ایک اور شیڈول ریکارڈ نہیں ہوگا۔"</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other">‏<xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>، <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> کے کچھ حصے اور ‎%3$d مزید شیڈولز ریکارڈ نہیں ہوں گے۔</item>
+ <item quantity="one">‏<xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>، <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> کے کچھ حصے اور ‎%3$d مزید شیڈول ریکارڈ نہیں ہوگا۔</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"آپ کیا ریکارڈ کرنا چاہیں گے؟"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"آپ کتنی دیر تک ریکارڈ کرنا پسند کریں گے؟"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"پہلے سے شیڈول کردہ"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"اسی پروگرام کا پہلے ہی <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> بجے ریکارڈ ہونے کیلئے شیڈول بنا ہوا ہے۔"</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"پہلے سے ریکارڈ شدہ"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"‏یہ پروگرام پہلے سے ہی ریکارڈ شدہ ہے۔ یہ DVR لائبریری میں دستیاب ہے۔"</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"سیریز کی ریکارڈنگ کا شیڈول بن گیا ہے"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> کیلئے <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ریکارڈنگز کا شیڈول بن گیا ہے۔</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> کیلئے <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ریکارڈنگ کا شیڈول بن گیا ہے۔</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> کیلئے <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ریکارڈنگز کا شیڈول بن گیا ہے۔ تضادات کی وجہ سے ان میں سے <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> ریکارڈ نہیں ہوں گی۔</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> کیلئے <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ریکارڈنگ کا شیڈول بن گیا ہے۔ تضادات کی وجہ سے اس کی ریکارڈنگ نہیں ہو گی۔</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> کیلئے <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ریکارڈنگز کا شیڈول بن گیا ہے۔ تضادات کی وجہ سے اس سیریز اور دیگر سیریز کی <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> اقساط ریکارڈ نہیں ہوں گی۔</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> کیلئے <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ریکارڈنگ کا شیڈول بن گیا ہے۔ تضادات کی وجہ سے اس سیریز اور دیگر سیریز کی <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> اقساط ریکارڈ نہیں ہوں گی۔</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> کیلئے <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ریکارڈنگز کا شیڈول بن گیا ہے۔ تضادات کی وجہ سے دیگر سیریز کی 1 قسط ریکارڈ نہیں ہو گی۔</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> کیلئے <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ریکارڈنگ کا شیڈول بن گیا ہے۔ تضادات کی وجہ سے دیگر سیریز کی 1 قسط ریکارڈ نہیں ہو گی۔</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> کیلئے <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ریکارڈنگز کا شیڈول بن گیا ہے۔ تضادات کی وجہ سے دیگر سیریز کی <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> اقساط ریکارڈ نہیں ہوں گی۔</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> کیلئے <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ریکارڈنگ کا شیڈول بن گیا ہے۔ تضادات کی وجہ سے دیگر سیریز کی <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> اقساط ریکارڈ نہیں ہوں گی۔</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"ریکارڈ شدہ پروگرام نہیں ملا۔"</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"متعلقہ ریکارڈنگز"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">‏%1$d ریکارڈنگز</item>
+ <item quantity="one">‏%1$d ریکارڈنگ</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> کو ریکارڈنگ شیڈول سے ہٹا دیا گیا"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ٹیونر تضادات کی وجہ سے جزوی طور پر ریکارڈ ہوگا۔"</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ٹیونر تضادات کی وجہ سے ریکارڈ نہیں ہوگا۔"</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ابھی شیڈول میں کوئی ریکارڈنگز نہیں ہیں۔\nآپ پروگرام گائیڈ سے ریکارڈنگ کا شیڈول بنا سکتے ہیں۔"</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">‏%1$d ریکارڈنگ تنازعات</item>
+ <item quantity="one">‏%1$d ریکارڈنگ تنازعہ</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"سیریز کی ترتیبات"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"سیریز کی ریکارڈنگ شروع کریں"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"سیریز کی ریکارڈنگ روکیں"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"سیریز ریکارڈنگ روکیں؟"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"‏ریکارڈ شدہ ایپی سوڈز DVR لائبریری میں دستیاب رہیں گے۔"</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"روکیں"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"ابھی کوئی ایپی سوڈ آن ائیر نہیں ہے۔"</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"کوئی ایپی سوڈز دستیاب نہیں۔\nایک بار دستیاب ہوجائے تو ان کو ریکارڈ کیا جائے گا۔"</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">‏(%1$d منٹ)</item>
+ <item quantity="one">‏(%1$d منٹ) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"ﺁﺝ"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"آئندہ کل"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"گزشتہ کل"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> آج"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> آئندہ کل"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"اسکور"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"ریکارڈ شدہ پروگرامز"</string>
+</resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
deleted file mode 100644
index 47fcb2ad..00000000
--- a/res/values-ur/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"مونو"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"اسٹیریو"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"پلے کنٹرولز"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"حالیہ چینلز"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"‏TV کے اختیارات"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"‏PIP کے اختیارات"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"چلانے کے کنٹرولز اس چینل کیلئے غیر دستیاب ہیں"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"چلائیں یا موقوف کریں"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"تیزی سے فارورڈ کریں"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"ریوائینڈ کریں"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"آگے"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"پچھلا"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"پروگرام گائیڈ"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"نئے چینلز دستیاب ہیں"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> کھولیں"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"سب ٹائٹلز"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"ڈسپلے وضع"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"آن"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"آف"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"کثیر آڈیو"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"مزید چینلز حاصل کریں"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"ترتیبات"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"ماخذ"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"تبادلہ کریں"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"آن"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"آف"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"آواز"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"مرکزی"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"‏PIP ونڈو"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"لے آؤٹ"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"نیچے دائیں"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"اوپری دائیں"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"اوپری بائیں"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"نیچے بائیں"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"سمت بہ سمت"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"سائز"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"بڑا"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"چھوٹا"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"ان پٹ ماخذ"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"‏TV (اینٹینا/کیبل)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"پروگرام کی معلومات نہیں"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"کوئی معلومات نہیں ہے"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"مسدود چینل"</string>
- <string name="default_language" msgid="4122326459624337928">"نامعلوم زبان"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"سب ٹائٹلز"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"آف"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"فارمیٹنگ کسٹمائز کریں"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"سب ٹائٹل کیلئے سسٹم وار ترجیحات سیٹ کریں"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"ڈسپلے وضع"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"کثیر آڈیو"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"مونو"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"اسٹیریو"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 گھیر"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 گھیر"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"‏‎%d چینلز"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"چینل لسٹ کسٹمائز کریں"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"گروپ منتخب کریں"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"گروپ غیر منتخب کریں"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"گروپ بلحاظ"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"چینل ماخذ"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"گروپ بلحاظ"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"یہ پروگرام مسدود ہے"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"اس پروگرام کی درجہ بندی <xliff:g id="RATING">%1$s</xliff:g> کی گئی ہے"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"ان پٹ آٹو اسکین کو سپورٹ نہیں کرتا"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"\'<xliff:g id="TV_INPUT">%s</xliff:g>\' کیلئے آٹو اسکین شروع کرنے سے قاصر ہے"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"سب ٹائٹلز کیلئے سسٹم وار ترجیحات شروع کرنے سے قاصر ہے۔"</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">‏%1$d چینل شامل ہو گئے</item>
- <item quantity="one">‏%1$d چینل شامل ہو گیا</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"کوئی چینلز شامل نہیں کیے گئے"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"ٹیونر"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"پیرنٹل کنٹرولز"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"آن"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"آف"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"چینلز مسدود کر دیے"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"سبھی کو مسدود کریں"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"سبھی غیر مسدود کریں"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"مخفی چینلز"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"پروگرام پابندیاں"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"‏PIN تبدیل کریں"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"درجہ بندی کے سسٹمز"</string>
- <string name="option_ratings" msgid="4009116954188688616">"درجہ بندیاں"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"درجہ بندی کے سبھی سسٹمز دیکھیں"</string>
- <string name="other_countries" msgid="8342216398676184749">"دیگر ممالک"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"کوئی نہیں"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"کوئی نہیں"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"کوئی نہیں"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"زیادہ پابندیاں"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"متوسط پابندیاں"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"کم پابندیاں"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"حسب ضرورت"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"بچوں کیلئے مناسب مواد"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"بڑی عمر کے بچوں کیلئے مناسب مواد"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"نوعمروں کیلئے مناسب مواد"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"دستی پابندیاں"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"‏%1$s اور ذیلی درجہ بندیاں"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"ذیلی درجہ بندیاں"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"‏یہ چینل دیکھنے کیلئے اپنا PIN درج کریں"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"‏یہ پروگرام دیکھنے کیلئے اپنا PIN درج کریں"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"‏اس پروگرام کی درجہ بندی <xliff:g id="RATING">%1$s</xliff:g> ہوئی ہے۔ اس پروگرام کو دیکھنے کیلئے اپنی PIN درج کریں"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"‏اپنا PIN درج کریں"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"‏پیرنٹل کنٹرولز سیٹ کرنے کیلئے، ایک PIN بنائیں"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"‏نیا PIN درج کریں"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"‏اپنے PIN کی توثیق کریں"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"‏اپنا موجودہ PIN درج کریں"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">‏آپ نے 5 بار غلط PIN درج کی۔\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> سیکنڈز بعد دوبارہ کوشش کریں۔</item>
- <item quantity="one">‏آپ نے 5 بار غلط PIN درج کی۔\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> سیکنڈ بعد دوبارہ کوشش کریں۔</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"‏وہ PIN غلط تھا۔ دوبارہ کوشش کریں۔"</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"‏دوبارہ کوشش کریں، PIN مماثل نہیں ہے"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"ترتیبات"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"چینل فہرست حسب ضرورت بنائیں"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"اپنی پروگرام گائیڈ کیلئے چینلز منتخب کریں"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"چینل کے مآخذ"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"نئے چینلز دستیاب ہیں"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"پیرنٹل کنٹرولز"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"اوپن سورس لائسنسز"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"اوپن سورس لائسنسز"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"ورژن"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"‏یہ چینل دیکھنے کیلئے Right دبائیں اور اپنا PIN درج کریں"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"‏یہ پروگرام دیکھنے کیلئے Right دبائیں اور اپنا PIN درج کریں"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"‏اس پروگرام کی درجہ بندی <xliff:g id="RATING">%1$s</xliff:g> کی گئی ہے۔\nاس پروگرام کو دیکھنے کیلئے Right دبائیں اور اپنا PIN درج کریں"</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"‏اس چینل کو دیکھنے کیلئے ڈیفالٹ لائیو TV ایپ استعمال کریں۔"</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"‏اس پروگرام کو دیکھنے کیلئے ڈیفالٹ لائیو TV ایپ استعمال کریں۔"</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"‏اس پروگرام کی درجہ بندی <xliff:g id="RATING">%1$s</xliff:g> کی گئی ہے۔\nاس پروگرام کو دیکھنے کیلئے ڈیفالٹ لائیو TV ایپ استعمال کریں۔"</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"پروگرام مسدود ہے"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"اس پروگرام کی درجہ بندی <xliff:g id="RATING">%1$s</xliff:g> کی گئی ہے"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"صرف آڈیو"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"کمزور سگنل"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"کوئی انٹرنیٹ کنکشن نہیں ہے"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">یہ چینل <xliff:g id="END_TIME_1">%1$s</xliff:g> تک نہیں چلایا جا سکتا کیونکہ دوسرے چینلز کو ریکارڈ کیا جا رہا ہے۔ \n\nریکارڈنگ کا شیڈول ایڈجسٹ کرنے کیلئے دائیں طرف دبائیں۔</item>
- <item quantity="one">یہ چینل <xliff:g id="END_TIME_0">%1$s</xliff:g> تک نہیں چلایا جا سکتا کیونکہ ایک اور چینل کو ریکارڈ کیا جا رہا ہے۔ \n\nریکارڈنگ کا شیڈول ایڈجسٹ کرنے کیلئے دائیں طرف دبائیں۔</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"کوئی عنوان نہیں ہے"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"چینل مسدود کر دیا گیا"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"نئے"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"مآخذ"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">‏%1$d چینلز</item>
- <item quantity="one">‏%1$d چینل</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"کوئی چینلز دستیاب نہیں ہیں"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"نئے"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"ترتیب نہیں دیا گیا"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"مزید مآخذ حاصل کریں"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"لائیو چینلز کی پیشکش کرنے والی ایپس براؤز کریں"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"نئے چینل ماخذین دستیاب ہیں"</string>
- <string name="new_sources_description" msgid="749649005588426813">"نئے چینل ماخذین کے پاس پیشکش کیلئے چینل ہیں۔\nانہیں ابھی سیٹ اپ کریں یا چینل ماخذ ترتیب میں بعد میں کریں۔"</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"ابھی سیٹ اپ کریں"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"ٹھیک ہے، سمجھ آ گئی"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"‏TV مینو تک رسائی حاصل کرنے کیلئے "<b>"منتخب کریں کو دبائیں"</b>"۔"</string>
- <string name="msg_no_input" msgid="3897674146985427865">"‏کوئی TV ان پٹ نہیں ملا"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"‏TV ان پٹ تلاش نہیں کیا جا سکتا"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"‏PIP تعاون یافتہ نہیں ہے"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"‏ایسا کوئی ان پٹ دستیاب نہیں ہے جسے PIP کے ساتھ دکھایا جا سکے"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"‏ٹیونر کی قسم مناسب نہیں ہے۔ براہ کرم ٹیونر کی قسم والے TV ان پٹ کیلئے لائیو چینلز ایپ شروع کریں۔"</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"ٹیون کرنا ناکام ہوگیا"</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"اس کارروائی کو نمٹانے کیلئے کوئی ایپ نہیں ملی۔"</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"سبھی ماخذ چینلز مخفی ہیں۔ \nدیکھنے کیلئے کم از کم ایک چینل منتخب کریں۔"</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"ویڈیو غیر متوقع طور پر دستیاب نہیں ہے"</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"‏BACK کلید منسلک آلہ کیلئے ہے۔ باہر نکلنے کیلئے HOME بٹن دبائیں۔"</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"‏لائیو چینلز کو TV فہرستیں پڑھنے کیلئے اجازت کی ضرورت ہے۔"</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"اپنے ذرائع سیٹ اپ کریں"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"‏لائیو چینلز روایتی TV چینلز کے تجربے کو ایپس کی جانب سے فراہم کردہ اسٹریمنگ چینلز سے ملاتے ہیں۔ \n\nپہلے سے انسٹال شدہ چینل ماخذین کو سیٹ اپ کر کے شروع کریں۔ یا لائیو چینلز کی پیشکش کرنے والی مزید ایپس کیلئے Google Play اسٹور براؤز کریں۔"</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"ریکارڈنگز اور شیڈولز"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 منٹ"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 منٹ"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 گھنٹہ"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 گھنٹے"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"حالیہ"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"شیڈول کردہ"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"سلسلہ"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"دیگر"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"چینل ریکارڈ نہیں ہو سکتا۔"</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"پروگرام ریکارڈ نہیں ہو سکتا۔"</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> کی ریکارڈنگ کیلئے شیڈول بن گیا ہے"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"اب سے لے کر <xliff:g id="ENDTIME">%2$s</xliff:g> تک <xliff:g id="PROGRAMNAME">%1$s</xliff:g> ریکارڈ ہو رہا ہے"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"پورا شیڈول"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">‏اگلے ‎%1$d دن</item>
- <item quantity="one">‏اگلا ‎%1$d دن</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">‏%1$d منٹس</item>
- <item quantity="one">‏%1$d منٹ</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">‏%1$d نئی ریکارڈنگز</item>
- <item quantity="one">‏%1$d نئی ریکارڈنگ</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">‏%1$d ریکارڈنگز</item>
- <item quantity="one">‏%1$d ریکارڈنگ</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">‏%1$d ریکارڈنگز کا شیڈول بن گیا</item>
- <item quantity="one">‏%1$d ریکارڈنگ کا شیڈول بن گيا</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"دیکھیں"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"شروع سے چلائیں"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"چلانا دوبارہ شروع کریں"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"حذف کریں"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"ریکارڈنگز حذف کریں"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"دوبارہ شروع کریں"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"سیزن <xliff:g id="SEASON_NUMBER">%1$s</xliff:g>"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"شیڈول دیکھیں"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"مزید پڑھیں"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"ریکارڈنگز حذف کریں"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"وہ ایپی سوڈز منتخب کریں جو آپ حذف کرنا چاہتے ہیں۔ ایک بار حذف ہونے کے بعد ان کو بازیاب نہیں کیا جا سکتا۔"</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"حذف کرنے کیلئے کوئی ریکارڈنگ نہیں ہے۔"</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"دیکھی گئی ایپی سوڈز منتخب کریں"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"تمام ایپی سوڈز منتخب کریں"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"تمام ایپی سوڈز غیر منتخب کریں"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"<xliff:g id="DURATION">%2$d</xliff:g> میں سے <xliff:g id="WATCHED">%1$d</xliff:g> منٹ کی دیکھ لیں"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"<xliff:g id="DURATION">%2$d</xliff:g> میں سے <xliff:g id="WATCHED">%1$d</xliff:g> سیکنڈ کی دیکھ لیں"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"کبھی نہیں دیکھیں"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">‏%2$d میں سے ‎%1$d ایپی سوڈز حذف ہو گئیں</item>
- <item quantity="one">‏%2$d میں سے ‎%1$d ایپی سوڈ حذف ہو گئی</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"ترجیح"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"سب سے اعلی"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"سب سے کم"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"نہیں۔ <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"چینلز"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"کوئی بھی"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"ترجیح کا انتخاب کریں"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"جب ایک وقت میں بہت سارے پروگرامز ریکارڈ کرنے ہوں تو صرف اعلی ترجیح والے پروگرامز ریکارڈ کیے جائیں گے۔"</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"محفوظ کریں"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"یک وقتی ریکارڈنگز کو سب سے اعلی ترجیح حاصل ہوتی ہے"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"منسوخ کریں"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"منسوخ کریں"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"بھول جائیں"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"روکیں"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"ریکارڈنگ کا شیڈول ملاحظہ کریں"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"یہ واحد پروگرام"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"ابھی - <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"پوری سیریز…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"کسی بھی طرح شیڈول بنائیں"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"اس کی بجائے یہ ریکارڈ کریں"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"اس ریکارڈنگ کو منسوخ کریں"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"ابھی دیکھیں"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"قابل ریکارڈ"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"ریکارڈنگ کا شیڈول"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"ریکارڈنگ شیڈول میں تصادم"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"ریکارڈ ہو رہا ہے"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"ریکارڈنگ ناکام ہو گئی"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"ریکارڈنگ کے شیڈولز بنانے کیلئے پروگرام پڑھے جا رہے ہیں"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"پروگرامز پڑھے جا رہے ہیں"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"‏DVR کو مزید اسٹوریج درکار ہے"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"‏آپ DVR کے ساتھ پروگرامز ریکارڈ کر سکیں گے۔ تاہم آپ کے آلہ پر DVR کے کام کرنے کیلئے ابھی کافی اسٹوریج نہیں ہے۔ براہ کرم ایک بیرونی ڈرائیو منسلک کریں جو GB <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> یا اس سے بڑی ہو اور اسے آلہ کی اسٹوریج کے بطور فارمیٹ کرنے کیلئے مراحل کی پیروی کریں۔"</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"اسٹوریج غائب ہے"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"‏DVR کی استعمال کردہ کچھ اسٹوریج غائب ہے۔ براہ کرم وہ بیرونی ڈرائیو جو آپ نے پہلے DVR کو دوبارہ فعال کرنے کیلئے استعمال کی تھی، منسلک کریں۔ متبادل طور پر، اگر یہ مزید دستیاب نہ ہو تو آپ اسٹوریج کو بھولنے کا انتخاب کر سکتے ہیں۔"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"اسٹوریج کو بھول جائیں؟"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"آپ کا تمام ریکارڈ کردہ مواد اور شیڈولز ضائع ہو جائیں گے۔"</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"ریکارڈنگ روکیں؟"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"ریکارڈ شدہ مواد محفوظ ہو جائے گا۔"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"ریکارڈنگ کا شیڈول لیکن تضادات"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"ریکارڈنگ شروع ہو گئی ہے لیکن اس میں تضادات ہیں"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> ریکارڈ ہوجائے گا۔"</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"<xliff:g id="CHANNELNAME">%1$s</xliff:g> ریکارڈ ہو رہا ہے۔"</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g> کے کچھ حصے ریکارڈ نہیں ہوں گے۔"</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g> اور <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> کے کچھ حصے ریکارڈ نہیں ہوں گے۔"</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>، <xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g> کے کچھ حصے اور ایک اور شیڈول ریکارڈ نہیں ہوگا۔"</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other">‏<xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>، <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> کے کچھ حصے اور ‎%3$d مزید شیڈولز ریکارڈ نہیں ہوں گے۔</item>
- <item quantity="one">‏<xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>، <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> کے کچھ حصے اور ‎%3$d مزید شیڈول ریکارڈ نہیں ہوگا۔</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"آپ کیا ریکارڈ کرنا چاہیں گے؟"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"آپ کتنی دیر تک ریکارڈ کرنا پسند کریں گے؟"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"پہلے سے شیڈول کردہ"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"اسی پروگرام کا پہلے ہی <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> بجے ریکارڈ ہونے کیلئے شیڈول بنا ہوا ہے۔"</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"پہلے سے ریکارڈ شدہ"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"‏یہ پروگرام پہلے سے ہی ریکارڈ شدہ ہے۔ یہ DVR لائبریری میں دستیاب ہے۔"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"ریکارڈ شدہ پروگرام نہیں ملا۔"</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"متعلقہ ریکارڈنگز"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(پروگرام کی کوئی تفصیل نہیں)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">‏%1$d ریکارڈنگز</item>
- <item quantity="one">‏%1$d ریکارڈنگ</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> کو ریکارڈنگ شیڈول سے ہٹا دیا گیا"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"ٹیونر تضادات کی وجہ سے جزوی طور پر ریکارڈ ہوگا۔"</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"ٹیونر تضادات کی وجہ سے ریکارڈ نہیں ہوگا۔"</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"ابھی شیڈول میں کوئی ریکارڈنگز نہیں ہیں۔\nآپ پروگرام گائیڈ سے ریکارڈنگ کا شیڈول بنا سکتے ہیں۔"</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">‏%1$d ریکارڈنگ تنازعات</item>
- <item quantity="one">‏%1$d ریکارڈنگ تنازعہ</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"سیریز کی ترتیبات"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"سیریز کی ریکارڈنگ شروع کریں"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"سیریز کی ریکارڈنگ روکیں"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"سیریز ریکارڈنگ روکیں؟"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"‏ریکارڈ شدہ ایپی سوڈز DVR لائبریری میں دستیاب رہیں گے۔"</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"روکیں"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"کوئی ایپی سوڈز دستیاب نہیں۔\nایک بار دستیاب ہوجائے تو ان کو ریکارڈ کیا جائے گا۔"</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">‏(%1$d منٹ)</item>
- <item quantity="one">‏(%1$d منٹ) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"ﺁﺝ"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"آئندہ کل"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"گزشتہ کل"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> آج"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> آئندہ کل"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"اسکور"</string>
-</resources>
diff --git a/res/values-uz-v23/strings.xml b/res/values-uz-rUZ-v23/strings.xml
index 9d1c1de7..9d1c1de7 100644
--- a/res/values-uz-v23/strings.xml
+++ b/res/values-uz-rUZ-v23/strings.xml
diff --git a/res/values-uz/arrays.xml b/res/values-uz-rUZ/arrays.xml
index 71619002..71619002 100644
--- a/res/values-uz/arrays.xml
+++ b/res/values-uz-rUZ/arrays.xml
diff --git a/res/values-uz/rating_system_strings.xml b/res/values-uz-rUZ/rating_system_strings.xml
index 91d82748..91d82748 100644
--- a/res/values-uz/rating_system_strings.xml
+++ b/res/values-uz-rUZ/rating_system_strings.xml
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
new file mode 100644
index 00000000..ff37421d
--- /dev/null
+++ b/res/values-uz-rUZ/strings.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
+ <string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
+ <string name="menu_title_play_controls" msgid="2490237359425190652">"Boshqaruv"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kanallar"</string>
+ <string name="menu_title_options" msgid="7184594626814914022">"TV sozlamalari"</string>
+ <string name="play_controls_unavailable" msgid="8900698593131693148">"Ushbu kanal uchun ijro etish boshqaruvlari mavjud emas"</string>
+ <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Ijro yoki pauza"</string>
+ <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Oldinga tezkor o‘tkazish"</string>
+ <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Orqaga o‘tkazish"</string>
+ <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Keyingisi"</string>
+ <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Avvalgi"</string>
+ <string name="channels_item_program_guide" msgid="2889807207930678418">"Tele-yo‘lboshchi"</string>
+ <string name="channels_item_setup" msgid="6557412175737379022">"Yangi kanallar mavjud"</string>
+ <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasini ochish"</string>
+ <string name="options_item_closed_caption" msgid="5945274655046367170">"Taglavhalar"</string>
+ <string name="options_item_display_mode" msgid="7989243076748680140">"Ekran rejimi"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"Kadr ustida kadr"</string>
+ <string name="options_item_multi_audio" msgid="5118851311937896923">"Ko‘p kanalli"</string>
+ <string name="options_item_more_channels" msgid="971040969622943300">"Boshqa kanallar"</string>
+ <string name="options_item_settings" msgid="7623205838542400074">"Sozlamalar"</string>
+ <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenna/kabel)"</string>
+ <string name="no_program_information" msgid="1049844207745145132">"Dastur haqida ma’l. yo‘q"</string>
+ <string name="program_title_for_no_information" msgid="384451471906070101">"Ma’lumot yo‘q"</string>
+ <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Bloklangan kanal"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Noma’lum til"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Taglavhalar %1$d"</string>
+ <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Taglavhalar"</string>
+ <string name="closed_caption_option_item_off" msgid="4824009036785647753">"O‘chiq"</string>
+ <string name="closed_caption_system_settings" msgid="1856974607743827178">"Formatlarni sozlash"</string>
+ <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Taglavhalar uchun tizim sozlamalari"</string>
+ <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Ekran rejimi"</string>
+ <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Ko‘p kanalli"</string>
+ <string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
+ <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"stereo"</string>
+ <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 qamrovli"</string>
+ <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 qamrovli"</string>
+ <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ta kanal"</string>
+ <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Ro‘yxatni sozlash"</string>
+ <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Guruhni tanlash"</string>
+ <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Guruhni o‘chirish"</string>
+ <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Guruhlash tartibi"</string>
+ <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Kanal manbasi"</string>
+ <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
+ <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
+ <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
+ <string name="side_panel_title_group_by" msgid="1783176601425788939">"Guruhlash tartibi"</string>
+ <string name="program_guide_content_locked" msgid="198056836554559553">"Bu dastur bloklangan"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Bu dastur tasniflanmagan"</string>
+ <string name="program_guide_content_locked_format" msgid="514915272862967389">"Bu dastur uchun yosh cheklovi: <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="msg_no_setup_activity" msgid="7746893144640239857">"Bu kirish avtomatik qidiruvni qo‘llab-quvvatlamaydi"</string>
+ <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"“<xliff:g id="TV_INPUT">%s</xliff:g>” uchun avtomatik qidiruvni boshlab bo‘lmadi"</string>
+ <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Taglavhalar uchun tizim sozlamalarini ochib bo‘lmadi."</string>
+ <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
+ <item quantity="other">%1$d ta kanal qo‘shildi</item>
+ <item quantity="one">%1$d ta kanal qo‘shildi</item>
+ </plurals>
+ <string name="msg_no_channel_added" msgid="2882586037409921925">"Kanal qo‘shilmadi"</string>
+ <string name="menu_parental_controls" msgid="2474294054521345840">"Ota-ona nazorati"</string>
+ <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Yoniq"</string>
+ <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"O‘chiq"</string>
+ <string name="option_channels_locked" msgid="5797855082297549907">"Kanallar bloklandi"</string>
+ <string name="option_channels_lock_all" msgid="6594512884477342940">"Hammasini bloklash"</string>
+ <string name="option_channels_unlock_all" msgid="6839513296447567623">"Blokdan chiqarish"</string>
+ <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Berkitilgan kanallar"</string>
+ <string name="option_program_restrictions" msgid="241342023067364108">"Yosh cheklovlari"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"PIN kodni o‘zgartirish"</string>
+ <string name="option_country_rating_systems" msgid="7288569813945260224">"Reyting tizimlari"</string>
+ <string name="option_ratings" msgid="4009116954188688616">"Reytinglar"</string>
+ <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Barcha reyting tizimlari"</string>
+ <string name="other_countries" msgid="8342216398676184749">"Boshqa mamlakatlar"</string>
+ <string name="option_no_locked_channel" msgid="2543094883927978444">"Hech biri"</string>
+ <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Hech biri"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Tasniflanmagan"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Tasniflanmagan dasturlarni bloklash"</string>
+ <string name="option_rating_none" msgid="5204552587760414879">"Hech biri"</string>
+ <string name="option_rating_high" msgid="8898400296730158893">"Qat’iy cheklovlar"</string>
+ <string name="option_rating_medium" msgid="6455853836426497151">"O‘rtacha cheklovlar"</string>
+ <string name="option_rating_low" msgid="5800146024503377969">"Yengil cheklovlar"</string>
+ <string name="option_rating_custom" msgid="3155377834510646436">"Boshqa"</string>
+ <string name="option_rating_high_description" msgid="609567565273278745">"Kontent bolalar uchun mos"</string>
+ <string name="option_rating_medium_description" msgid="7169199016608935280">"Kontent o‘rta yoshdagi bolalar uchun mos"</string>
+ <string name="option_rating_low_description" msgid="4740109576615335045">"Kontent o‘smirlar uchun mos"</string>
+ <string name="option_rating_custom_description" msgid="6180723522991233194">"Foydalanuvchi cheklovlari"</string>
+ <!-- no translation found for option_attribution (2967657807178951562) -->
+ <skip />
+ <string name="option_subrating_title" msgid="5485055507818077595">"%1$s: sub-reytinglar"</string>
+ <string name="option_subrating_header" msgid="4637961301549615855">"Sub-reytinglar"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Bu kanalni ko‘rish uchun PIN kodni kiriting"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Bu dasturni ko‘rish uchun PIN kodni kiriting"</string>
+ <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Bu dastur uchun yosh cheklovi: <xliff:g id="RATING">%1$s</xliff:g>. Bu dasturni ko‘rish uchun PIN kodni kiriting"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Bu dastur tasniflanmagan. Mazkur dasturni tomosha qilish uchun PIN kodni kiriting"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"PIN kodni kiriting"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"Ota-ona nazoratini o‘rnatish uchun PIN-kod yarating"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"Yangi PIN kodni kiriting"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"PIN kodni kiriting"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"Joriy PIN kodni kiriting"</string>
+ <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
+ <item quantity="other">Siz PIN kodni 5 marta noto‘g‘ri kiritdingiz.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> soniyadan keyin qayta urinib ko‘ring.</item>
+ <item quantity="one">Siz PIN kodni 5 marta noto‘g‘ri kiritdingiz.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> soniyadan keyin qayta urinib ko‘ring.</item>
+ </plurals>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN-kod noto‘g‘ri, qaytadan urining."</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"Qaytadan urinib ko‘ring, PIN-kod noto‘g‘ri"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Pochta indeksini kiriting."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Jonli efir ilovasi TV kanallari uchun to‘liq teledasturlarni taqdim etish uchun pochta indeksidan foydalanadi."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Pochta indeksini kiriting"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Pochta indeksi xato"</string>
+ <string name="side_panel_title_settings" msgid="8244327316510918755">"Sozlamalar"</string>
+ <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Ro‘yxatni sozlash"</string>
+ <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Teledastur uchun kanallarni tanlash"</string>
+ <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanal manbalari"</string>
+ <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Yangi kanallar topildi"</string>
+ <string name="settings_parental_controls" msgid="5449397921700749317">"Ota-ona nazorati"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Tomosha qilayotganingizda yozib boring, bunda jonli dasturlarni pauzaga qo‘yishingiz yoki orgaga qaytarishingiz mumkin bo‘ladi.\nDiqqat! Bu funksiyasi yoqilganda, ichki xotira intensiv ishlatiladi. Natijada uning xizmat muddati qisqarishi mumkin."</string>
+ <string name="settings_menu_licenses" msgid="1257646083838406103">"Ochiq kodli DT litsenziyalari"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Fikr-mulohaza yuborish"</string>
+ <string name="settings_menu_version" msgid="2604030372029921403">"Versiyasi"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"Bu kanalni ko‘rish uchun o‘ngga qaragan chiziqni bosing va PIN kodni kiriting"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"Bu dasturni ko‘rish uchun o‘ngga qaragan chiziqni bosing va PIN kodni kiriting"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Bu dastur tasniflanmagan.\nMazkur dasturni tomosha qilish uchun o‘ngga strelkani bosing va PIN kodni kiriting"</string>
+ <string name="tvview_content_locked_format" msgid="3741874636031338247">"Bu dastur uchun yosh cheklovi: <xliff:g id="RATING">%1$s</xliff:g>.\nUshbu dasturni ko‘rish uchun o‘ngga qaragan milni bosing va PIN-kodni kiriting."</string>
+ <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Bu kanallarni ko‘rish uchun birlamchi “Jonli efir” ilovasidan foydalaning."</string>
+ <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Bu dasturni ko‘rish uchun birlamchi “Jonli efir” ilovasidan foydalaning."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Bu dastur tasniflanmagan.\nMazkur dasturni tomosha qilish uchun birlamchi Jonli efir ilovasidan foydalaning."</string>
+ <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Bu dastur uchun yosh cheklovi: <xliff:g id="RATING">%1$s</xliff:g>.\nUshbu dasturni ko‘rish uchun birlamchi “Jonli efir” ilovasidan foydalaning."</string>
+ <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Dastur bloklangan"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Bu dastur tasniflanmagan"</string>
+ <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Bu dastur uchun yosh cheklovi: <xliff:g id="RATING">%1$s</xliff:g>"</string>
+ <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Faqat audio"</string>
+ <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Signal kuchsiz"</string>
+ <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Internet aloqasi yo‘q"</string>
+ <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
+ <item quantity="other">Bu kanalni <xliff:g id="END_TIME_1">%1$s</xliff:g> gacha yoqib bo‘lmaydi, chunki boshqa kanallar yozib olinmoqda. \n\nYozib olish jadvalini o‘zgartirish uchun o‘ng strelkani bosing.</item>
+ <item quantity="one">Bu kanalni <xliff:g id="END_TIME_0">%1$s</xliff:g> gacha yoqib bo‘lmaydi, chunki boshqa kanal yozib olinmoqda. \n\nYozib olish jadvalini o‘zgartirish uchun o‘ng strelkani bosing.</item>
+ </plurals>
+ <string name="channel_banner_no_title" msgid="8660301979190693176">"Nomsiz"</string>
+ <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal bloklangan"</string>
+ <string name="setup_category_new" msgid="2899355289563443627">"Yangi"</string>
+ <string name="setup_category_done" msgid="4750902502852212319">"Manbalar"</string>
+ <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
+ <item quantity="other">%1$d ta kanal</item>
+ <item quantity="one">%1$d ta kanal</item>
+ </plurals>
+ <string name="setup_input_no_channels" msgid="1669327912393163331">"Hech qanday kanal mavjud emas"</string>
+ <string name="setup_input_new" msgid="3337725672277046798">"Yangi"</string>
+ <string name="setup_input_setup_now" msgid="1772000402336958967">"Sozlanmagan"</string>
+ <string name="setup_store_action_title" msgid="4083402039720973414">"Ko‘proq kanal manbalarini olish"</string>
+ <string name="setup_store_action_description" msgid="6820482635042445297">"Jonli kanallarni taklif etuvchi ilovalarni ko‘rish"</string>
+ <string name="new_sources_title" msgid="3878933676500061895">"Yangi kanal manbalari mavjud"</string>
+ <string name="new_sources_description" msgid="749649005588426813">"Yangi manbalar yangi kanallarni taqdim etadi.\nUlarni hozir yoki kanal manbalari sozlamalarida keyinroq sozlashingiz mumkin."</string>
+ <string name="new_sources_action_setup" msgid="177693761664016811">"Hozir sozlash"</string>
+ <string name="new_sources_action_skip" msgid="2501296961258184330">"OK"</string>
+ <!-- no translation found for intro_title (251772896916795556) -->
+ <skip />
+ <string name="intro_description" msgid="7806473686446937307">"TV menyusiga kirish uchun "<b>"TANLASH tugmasini bosing"</b>"."</string>
+ <string name="msg_no_input" msgid="3897674146985427865">"Hech qanday TV-kirish topilmadi"</string>
+ <string name="msg_no_specific_input" msgid="2688885987104249852">"TV-kirishni topib bo‘lmadi"</string>
+ <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tyuner turi mos kelmaydi. Agar TV-kirishdan foydalanayotgan bo‘lsangiz, “Jonli efir” ilovasini ishga tushiring."</string>
+ <string name="msg_tune_failed" msgid="3277419551849972252">"Sozlashni amalga oshirib bo‘lmadi."</string>
+ <string name="msg_missing_app" msgid="8291542072400042076">"Bu amalni bajara oladigan ilova topilmadi."</string>
+ <string name="msg_all_channels_hidden" msgid="777397634062471936">"Barcha kanallar berkitilgan.\nTomosha qilish uchun kamida bitta kanalni tanlang."</string>
+ <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Video kutilmaganda yo‘q bo‘lib qoldi."</string>
+ <string name="msg_back_key_guide" msgid="7404682718828721924">"ORQAGA tugmasi ulangan qurilmani boshqaradi. Chiqish uchun BOSHI tugmasini bosing."</string>
+ <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Teledasturlarni o‘qish uchun ruxsat zarur."</string>
+ <string name="setup_sources_text" msgid="4988039637873759839">"Manbalarni sozlash"</string>
+ <string name="setup_sources_description" msgid="5695518946225445202">"Jonli efirlar ilovalar tomonidan taqdim etiladigan translatsiya qilinadigan kanallar bilan an’anaviy televizor kanallarini uyg‘unlashtiradi. \n\nOldin o‘rnatilgan kanal manbalarini sozlash bilan boshlashingiz mumkin. Yoki jonli efirlarni taklif etadigan boshqa ilovalarni Google Play Market orqali ko‘rib chiqishingiz mumkin."</string>
+ <string name="channels_item_dvr" msgid="8911915252648532469">"Yozuvlar va jadvallar"</string>
+ <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 daqiqa"</string>
+ <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 daqiqa"</string>
+ <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 soat"</string>
+ <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 soat"</string>
+ <string name="dvr_main_recent" msgid="2553805424822806495">"Yaqinda"</string>
+ <string name="dvr_main_scheduled" msgid="7837260963086408492">"Rejalashtirilgan"</string>
+ <string name="dvr_main_series" msgid="8278256687595691676">"Seriallar"</string>
+ <string name="dvr_main_others" msgid="2970835573614038153">"Boshqalar"</string>
+ <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Bu kanalni yozib bo‘lmaydi."</string>
+ <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Bu dasturni yozib bo‘lmaydi."</string>
+ <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> dasturini yozib olish rejalashtirildi"</string>
+ <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> dasturini yozib olish boshlandi (<xliff:g id="ENDTIME">%2$s</xliff:g> gacha yoziladi)"</string>
+ <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"To‘liq jadval"</string>
+ <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
+ <item quantity="other">Keyingi %1$d kun</item>
+ <item quantity="one">Keyingi %1$d kun</item>
+ </plurals>
+ <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
+ <item quantity="other">%1$d daqiqa</item>
+ <item quantity="one">%1$d daqiqa</item>
+ </plurals>
+ <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
+ <item quantity="other">%1$d ta yangi yozuv</item>
+ <item quantity="one">%1$d ta yangi yozuv</item>
+ </plurals>
+ <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
+ <item quantity="other">%1$d ta yozuv</item>
+ <item quantity="one">%1$d ta yozuv</item>
+ </plurals>
+ <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
+ <item quantity="other">%1$d ta yozuv rejalashtirilgan</item>
+ <item quantity="one">%1$d ta yozuv rejalashtirilgan</item>
+ </plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Yozib olishni bekor qilish"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Yozib olishni to‘xtatish"</string>
+ <string name="dvr_detail_watch" msgid="7085694764364338215">"Tomosha qilish"</string>
+ <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Boshidan ijro etish"</string>
+ <string name="dvr_detail_resume_play" msgid="875591300274416373">"Ijroni davom ettirish"</string>
+ <string name="dvr_detail_delete" msgid="4535881013528321898">"O‘chirish"</string>
+ <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Yozuvlarni o‘chirish"</string>
+ <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Davom ettirish"</string>
+ <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-fasl"</string>
+ <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Jadvalni ko‘rish"</string>
+ <string name="dvr_detail_read_more" msgid="2588920758094498544">"Batafsil"</string>
+ <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Yozuvlarni o‘chirish"</string>
+ <string name="dvr_series_deletion_description" msgid="994839237906552969">"O‘chirib tashlash kerak bo‘lgan qismlarni tanlang. O‘chirilgach, qayta tiklab bo‘lmaydi."</string>
+ <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"O‘chirib tashlash uchun hech narsa yo‘q."</string>
+ <string name="dvr_series_select_watched" msgid="3608122404146716502">"Ko‘rilgan qismlarni belgilash"</string>
+ <string name="dvr_series_select_all" msgid="5415749261739544048">"Barcha qismlarni belgilash"</string>
+ <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Hammasini bekor qilish"</string>
+ <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"Ko‘rilgan: <xliff:g id="WATCHED">%1$d</xliff:g> daqiqa (jami: <xliff:g id="DURATION">%2$d</xliff:g> daqiqa)"</string>
+ <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"Ko‘rilgan: <xliff:g id="WATCHED">%1$d</xliff:g> soniya (jami: <xliff:g id="DURATION">%2$d</xliff:g> soniya)"</string>
+ <string name="dvr_series_never_watched" msgid="6086008065876122655">"Ko‘rilmaganlar"</string>
+ <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
+ <item quantity="other">%1$d ta qism o‘chirib tashlandi (jami: %2$d ta)</item>
+ <item quantity="one">%1$d ta qism o‘chirib tashlandi (jami: %2$d ta)</item>
+ </plurals>
+ <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Muhimlik darajasi"</string>
+ <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Eng yuqori"</string>
+ <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Eng past"</string>
+ <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"# <xliff:g id="RANK">%1$d</xliff:g>"</string>
+ <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Kanallar"</string>
+ <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Har qanday"</string>
+ <string name="dvr_priority_title" msgid="1537886929061487213">"Muhimlilik darajasini tanlash"</string>
+ <string name="dvr_priority_description" msgid="8362040921417154645">"Bir vaqtning o‘zida bir nechta dasturlar yozib olinishi kerak bo‘lsa, faqat muhimlilik darajasi yuqori dasturlargina yozib olinadi."</string>
+ <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Saqlash"</string>
+ <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Bir martalik yozuvlarning muhimlilik darajasi yuqori"</string>
+ <string name="dvr_action_stop" msgid="1378723485295471381">"To‘xtatish"</string>
+ <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Yozib olish jadvalini ko‘rish"</string>
+ <string name="dvr_action_record_episode" msgid="8596182676610326327">"Faqat bu dastur"</string>
+ <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"hozir – <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
+ <string name="dvr_action_record_series" msgid="8501991316179436899">"To‘liq serial…"</string>
+ <string name="dvr_action_record_anyway" msgid="991470058034937231">"Baribir yozib olinsin"</string>
+ <string name="dvr_action_record_instead" msgid="6821164728752215738">"Bu dasturni yozib olish"</string>
+ <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Bu yozib olishni bekor qilish"</string>
+ <string name="dvr_action_watch_now" msgid="7181211920959075976">"Tomosha qilish"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Yozuvlarni o‘chirish…"</string>
+ <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Yozib olish mumkin"</string>
+ <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Yozib olish rejalashtirildi"</string>
+ <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Yozib olish taymerida ziddiyat"</string>
+ <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Yozib olish"</string>
+ <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Yozib olib bo‘lmadi"</string>
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Dasturlar o‘qib chiqilmoqda"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Oxirgi yozuvlarni ko‘rish"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"“<xliff:g id="PROGRAMNAME">%1$s</xliff:g>” to‘liq yozib olinmadi."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"“<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>” va “<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>” to‘liq yozib olinmadi."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"“<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>”, “<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>” va “<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>” to‘liq yozib olinmadi."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Xotirada joy kamligi tufayli “<xliff:g id="PROGRAMNAME">%1$s</xliff:g>” to‘liq yozib olinmadi."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Xotirada joy kamligi tufayli “<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>” va “<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>” to‘liq yozib olinmadi."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Xotirada joy kamligi tufayli “<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>”, “<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>” va “<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>” to‘liq yozib olinmadi."</string>
+ <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR uchun ko‘proq joy kerak"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Dasturlarni DVR orqali yozib olish mumkin. Lekin hozir DVR ishlashi uchun qurilmangizda yetarli joy qolmadi. <xliff:g id="STORAGE_SIZE">%1$d</xliff:g> GB va undan katta hajmli tashqi xotira qurilmasini ulang va qurilma xotirasi sifatida formatlash uchun ko‘rsatmalarga amal qiling."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Xotirada joy yetarli emas"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Joy yetarli bo‘lmagani uchun bu dasturni yozib bo‘lmaydi. Eski yozuvlarni bir nechtasini o‘chirib tashlab ko‘ring."</string>
+ <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Xotira mavjud emas"</string>
+ <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Yozib olish to‘xtatilsinmi?"</string>
+ <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Yozib olingan kontent saqlab qo‘yiladi."</string>
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Bu dastur bilan ixtilof borligi uchun “<xliff:g id="PROGRAMNAME">%1$s</xliff:g>” dasturini yozib olish to‘xtatiladi. Yozib olingan qismi saqlab olinadi."</string>
+ <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Yozib olish rejalashtirildi, lekin ixtiloflar bor"</string>
+ <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Yozib olish jadvalida ixtiloflar bor"</string>
+ <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"“<xliff:g id="PROGRAMNAME">%1$s</xliff:g>” dasturi yozib olinadi."</string>
+ <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"“<xliff:g id="CHANNELNAME">%1$s</xliff:g>” kanalidagi video yozib olinmoqda."</string>
+ <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"“<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g>” dasturining faqat bir qismi yozib olinadi."</string>
+ <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"“<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>” va “<xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>” dasturlarining faqat bir qismi yozib olinadi."</string>
+ <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"“<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>”, “<xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>” va yana bitta dasturning faqat bir qismi yozib olinadi."</string>
+ <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
+ <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> va yana %3$d ta dasturning faqat bir qismi yozib olinadi.</item>
+ <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> va yana %3$d ta dasturning faqat bir qismi yozib olinadi.</item>
+ </plurals>
+ <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Nimalar yozib olinsin?"</string>
+ <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Qancha vaqt yozib olinsin?"</string>
+ <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Allaqachon rejalashtirilgan"</string>
+ <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Bu dasturni allaqachon <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> da yozib olish rejalashtirilgan."</string>
+ <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Dastur allaqachon yozib olingan"</string>
+ <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Bu dastur allaqachon yozib olingan. U DVR kutubxonasida saqlanadi."</string>
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Seriallarni yozib olish rejalashtirildi"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> uchun <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ta yozuv rejalashtirilgan.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> uchun <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ta yozuv rejalashtirilgan.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> uchun <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ta yozuv rejalashtirilgan. Ixtiloflar borligi uchun ulardan <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> tasi yozib olinmaydi.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> uchun <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ta yozuv rejalashtirilgan. Ixtiloflar borligi uchun u yozib olinmaydi.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> uchun <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ta yozuv rejalashtirilgan. Ixtiloflar borligi uchun bu serialning <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ta qismi va boshqa seriallar yozib olinmaydi.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> uchun <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ta yozuv rejalashtirilgan. Ixtiloflar borligi uchun bu serialning <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ta qismi va boshqa seriallar yozib olinmaydi.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="SERIESNAME_3">%2$s</xliff:g> uchun <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ta yozuv rejalashtirilgan. Ixtiloflar borligi uchun boshqa seriallarning 1 ta qismi yozib olinmaydi.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> uchun <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ta yozuv rejalashtirilgan. Ixtiloflar borligi uchun boshqa seriallarning 1 ta qismi yozib olinmaydi.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="SERIESNAME_4">%2$s</xliff:g> uchun <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ta yozuv rejalashtirilgan. Ixtiloflar borligi uchun boshqa seriallarning <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> ta qismi yozib olinmaydi.</item>
+ <item quantity="one"><xliff:g id="SERIESNAME_1">%2$s</xliff:g> uchun <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> ta yozuv rejalashtirilgan. Ixtiloflar borligi uchun boshqa seriallarning <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> ta qismi yozib olinmaydi.</item>
+ </plurals>
+ <string name="dvr_program_not_found" msgid="3282879532038010202">"Yozib olingan dasturni topib bo‘lmadi."</string>
+ <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Aloqador yozuvlar"</string>
+ <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
+ <item quantity="other">%1$d ta yozuv</item>
+ <item quantity="one">%1$d ta yozuv</item>
+ </plurals>
+ <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
+ <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> yozuvi jadvaldan olib tashlandi"</string>
+ <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Tyuner yo‘qligi sababli qisman yozib olinadi."</string>
+ <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Tyuner yo‘qligi sababli yozib olinmaydi."</string>
+ <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Jadval bo‘sh.\nTele-yo‘lboshlovchi orqali yozib olishni rejalashtirish mumkin."</string>
+ <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
+ <item quantity="other">%1$d ta yozib olish bo‘yicha ziddiyat</item>
+ <item quantity="one">%1$d ta yozib olish bo‘yicha ziddiyat</item>
+ </plurals>
+ <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Qismlar sozlamalari"</string>
+ <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Yozib olishni boshlash"</string>
+ <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Yozib olishni to‘xtatish"</string>
+ <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Yozib olish to‘xtatilsinmi?"</string>
+ <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Yozib olingan qismlar DVR kutubxonasida saqlanadi."</string>
+ <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"To‘xtatish"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Hozir hech qaysi serial qismi efirga uzatilmayapti."</string>
+ <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Hali serial qismi chiqmagan.\nEfirga chiqishi bilan yozib olinadi."</string>
+ <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
+ <item quantity="other">(%1$d daqiqa)</item>
+ <item quantity="one">(%1$d daqiqa) </item>
+ </plurals>
+ <string name="dvr_date_today" msgid="7691050705354303471">"Bugun"</string>
+ <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Ertaga"</string>
+ <string name="dvr_date_yesterday" msgid="2127672919053118239">"Kecha"</string>
+ <string name="dvr_date_today_time" msgid="8359696776305244535">"Bugun <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Ertaga <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="program_guide_critic_score" msgid="340530743913585150">"Ball"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Yozib olingan dasturlar"</string>
+</resources>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
deleted file mode 100644
index 55a0324f..00000000
--- a/res/values-uz/strings.xml
+++ /dev/null
@@ -1,350 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="audio_channel_mono" msgid="8812941280022167428">"mono"</string>
- <string name="audio_channel_stereo" msgid="5798223286366598036">"stereo"</string>
- <string name="menu_title_play_controls" msgid="2490237359425190652">"Boshqaruv"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"So‘nggi kanallar"</string>
- <string name="menu_title_options" msgid="7184594626814914022">"TV sozlamalari"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP sozlamalari"</string>
- <string name="play_controls_unavailable" msgid="8900698593131693148">"Ushbu kanal uchun ijro etish boshqaruvlari mavjud emas"</string>
- <string name="play_controls_description_play_pause" msgid="7225542861669250558">"Ijro yoki pauza"</string>
- <string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Oldinga tezkor o‘tkazish"</string>
- <string name="play_controls_description_fast_rewind" msgid="953488122681015803">"Orqaga o‘tkazish"</string>
- <string name="play_controls_description_skip_next" msgid="1603587562124694592">"Keyingisi"</string>
- <string name="play_controls_description_skip_previous" msgid="3858447678278021381">"Avvalgi"</string>
- <string name="channels_item_program_guide" msgid="2889807207930678418">"Tele-yo‘lboshchi"</string>
- <string name="channels_item_setup" msgid="6557412175737379022">"Yangi kanallar mavjud"</string>
- <string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasini ochish"</string>
- <string name="options_item_closed_caption" msgid="5945274655046367170">"Taglavhalar"</string>
- <string name="options_item_display_mode" msgid="7989243076748680140">"Ekran rejimi"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"Kadr ustida kadr"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Yoniq"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"O‘chiq"</string>
- <string name="options_item_multi_audio" msgid="5118851311937896923">"Ko‘p kanalli"</string>
- <string name="options_item_more_channels" msgid="971040969622943300">"Boshqa kanallar"</string>
- <string name="options_item_settings" msgid="7623205838542400074">"Sozlamalar"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Manba"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Almashtirish"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Yoniq"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"O‘chiq"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Ovoz"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Asosiy oyna"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP oynasi"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Joylashuvi"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Pastda o‘ngda"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Tepada o‘ngda"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Tepada chapda"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Pastda chapda"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Yonma-yon"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"O‘lchami"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Katta"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Kichik"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Kirish manbasi"</string>
- <string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (antenna/kabel)"</string>
- <string name="no_program_information" msgid="1049844207745145132">"Dastur haqida ma’l. yo‘q"</string>
- <string name="program_title_for_no_information" msgid="384451471906070101">"Ma’lumot yo‘q"</string>
- <string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Bloklangan kanal"</string>
- <string name="default_language" msgid="4122326459624337928">"Noma’lum til"</string>
- <string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Taglavhalar"</string>
- <string name="closed_caption_option_item_off" msgid="4824009036785647753">"O‘chiq"</string>
- <string name="closed_caption_system_settings" msgid="1856974607743827178">"Formatlarni sozlash"</string>
- <string name="closed_caption_system_settings_description" msgid="6285276836057964524">"Taglavhalar uchun tizim sozlamalari"</string>
- <string name="side_panel_title_display_mode" msgid="6346286034015991229">"Ekran rejimi"</string>
- <string name="side_panel_title_multi_audio" msgid="5970537894780855080">"Ko‘p kanalli"</string>
- <string name="multi_audio_channel_mono" msgid="6229173848963557723">"mono"</string>
- <string name="multi_audio_channel_stereo" msgid="3758995659214256587">"stereo"</string>
- <string name="multi_audio_channel_surround_6" msgid="6066304966228963942">"5.1 qamrovli"</string>
- <string name="multi_audio_channel_surround_8" msgid="2765140653768694313">"7.1 qamrovli"</string>
- <string name="multi_audio_channel_suffix" msgid="4443825738196093772">"%d ta kanal"</string>
- <string name="side_panel_title_edit_channels_for_an_input" msgid="7334895164698222989">"Ro‘yxatni sozlash"</string>
- <string name="edit_channels_item_select_group" msgid="4953000352257999703">"Guruhni tanlash"</string>
- <string name="edit_channels_item_deselect_group" msgid="5092649099546997807">"Guruhni o‘chirish"</string>
- <string name="edit_channels_item_group_by" msgid="7794571851966798199">"Guruhlash tartibi"</string>
- <string name="edit_channels_group_by_sources" msgid="5481053601210461217">"Kanal manbasi"</string>
- <string name="edit_channels_group_by_hd_sd" msgid="5582719665718278819">"HD/SD"</string>
- <string name="edit_channels_group_divider_for_hd" msgid="5311355566660389423">"HD"</string>
- <string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
- <string name="side_panel_title_group_by" msgid="1783176601425788939">"Guruhlash tartibi"</string>
- <string name="program_guide_content_locked" msgid="198056836554559553">"Bu dastur bloklangan"</string>
- <string name="program_guide_content_locked_format" msgid="514915272862967389">"Bu dastur uchun yosh cheklovi: <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="msg_no_setup_activity" msgid="7746893144640239857">"Bu kirish avtomatik qidiruvni qo‘llab-quvvatlamaydi"</string>
- <string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"“<xliff:g id="TV_INPUT">%s</xliff:g>” uchun avtomatik qidiruvni boshlab bo‘lmadi"</string>
- <string name="msg_unable_to_start_system_captioning_settings" msgid="705242616044165668">"Taglavhalar uchun tizim sozlamalarini ochib bo‘lmadi."</string>
- <plurals name="msg_channel_added" formatted="false" msgid="5301526166755938705">
- <item quantity="other">%1$d ta kanal qo‘shildi</item>
- <item quantity="one">%1$d ta kanal qo‘shildi</item>
- </plurals>
- <string name="msg_no_channel_added" msgid="2882586037409921925">"Kanal qo‘shilmadi"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Tyuner"</string>
- <string name="menu_parental_controls" msgid="2474294054521345840">"Ota-ona nazorati"</string>
- <string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Yoniq"</string>
- <string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"O‘chiq"</string>
- <string name="option_channels_locked" msgid="5797855082297549907">"Kanallar bloklandi"</string>
- <string name="option_channels_lock_all" msgid="6594512884477342940">"Barchasini bloklash"</string>
- <string name="option_channels_unlock_all" msgid="6839513296447567623">"Blokdan chiqarish"</string>
- <string name="option_channels_subheader_hidden" msgid="4669425935426972078">"Berkitilgan kanallar"</string>
- <string name="option_program_restrictions" msgid="241342023067364108">"Yosh cheklovlari"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"PIN kodni o‘zgartirish"</string>
- <string name="option_country_rating_systems" msgid="7288569813945260224">"Reyting tizimlari"</string>
- <string name="option_ratings" msgid="4009116954188688616">"Reytinglar"</string>
- <string name="option_see_all_rating_systems" msgid="7702673500014877288">"Barcha reyting tizimlari"</string>
- <string name="other_countries" msgid="8342216398676184749">"Boshqa mamlakatlar"</string>
- <string name="option_no_locked_channel" msgid="2543094883927978444">"Hech biri"</string>
- <string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Hech biri"</string>
- <string name="option_rating_none" msgid="5204552587760414879">"Hech biri"</string>
- <string name="option_rating_high" msgid="8898400296730158893">"Qat’iy cheklovlar"</string>
- <string name="option_rating_medium" msgid="6455853836426497151">"O‘rtacha cheklovlar"</string>
- <string name="option_rating_low" msgid="5800146024503377969">"Yengil cheklovlar"</string>
- <string name="option_rating_custom" msgid="3155377834510646436">"Boshqa"</string>
- <string name="option_rating_high_description" msgid="609567565273278745">"Kontent bolalar uchun mos"</string>
- <string name="option_rating_medium_description" msgid="7169199016608935280">"Kontent o‘rta yoshdagi bolalar uchun mos"</string>
- <string name="option_rating_low_description" msgid="4740109576615335045">"Kontent o‘smirlar uchun mos"</string>
- <string name="option_rating_custom_description" msgid="6180723522991233194">"Foydalanuvchi cheklovlari"</string>
- <!-- no translation found for option_attribution (2967657807178951562) -->
- <skip />
- <string name="option_subrating_title" msgid="5485055507818077595">"%1$s: sub-reytinglar"</string>
- <string name="option_subrating_header" msgid="4637961301549615855">"Sub-reytinglar"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Bu kanalni ko‘rish uchun PIN kodni kiriting"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"Bu dasturni ko‘rish uchun PIN kodni kiriting"</string>
- <string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Bu dastur uchun yosh cheklovi: <xliff:g id="RATING">%1$s</xliff:g>. Bu dasturni ko‘rish uchun PIN kodni kiriting"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"PIN kodni kiriting"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"Ota-ona nazoratini o‘rnatish uchun PIN-kod yarating"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"Yangi PIN kodni kiriting"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"PIN kodni kiriting"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"Joriy PIN kodni kiriting"</string>
- <plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
- <item quantity="other">Siz PIN kodni 5 marta noto‘g‘ri kiritdingiz.\n<xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> soniyadan keyin qayta urinib ko‘ring.</item>
- <item quantity="one">Siz PIN kodni 5 marta noto‘g‘ri kiritdingiz.\n<xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> soniyadan keyin qayta urinib ko‘ring.</item>
- </plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN-kod noto‘g‘ri, qaytadan urining."</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"Qaytadan urinib ko‘ring, PIN-kod noto‘g‘ri"</string>
- <string name="side_panel_title_settings" msgid="8244327316510918755">"Sozlamalar"</string>
- <string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Ro‘yxatni sozlash"</string>
- <string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Teledastur uchun kanallarni tanlash"</string>
- <string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Kanal manbalari"</string>
- <string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Yangi kanallar topildi"</string>
- <string name="settings_parental_controls" msgid="5449397921700749317">"Ota-ona nazorati"</string>
- <string name="settings_menu_licenses" msgid="1257646083838406103">"Ochiq kodli DT litsenziyalari"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Ochiq kodli DT litsenziyalari"</string>
- <string name="settings_menu_version" msgid="2604030372029921403">"Versiyasi"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"Bu kanalni ko‘rish uchun o‘ngga qaragan chiziqni bosing va PIN kodni kiriting"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"Bu dasturni ko‘rish uchun o‘ngga qaragan chiziqni bosing va PIN kodni kiriting"</string>
- <string name="tvview_content_locked_format" msgid="3741874636031338247">"Bu dastur uchun yosh cheklovi: <xliff:g id="RATING">%1$s</xliff:g>.\nUshbu dasturni ko‘rish uchun o‘ngga qaragan milni bosing va PIN-kodni kiriting."</string>
- <string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Bu kanallarni ko‘rish uchun birlamchi “Jonli efir” ilovasidan foydalaning."</string>
- <string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Bu dasturni ko‘rish uchun birlamchi “Jonli efir” ilovasidan foydalaning."</string>
- <string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Bu dastur uchun yosh cheklovi: <xliff:g id="RATING">%1$s</xliff:g>.\nUshbu dasturni ko‘rish uchun birlamchi “Jonli efir” ilovasidan foydalaning."</string>
- <string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Dastur bloklangan"</string>
- <string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Bu dastur uchun yosh cheklovi: <xliff:g id="RATING">%1$s</xliff:g>"</string>
- <string name="tvview_msg_audio_only" msgid="1356866203687173329">"Faqat audio"</string>
- <string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Signal kuchsiz"</string>
- <string name="tvview_msg_no_internet_connection" msgid="7655994401188888231">"Internet aloqasi yo‘q"</string>
- <plurals name="tvview_msg_input_no_resource" formatted="false" msgid="8581894855153658823">
- <item quantity="other">Bu kanalni <xliff:g id="END_TIME_1">%1$s</xliff:g> gacha yoqib bo‘lmaydi, chunki boshqa kanallar yozib olinmoqda. \n\nYozib olish jadvalini o‘zgartirish uchun o‘ng strelkani bosing.</item>
- <item quantity="one">Bu kanalni <xliff:g id="END_TIME_0">%1$s</xliff:g> gacha yoqib bo‘lmaydi, chunki boshqa kanal yozib olinmoqda. \n\nYozib olish jadvalini o‘zgartirish uchun o‘ng strelkani bosing.</item>
- </plurals>
- <string name="channel_banner_no_title" msgid="8660301979190693176">"Nomsiz"</string>
- <string name="channel_banner_locked_channel_title" msgid="2006564967318945980">"Kanal bloklangan"</string>
- <string name="setup_category_new" msgid="2899355289563443627">"Yangi"</string>
- <string name="setup_category_done" msgid="4750902502852212319">"Manbalar"</string>
- <plurals name="setup_input_channels" formatted="false" msgid="1695941684075602971">
- <item quantity="other">%1$d ta kanal</item>
- <item quantity="one">%1$d ta kanal</item>
- </plurals>
- <string name="setup_input_no_channels" msgid="1669327912393163331">"Hech qanday kanal mavjud emas"</string>
- <string name="setup_input_new" msgid="3337725672277046798">"Yangi"</string>
- <string name="setup_input_setup_now" msgid="1772000402336958967">"Sozlanmagan"</string>
- <string name="setup_store_action_title" msgid="4083402039720973414">"Ko‘proq kanal manbalarini olish"</string>
- <string name="setup_store_action_description" msgid="6820482635042445297">"Jonli kanallarni taklif etuvchi ilovalarni ko‘rish"</string>
- <string name="new_sources_title" msgid="3878933676500061895">"Yangi kanal manbalari mavjud"</string>
- <string name="new_sources_description" msgid="749649005588426813">"Yangi manbalar yangi kanallarni taqdim etadi.\nUlarni hozir yoki kanal manbalari sozlamalarida keyinroq sozlashingiz mumkin."</string>
- <string name="new_sources_action_setup" msgid="177693761664016811">"Hozir sozlash"</string>
- <string name="new_sources_action_skip" msgid="2501296961258184330">"OK"</string>
- <!-- no translation found for intro_title (251772896916795556) -->
- <skip />
- <string name="intro_description" msgid="7806473686446937307">"TV menyusiga kirish uchun "<b>"TANLASH tugmasini bosing"</b>"."</string>
- <string name="msg_no_input" msgid="3897674146985427865">"Hech qanday TV-kirish topilmadi"</string>
- <string name="msg_no_specific_input" msgid="2688885987104249852">"TV-kirishni topib bo‘lmadi"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP qo‘llab-quvvatlanmaydi"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"PIP bilan ko‘rsatish uchun hech qanday manba yo‘q"</string>
- <string name="msg_not_passthrough_input" msgid="4502101097091087411">"Tyuner turi mos kelmaydi. Agar TV-kirishdan foydalanayotgan bo‘lsangiz, “Jonli efir” ilovasini ishga tushiring."</string>
- <string name="msg_tune_failed" msgid="3277419551849972252">"Sozlashni amalga oshirib bo‘lmadi."</string>
- <string name="msg_missing_app" msgid="8291542072400042076">"Bu amalni bajara oladigan ilova topilmadi."</string>
- <string name="msg_all_channels_hidden" msgid="777397634062471936">"Barcha kanallar berkitilgan.\nTomosha qilish uchun kamida bitta kanalni tanlang."</string>
- <string name="msg_channel_unavailable_unknown" msgid="765586450831081871">"Video kutilmaganda yo‘q bo‘lib qoldi."</string>
- <string name="msg_back_key_guide" msgid="7404682718828721924">"ORQAGA tugmasi ulangan qurilmani boshqaradi. Chiqish uchun BOSHI tugmasini bosing."</string>
- <string name="msg_read_tv_listing_permission_denied" msgid="8882813301235518909">"Teledasturlarni o‘qish uchun ruxsat zarur."</string>
- <string name="setup_sources_text" msgid="4988039637873759839">"Manbalarni sozlash"</string>
- <string name="setup_sources_description" msgid="5695518946225445202">"Jonli efirlar ilovalar tomonidan taqdim etiladigan translatsiya qilinadigan kanallar bilan an’anaviy televizor kanallarini uyg‘unlashtiradi. \n\nOldin o‘rnatilgan kanal manbalarini sozlash bilan boshlashingiz mumkin. Yoki jonli efirlarni taklif etadigan boshqa ilovalarni Google Play Market orqali ko‘rib chiqishingiz mumkin."</string>
- <string name="channels_item_dvr" msgid="8911915252648532469">"Yozuvlar va jadvallar"</string>
- <string name="recording_start_dialog_10_min_duration" msgid="5739636508245795292">"10 daqiqa"</string>
- <string name="recording_start_dialog_30_min_duration" msgid="4691127772622189977">"30 daqiqa"</string>
- <string name="recording_start_dialog_1_hour_duration" msgid="7159533207022355641">"1 soat"</string>
- <string name="recording_start_dialog_3_hours_duration" msgid="295984419320006238">"3 soat"</string>
- <string name="dvr_main_recent" msgid="2553805424822806495">"Yaqinda"</string>
- <string name="dvr_main_scheduled" msgid="7837260963086408492">"Rejalashtirilgan"</string>
- <string name="dvr_main_series" msgid="8278256687595691676">"Seriallar"</string>
- <string name="dvr_main_others" msgid="2970835573614038153">"Boshqalar"</string>
- <string name="dvr_msg_cannot_record_channel" msgid="6836291367918532447">"Bu kanalni yozib bo‘lmaydi."</string>
- <string name="dvr_msg_cannot_record_program" msgid="4184046342810946090">"Bu dasturni yozib bo‘lmaydi."</string>
- <string name="dvr_msg_program_scheduled" msgid="3800847542300367572">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> dasturini yozib olish rejalashtirildi"</string>
- <string name="dvr_msg_current_program_scheduled" msgid="2505247201782991463">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> dasturini yozib olish boshlandi (<xliff:g id="ENDTIME">%2$s</xliff:g> gacha yoziladi)"</string>
- <string name="dvr_full_schedule_card_view_title" msgid="7198521806965950089">"To‘liq jadval"</string>
- <plurals name="dvr_full_schedule_card_view_content" formatted="false" msgid="790788122541080768">
- <item quantity="other">Keyingi %1$d kun</item>
- <item quantity="one">Keyingi %1$d kun</item>
- </plurals>
- <plurals name="dvr_program_duration" formatted="false" msgid="6742119148312354741">
- <item quantity="other">%1$d daqiqa</item>
- <item quantity="one">%1$d daqiqa</item>
- </plurals>
- <plurals name="dvr_count_new_recordings" formatted="false" msgid="3569310208305402815">
- <item quantity="other">%1$d ta yangi yozuv</item>
- <item quantity="one">%1$d ta yangi yozuv</item>
- </plurals>
- <plurals name="dvr_count_recordings" formatted="false" msgid="7417379223468131391">
- <item quantity="other">%1$d ta yozuv</item>
- <item quantity="one">%1$d ta yozuv</item>
- </plurals>
- <plurals name="dvr_count_scheduled_recordings" formatted="false" msgid="1650330290765214511">
- <item quantity="other">%1$d ta yozuv rejalashtirilgan</item>
- <item quantity="one">%1$d ta yozuv rejalashtirilgan</item>
- </plurals>
- <string name="dvr_detail_watch" msgid="7085694764364338215">"Tomosha qilish"</string>
- <string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Boshidan ijro etish"</string>
- <string name="dvr_detail_resume_play" msgid="875591300274416373">"Ijroni davom ettirish"</string>
- <string name="dvr_detail_delete" msgid="4535881013528321898">"O‘chirish"</string>
- <string name="dvr_detail_series_delete" msgid="4831926831670312674">"Yozuvlarni o‘chirish"</string>
- <string name="dvr_detail_series_resume" msgid="6935136228671386246">"Davom ettirish"</string>
- <string name="dvr_detail_series_season_title" msgid="5474850936497854790">"<xliff:g id="SEASON_NUMBER">%1$s</xliff:g>-fasl"</string>
- <string name="dvr_detail_view_schedule" msgid="7137536927421904426">"Jadvalni ko‘rish"</string>
- <string name="dvr_detail_read_more" msgid="2588920758094498544">"Batafsil"</string>
- <string name="dvr_series_deletion_title" msgid="7672649492494507574">"Yozuvlarni o‘chirish"</string>
- <string name="dvr_series_deletion_description" msgid="994839237906552969">"O‘chirib tashlash kerak bo‘lgan qismlarni tanlang. O‘chirilgach, qayta tiklab bo‘lmaydi."</string>
- <string name="dvr_series_deletion_no_recordings" msgid="481210819034514">"O‘chirib tashlash uchun hech narsa yo‘q."</string>
- <string name="dvr_series_select_watched" msgid="3608122404146716502">"Ko‘rilgan qismlarni belgilash"</string>
- <string name="dvr_series_select_all" msgid="5415749261739544048">"Barcha qismlarni belgilash"</string>
- <string name="dvr_series_deselect_all" msgid="1680395960166387572">"Hammasini bekor qilish"</string>
- <string name="dvr_series_watched_info_minutes" msgid="5656926431901526030">"Ko‘rilgan: <xliff:g id="WATCHED">%1$d</xliff:g> daqiqa (jami: <xliff:g id="DURATION">%2$d</xliff:g> daqiqa)"</string>
- <string name="dvr_series_watched_info_seconds" msgid="2667537184197566662">"Ko‘rilgan: <xliff:g id="WATCHED">%1$d</xliff:g> soniya (jami: <xliff:g id="DURATION">%2$d</xliff:g> soniya)"</string>
- <string name="dvr_series_never_watched" msgid="6086008065876122655">"Ko‘rilmaganlar"</string>
- <plurals name="dvr_msg_episodes_deleted" formatted="false" msgid="5627112959798353905">
- <item quantity="other">%1$d ta qism o‘chirib tashlandi (jami: %2$d ta)</item>
- <item quantity="one">%1$d ta qism o‘chirib tashlandi (jami: %2$d ta)</item>
- </plurals>
- <string name="dvr_series_settings_priority" msgid="5836437092774185710">"Muhimlik darajasi"</string>
- <string name="dvr_series_settings_priority_highest" msgid="1072006447796648382">"Eng yuqori"</string>
- <string name="dvr_series_settings_priority_lowest" msgid="6003996497908810225">"Eng past"</string>
- <string name="dvr_series_settings_priority_rank" msgid="667778382820956116">"# <xliff:g id="RANK">%1$d</xliff:g>"</string>
- <string name="dvr_series_settings_channels" msgid="3164900110165729909">"Kanallar"</string>
- <string name="dvr_series_settings_channels_all" msgid="656434955168572976">"Har qanday"</string>
- <string name="dvr_priority_title" msgid="1537886929061487213">"Muhimlilik darajasini tanlash"</string>
- <string name="dvr_priority_description" msgid="8362040921417154645">"Bir vaqtning o‘zida bir nechta dasturlar yozib olinishi kerak bo‘lsa, faqat muhimlilik darajasi yuqori dasturlargina yozib olinadi."</string>
- <string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Saqlash"</string>
- <string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Bir martalik yozuvlarning muhimlilik darajasi yuqori"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Bekor q-sh"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Bekor qilish"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"O‘chirib tashlash"</string>
- <string name="dvr_action_stop" msgid="1378723485295471381">"To‘xtatish"</string>
- <string name="dvr_action_view_schedules" msgid="7442990695392774263">"Yozib olish jadvalini ko‘rish"</string>
- <string name="dvr_action_record_episode" msgid="8596182676610326327">"Faqat bu dastur"</string>
- <string name="dvr_action_record_episode_from_now_description" msgid="5125122951529985697">"hozir – <xliff:g id="ENDTIME">%1$s</xliff:g>"</string>
- <string name="dvr_action_record_series" msgid="8501991316179436899">"To‘liq serial…"</string>
- <string name="dvr_action_record_anyway" msgid="991470058034937231">"Baribir yozib olinsin"</string>
- <string name="dvr_action_record_instead" msgid="6821164728752215738">"Bu dasturni yozib olish"</string>
- <string name="dvr_action_record_cancel" msgid="8644254745772185288">"Bu yozib olishni bekor qilish"</string>
- <string name="dvr_action_watch_now" msgid="7181211920959075976">"Tomosha qilish"</string>
- <string name="dvr_epg_program_recordable" msgid="609229576209476903">"Yozib olish mumkin"</string>
- <string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Yozib olish rejalashtirildi"</string>
- <string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Yozib olish taymerida ziddiyat"</string>
- <string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Yozib olish"</string>
- <string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Yozib olib bo‘lmadi"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Yozib olish jadvallarini yaratish uchun dasturlar o‘qib chiqilmoqda"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Dasturlar o‘qib chiqilmoqda"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
- <string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR uchun ko‘proq joy kerak"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Dasturlarni DVR orqali yozib olish mumkin. Lekin hozir DVR ishlashi uchun qurilmangizda yetarli joy qolmadi. <xliff:g id="STORAGE_SIZE">%1$s</xliff:g> GB va undan katta hajmli tashqi xotira qurilmasini ulang va qurilma xotirasi sifatida formatlash uchun ko‘rsatmalarga amal qiling."</string>
- <string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Xotira mavjud emas"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Xotira topilmadi. Videomagnitofonni qayta yoqishdan oldin tashqi xotirani ulang yoki undan foydalanib bo‘lmasa, xotirani o‘chirib tashlang."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Xotira o‘chirib tashlansinmi?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Barcha yozib olingan kontentlar va jadvallar o‘chib ketadi."</string>
- <string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Yozib olish to‘xtatilsinmi?"</string>
- <string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Yozib olingan kontent saqlab qo‘yiladi."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
- <string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Yozib olish rejalashtirildi, lekin ixtiloflar bor"</string>
- <string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Yozib olish jadvalida ixtiloflar bor"</string>
- <string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"“<xliff:g id="PROGRAMNAME">%1$s</xliff:g>” dasturi yozib olinadi."</string>
- <string name="dvr_channel_conflict_dialog_description_prefix" msgid="212344250779878791">"“<xliff:g id="CHANNELNAME">%1$s</xliff:g>” kanalidagi video yozib olinmoqda."</string>
- <string name="dvr_program_conflict_dialog_description_1" msgid="2278200346765501164">"“<xliff:g id="CONFLICTPROGRAMNAME">%1$s</xliff:g>” dasturining faqat bir qismi yozib olinadi."</string>
- <string name="dvr_program_conflict_dialog_description_2" msgid="5648524408147235696">"“<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>” va “<xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>” dasturlarining faqat bir qismi yozib olinadi."</string>
- <string name="dvr_program_conflict_dialog_description_3" msgid="6879199850098595108">"“<xliff:g id="CONFLICTPROGRAMNAME_1">%1$s</xliff:g>”, “<xliff:g id="CONFLICTPROGRAMNAME_2">%2$s</xliff:g>” va yana bitta dasturning faqat bir qismi yozib olinadi."</string>
- <plurals name="dvr_program_conflict_dialog_description_many" formatted="false" msgid="1008340710252647947">
- <item quantity="other"><xliff:g id="CONFLICTPROGRAMNAME_1_2">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_3">%2$s</xliff:g> va yana %3$d ta dasturning faqat bir qismi yozib olinadi.</item>
- <item quantity="one"><xliff:g id="CONFLICTPROGRAMNAME_1_0">%1$s</xliff:g>, <xliff:g id="CONFLICTPROGRAMNAME_2_1">%2$s</xliff:g> va yana %3$d ta dasturning faqat bir qismi yozib olinadi.</item>
- </plurals>
- <string name="dvr_schedule_dialog_title" msgid="5235629824986156058">"Nimalar yozib olinsin?"</string>
- <string name="dvr_channel_record_duration_dialog_title" msgid="4601361040431047918">"Qancha vaqt yozib olinsin?"</string>
- <string name="dvr_already_scheduled_dialog_title" msgid="4525318291210934311">"Allaqachon rejalashtirilgan"</string>
- <string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Bu dasturni allaqachon <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> da yozib olish rejalashtirilgan."</string>
- <string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Dastur allaqachon yozib olingan"</string>
- <string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Bu dastur allaqachon yozib olingan. U DVR kutubxonasida saqlanadi."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
- <string name="dvr_program_not_found" msgid="3282879532038010202">"Yozib olingan dasturni topib bo‘lmadi."</string>
- <string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Aloqador yozuvlar"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Dastur haqida ma’lumot yo‘q)"</string>
- <plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
- <item quantity="other">%1$d ta yozuv</item>
- <item quantity="one">%1$d ta yozuv</item>
- </plurals>
- <string name="dvr_schedules_information_separator" msgid="1669116853379998479">" / "</string>
- <string name="dvr_schedules_deletion_info" msgid="2837586459900271031">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> yozuvi jadvaldan olib tashlandi"</string>
- <string name="dvr_schedules_tuner_conflict_will_be_partially_recorded" msgid="5280490298546908729">"Tyuner yo‘qligi sababli qisman yozib olinadi."</string>
- <string name="dvr_schedules_tuner_conflict_will_not_be_recorded_info" msgid="5065400564003201095">"Tyuner yo‘qligi sababli yozib olinmaydi."</string>
- <string name="dvr_schedules_empty_state" msgid="1291529283469462741">"Jadval bo‘sh.\nTele-yo‘lboshlovchi orqali yozib olishni rejalashtirish mumkin."</string>
- <plurals name="dvr_series_schedules_header_description" formatted="false" msgid="9077188267856194114">
- <item quantity="other">%1$d ta yozib olish bo‘yicha ziddiyat</item>
- <item quantity="one">%1$d ta yozib olish bo‘yicha ziddiyat</item>
- </plurals>
- <string name="dvr_series_schedules_settings" msgid="4868501926847903985">"Qismlar sozlamalari"</string>
- <string name="dvr_series_schedules_start" msgid="8458768834047133835">"Yozib olishni boshlash"</string>
- <string name="dvr_series_schedules_stop" msgid="3427479298317584961">"Yozib olishni to‘xtatish"</string>
- <string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Yozib olish to‘xtatilsinmi?"</string>
- <string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Yozib olingan qismlar DVR kutubxonasida saqlanadi."</string>
- <string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"To‘xtatish"</string>
- <string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Hali serial qismi chiqmagan.\nEfirga chiqishi bilan yozib olinadi."</string>
- <plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
- <item quantity="other">(%1$d daqiqa)</item>
- <item quantity="one">(%1$d daqiqa) </item>
- </plurals>
- <string name="dvr_date_today" msgid="7691050705354303471">"Bugun"</string>
- <string name="dvr_date_tomorrow" msgid="4136735681186981844">"Ertaga"</string>
- <string name="dvr_date_yesterday" msgid="2127672919053118239">"Kecha"</string>
- <string name="dvr_date_today_time" msgid="8359696776305244535">"Bugun <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"Ertaga <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="program_guide_critic_score" msgid="340530743913585150">"Ball"</string>
-</resources>
diff --git a/res/values-v23/strings.xml b/res/values-v23/strings.xml
deleted file mode 100644
index 4809682a..00000000
--- a/res/values-v23/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Title of the channels row in the main menu. [CHAR LIMIT=NONE] -->
- <string name="menu_title_channels">Channels</string>
-</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index a8c4ab09..a1aae946 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"đơn âm"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"âm thanh nổi"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Điều khiển phát"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Kênh gần đây"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Kênh"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Tùy chọn TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Tùy chọn PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Điều khiển phát không có sẵn cho kênh này"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Phát hoặc tạm dừng"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Tua đi"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Phụ đề"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Chế độ hiển thị"</string>
<string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Bật"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Tắt"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Âm thanh đa kênh"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Tải thêm kênh"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Cài đặt"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Nguồn"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Hoán đổi"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Bật"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Tắt"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Âm thanh"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Cửa sổ chính"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Cửa sổ PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Bố cục"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Phía dưới cùng bên phải"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Phía trên cùng bên phải"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Phía trên cùng bên trái"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Phía dưới cùng bên trái"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"Cạnh nhau"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Kích thước"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Lớn"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Nhỏ"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Nguồn đầu vào"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"TV (ăng-ten/cáp)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Không có thông tin chương trình"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Không có thông tin"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Kênh bị chặn"</string>
- <string name="default_language" msgid="4122326459624337928">"Tiếng không xác định"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Ngôn ngữ không xác định"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Phụ đề chi tiết %1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Phụ đề"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Tắt"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Tùy chỉnh định dạng"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Nhóm theo"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Chương trình này đã bị chặn"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Chương trình này chưa được xếp hạng"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Chương trình này được xếp hạng <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Đầu vào không hỗ trợ tự động quét"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Không thể bắt đầu quét tự động cho \'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
@@ -92,7 +74,6 @@
<item quantity="one">Đã thêm %1$d kênh</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Chưa thêm kênh nào"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"Bộ dò"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Kiểm soát của cha mẹ"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Bật"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Tắt"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Các quốc gia khác"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Không có"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Không có"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Chưa được xếp hạng"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Chặn chương trình chưa có hạng"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Không có"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Hạn chế cao"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Hạn chế trung bình"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Nhập mã PIN của bạn để xem kênh này"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Nhập mã PIN của bạn để xem chương trình này"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Chương trình này được xếp hạng <xliff:g id="RATING">%1$s</xliff:g>. Nhập mã PIN của bạn để xem chương trình này"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Chương trình này chưa được xếp hạng. Hãy nhập mã PIN của bạn để xem chương trình này"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Nhập mã PIN của bạn"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Để đặt kiểm soát của phụ huynh, hãy tạo mã PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Nhập mã PIN mới"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Mã PIN đó không đúng. Hãy thử lại."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Hãy thử lại, mã PIN không khớp"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Nhập mã ZIP của bạn."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Ứng dụng Kênh trực tiếp sẽ sử dụng mã ZIP để cung cấp hướng dẫn chương trình đầy đủ cho các kênh truyền hình."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Nhập mã ZIP của bạn"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Mã ZIP không hợp lệ"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Cài đặt"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Tùy chỉnh danh sách kênh"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Chọn kênh cho hướng dẫn chương trình của bạn"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Nguồn kênh"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Đã có kênh mới"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Kiểm soát của phụ huynh"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"Chuyển dịch thời gian"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Ghi lại trong khi xem để bạn có thể tạm dừng hoặc tua lại các chương trình trực tiếp.\nCảnh báo: Điều này có thể làm giảm tuổi thọ của bộ nhớ trong bằng cách sử dụng nhiều bộ nhớ."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Giấy phép nguồn mở"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Giấy phép nguồn mở"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Gửi phản hồi"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Phiên bản"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Để xem kênh này, hãy nhấn vào Quyền và nhập mã PIN của bạn"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Để xem chương trình này, hãy nhấn vào Quyền và nhập mã PIN của bạn"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Chương trình này chưa được xếp hạng.\nĐể xem chương trình này, hãy nhấn vào phím Phải và nhập mã PIN của bạn"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Chương trình này được xếp hạng <xliff:g id="RATING">%1$s</xliff:g>.\nĐể xem chương trình này, hãy nhấn vào Quyền và nhập mã PIN của bạn."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Để xem kênh này, hãy sử dụng ứng dụng Truyền hình trực tiếp mặc định."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Để xem chương trình này, hãy sử dụng ứng dụng Truyền hình trực tiếp mặc định."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Chương trình này chưa được xếp hạng.\nĐể xem chương trình này, hãy sử dụng ứng dụng Truyền hình trực tiếp mặc định."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Chương trình này được xếp hạng <xliff:g id="RATING">%1$s</xliff:g>.\nĐể xem chương trình này, hãy sử dụng ứng dụng Truyền hình trực tiếp mặc định."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Chương trình bị chặn"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Chương trình này chưa được xếp hạng"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Chương trình này được xếp hạng <xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Chỉ âm thanh"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Tín hiệu yếu"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Nhấn CHỌN"</b>" để truy cập menu TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Không tìm thấy đầu vào TV nào"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Không tìm thấy đầu vào TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP không được hỗ trợ"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Không có đầu vào có thể hiển thị với PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"Loại bộ dò ko phù hợp. Hãy chạy ứng dụng Kênh trực tiếp cho đầu vào TV loại bộ dò."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Không dò được"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Không tìm thấy ứng dụng nào để xử lý tác vụ này."</string>
@@ -226,6 +217,8 @@
<item quantity="other">%1$d bản ghi được lên lịch</item>
<item quantity="one">%1$d bản ghi được lên lịch</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Hủy ghi"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Dừng ghi"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Xem"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Phát từ đầu"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Tiếp tục phát"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Khi có quá nhiều chương trình được ghi cùng lúc, chỉ có những chương trình với mức ưu tiên cao hơn sẽ được ghi."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Lưu"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Ghi một lần có mức độ ưu tiên cao nhất"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Hủy"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Hủy"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Quên"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Dừng"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Xem lịch ghi"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Chương trình duy nhất này"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Ghi chương trình này để thay thế"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Hủy lịch ghi này"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Xem ngay bây giờ"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Xóa bản ghi…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Có thể ghi được"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Đã lên lịch ghi"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Lịch ghi xung đột"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Đang ghi"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Ghi không thành công"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Đang đọc các chương trình để tạo lịch ghi"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Đang đọc chương trình"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Đang đọc chương trình"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Xem bản ghi gần đây"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Quá trình ghi <xliff:g id="PROGRAMNAME">%1$s</xliff:g> không hoàn thành."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Quá trình ghi <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> và <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> không hoàn thành."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Quá trình ghi <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> và <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> không hoàn thành."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Quá trình ghi <xliff:g id="PROGRAMNAME">%1$s</xliff:g> đã không hoàn thành do không đủ bộ nhớ."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Quá trình ghi <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> và <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> đã không hoàn thành do không đủ bộ nhớ."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Quá trình ghi <xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> và <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> đã không hoàn thành do không đủ bộ nhớ."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR cần thêm bộ nhớ"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Bạn sẽ có thể ghi các chương trình với DVR. Tuy nhiên không có đủ bộ nhớ trên thiết bị của bạn bây giờ để DVR hoạt động. Vui lòng kết nối ổ đĩa ngoài <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB hoặc lớn hơn và làm theo các bước để định dạng ổ đĩa ngoài làm thiết bị lưu trữ."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Bạn sẽ có thể ghi các chương trình với DVR. Tuy nhiên không có đủ bộ nhớ trên thiết bị của bạn bây giờ để DVR hoạt động. Vui lòng kết nối ổ đĩa ngoài <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB hoặc lớn hơn và làm theo các bước để định dạng ổ đĩa ngoài làm thiết bị lưu trữ."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Không đủ bộ nhớ"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Chương trình này sẽ không được ghi vì không có đủ bộ nhớ. Hãy thử xóa một số bản ghi hiện có."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Thiếu bộ nhớ"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Một số bộ nhớ được DVR sử dụng bị thiếu. Vui lòng kết nối các ổ đĩa ngoài bạn đã sử dụng trước đó để bật lại DVR. Ngoài ra bạn còn có thể chọn để quên bộ nhớ nếu bộ nhớ không còn nữa."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Quên bộ nhớ?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Tất cả nội dung đã ghi và lịch ghi của bạn sẽ bị mất."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Dừng ghi?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Nội dung đã ghi sẽ được lưu."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Quá trình ghi <xliff:g id="PROGRAMNAME">%1$s</xliff:g> sẽ bị dừng lại vì mâu thuẫn với chương trình này. Nội dung đã ghi sẽ được lưu."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Đã lên lịch ghi nhưng có xung đột"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Đã bắt đầu ghi nhưng có xung đột"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> sẽ được ghi."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Chương trình tương tự đã được lên lịch để ghi lúc <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Đã được ghi"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Chương trình này đã được ghi. Chương trình có sẵn trong thư viện DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Đã lên lịch ghi loạt phim"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> bản ghi đã được lên lịch cho <xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> bản ghi đã được lên lịch cho <xliff:g id="SERIESNAME_1">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> bản ghi đã được lên lịch cho <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> trong số chúng sẽ không được ghi do xung đột.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> bản ghi đã được lên lịch cho <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. Bản ghi sẽ không được ghi do xung đột.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> bản ghi đã được lên lịch cho <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> tập của loạt phim này và các loạt phim khác sẽ không được ghi do xung đột.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> bản ghi đã được lên lịch cho <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> tập của loạt phim này và các loạt phim khác sẽ không được ghi do xung đột.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> bản ghi đã được lên lịch cho <xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 tập của loạt phim khác sẽ không được ghi do xung đột.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> bản ghi đã được lên lịch cho <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. 1 tập của loạt phim khác sẽ không được ghi do xung đột.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> bản ghi đã được lên lịch cho <xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> tập của loạt phim khác sẽ không được ghi do xung đột.</item>
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> bản ghi đã được lên lịch cho <xliff:g id="SERIESNAME_1">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> tập của loạt phim khác sẽ không được ghi do xung đột.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Không tìm thấy chương trình nào được ghi."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Bản ghi liên quan"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Không có mô tả chương trình)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d bản ghi</item>
<item quantity="one">%1$d bản ghi</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Dừng ghi loạt phim?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Các tập đã ghi sẽ vẫn có sẵn trong thư viện DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Dừng"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Không có tập nào đang chiếu bây giờ."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Không có sẵn tập nào.\nChúng sẽ được ghi khi có sẵn."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d phút)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> hôm nay"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> ngày mai"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Điểm"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Chương trình đã ghi"</string>
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index e3d8ea08..2aa3e2cb 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"单声道"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"立体声"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"播放控件"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"最近观看的频道"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"频道"</string>
<string name="menu_title_options" msgid="7184594626814914022">"电视选项"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP 选项"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"此频道无法使用播放控件"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"播放或暂停"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"快进"</string>
@@ -34,34 +33,16 @@
<string name="channels_item_app_link_app_launcher" msgid="1395352122187670523">"打开<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="options_item_closed_caption" msgid="5945274655046367170">"字幕"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"显示模式"</string>
- <string name="options_item_pip" msgid="3951350386626879645">"PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"开启"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"关闭"</string>
+ <string name="options_item_pip" msgid="3951350386626879645">"画中画"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"多音频"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"获取更多频道"</string>
<string name="options_item_settings" msgid="7623205838542400074">"设置"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"来源"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"切换"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"开启"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"关闭"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"声音"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"主窗口"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"PIP 窗口"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"布局"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"右下方"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"右上方"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"左上方"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"左下方"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"并排"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"尺寸"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"大"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"小"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"输入源"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"电视(天线/有线)"</string>
<string name="no_program_information" msgid="1049844207745145132">"没有节目信息"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"无信息"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"已屏蔽的频道"</string>
- <string name="default_language" msgid="4122326459624337928">"未知语言"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"未知语言"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"字幕(%1$d)"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"字幕"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"关闭"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"自定义格式"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"标清"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"分组依据"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"此节目已被屏蔽"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"此节目未分级"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"此节目的分级为:<xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"该输入设备不支持自动扫描"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"无法为“<xliff:g id="TV_INPUT">%s</xliff:g>”启动自动扫描"</string>
@@ -92,7 +74,6 @@
<item quantity="one">已添加 %1$d 个频道</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"未添加任何频道"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"调谐器"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"家长控制"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"开启"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"关闭"</string>
@@ -101,13 +82,15 @@
<string name="option_channels_unlock_all" msgid="6839513296447567623">"全部取消屏蔽"</string>
<string name="option_channels_subheader_hidden" msgid="4669425935426972078">"隐藏的频道"</string>
<string name="option_program_restrictions" msgid="241342023067364108">"节目限制"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"更改PIN码"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"更改 PIN 码"</string>
<string name="option_country_rating_systems" msgid="7288569813945260224">"分级系统"</string>
<string name="option_ratings" msgid="4009116954188688616">"分级"</string>
<string name="option_see_all_rating_systems" msgid="7702673500014877288">"查看所有分级系统"</string>
<string name="other_countries" msgid="8342216398676184749">"其他国家/地区"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"无"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"无"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"未分级"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"屏蔽未分级的节目"</string>
<string name="option_rating_none" msgid="5204552587760414879">"无"</string>
<string name="option_rating_high" msgid="8898400296730158893">"严格限制"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"中等限制"</string>
@@ -121,36 +104,46 @@
<skip />
<string name="option_subrating_title" msgid="5485055507818077595">"%1$s和二级分级"</string>
<string name="option_subrating_header" msgid="4637961301549615855">"二级分级"</string>
- <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"输入PIN码即可观看此频道"</string>
- <string name="pin_enter_unlock_program" msgid="7311628843209871203">"输入PIN码即可观看此节目"</string>
+ <string name="pin_enter_unlock_channel" msgid="4797922378296393173">"输入 PIN 码即可观看此频道"</string>
+ <string name="pin_enter_unlock_program" msgid="7311628843209871203">"输入 PIN 码即可观看此节目"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"该节目的分级是“<xliff:g id="RATING">%1$s</xliff:g>”。要观看此节目,请输入您的 PIN 码"</string>
- <string name="pin_enter_pin" msgid="249314665028035038">"输入您的PIN码"</string>
- <string name="pin_enter_create_pin" msgid="3385754356793309946">"要设置家长控制功能,请创建一个PIN码"</string>
- <string name="pin_enter_new_pin" msgid="1739471585849790384">"请输入新的PIN码"</string>
- <string name="pin_enter_again" msgid="2618999754723090427">"确认您的PIN码"</string>
- <string name="pin_enter_old_pin" msgid="4588282612931041919">"输入当前的PIN码"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"此节目未分级。要观看此节目,请输入您的 PIN 码"</string>
+ <string name="pin_enter_pin" msgid="249314665028035038">"输入您的 PIN 码"</string>
+ <string name="pin_enter_create_pin" msgid="3385754356793309946">"要设置家长控制功能,请创建一个 PIN 码"</string>
+ <string name="pin_enter_new_pin" msgid="1739471585849790384">"请输入新的 PIN 码"</string>
+ <string name="pin_enter_again" msgid="2618999754723090427">"确认您的 PIN 码"</string>
+ <string name="pin_enter_old_pin" msgid="4588282612931041919">"输入当前的 PIN 码"</string>
<plurals name="pin_enter_countdown" formatted="false" msgid="3415233538538544309">
<item quantity="other">您已连续 5 次输错 PIN 码。\n请在 <xliff:g id="REMAINING_SECONDS_1">%1$d</xliff:g> 秒后重试。</item>
<item quantity="one">您已连续 5 次输错 PIN 码。\n请在 <xliff:g id="REMAINING_SECONDS_0">%1$d</xliff:g> 秒后重试。</item>
</plurals>
- <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN码不正确,请重试。"</string>
- <string name="pin_toast_not_match" msgid="4283624338659521768">"PIN码不匹配,请重试"</string>
+ <string name="pin_toast_wrong" msgid="2126295626095048746">"PIN 码不正确,请重试。"</string>
+ <string name="pin_toast_not_match" msgid="4283624338659521768">"PIN 码不匹配,请重试"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"请输入您的邮政编码。"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"直播频道应用将使用邮政编码提供完整的电视频道收视指南。"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"请输入您的邮政编码"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"邮政编码无效"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"设置"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"自定义频道列表"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"为您的收视指南选择频道"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"频道来源"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"有新频道"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"家长控制"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"时移"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"一边观看一边录制,这样您就能够让直播节目暂停或快退。\n警告:此功能会密集占用存储空间,因此可能会缩短内部存储空间的使用寿命。"</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"开放源代码许可"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"开放源代码许可"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"发送反馈"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"版本"</string>
- <string name="tvview_channel_locked" msgid="6486375335718400728">"要观看此频道,请按“向右”按钮,然后输入您的PIN码"</string>
- <string name="tvview_content_locked" msgid="391823084917017730">"要观看此节目,请按“向右”按钮,然后输入您的PIN码"</string>
+ <string name="tvview_channel_locked" msgid="6486375335718400728">"要观看此频道,请按“向右”按钮,然后输入您的 PIN 码"</string>
+ <string name="tvview_content_locked" msgid="391823084917017730">"要观看此节目,请按“向右”按钮,然后输入您的 PIN 码"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"此节目未分级。\n要观看此节目,请按向右键并输入您的 PIN 码"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"此节目的分级为:<xliff:g id="RATING">%1$s</xliff:g>。\n要观看此节目,请按“向右”按钮,然后输入您的 PIN 码。"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"要观看此频道,请使用默认的“电视直播”应用。"</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"要观看此节目,请使用默认的“电视直播”应用。"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"此节目未分级。\n要观看此节目,请使用默认的“电视直播”应用。"</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"该节目的分级是“<xliff:g id="RATING">%1$s</xliff:g>”。\n要观看此节目,请使用默认的“电视直播”应用。"</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"节目已被屏蔽"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"此节目未分级"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"此节目的分级为:<xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"仅提供音频"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"信号弱"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"按“选择”"</b>"可访问电视菜单。"</string>
<string name="msg_no_input" msgid="3897674146985427865">"未检测到电视输入设备"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"找不到该电视输入设备"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"不支持 PIP"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"没有可通过 PIP 方式显示的输入"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"不支持调谐器类型。请启动支持调谐器类型电视输入端口的“直播频道”应用。"</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"调谐失败"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"未找到可处理此操作的应用。"</string>
@@ -226,6 +217,8 @@
<item quantity="other">已安排录制 %1$d 项内容</item>
<item quantity="one">已安排录制 %1$d 项内容</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"取消录制"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"停止录制"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"观看"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"从头播放"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"继续播放"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"如果同一时段有太多的节目要录制,系统只会录制优先级较高的节目。"</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"保存"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"一次性录制内容具有最高优先级"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"取消"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"取消"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"移除"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"停止"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"查看录制时间表"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"只录这一集节目"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"改录这个节目"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"取消这项录制安排"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"立即观看"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"删除录制的节目…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"可录制"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"已排定录制时间"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"录制冲突"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"正在录制"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"录制失败"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"正在读取节目以创建录制时间安排表"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"正在读取节目"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"正在读取节目"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"查看最近的录制内容"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g>的录制没有完成。"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>和<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>的录制没有完成。"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>、<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>和<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>的录制没有完成。"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"由于存储空间不足,<xliff:g id="PROGRAMNAME">%1$s</xliff:g>的录制没有完成。"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"由于存储空间不足,<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>和<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>的录制没有完成。"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"由于存储空间不足,<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>、<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>和<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>的录制没有完成。"</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR 需要更多存储空间"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"您将可以使用 DVR 录制节目,但目前您设备上的存储空间不足,因此无法使用 DVR。请连接存储空间不小于 <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB 的外部驱动器,然后按照相关步骤将其格式化为设备的存储空间。"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"您将可以使用 DVR 录制节目,但目前您设备上的存储空间不足,因此无法使用 DVR。请连接存储空间不小于 <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB 的外部驱动器,然后按照相关步骤将其格式化为设备的存储空间。"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"存储空间不足"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"由于存储空间不足,系统将不会录制此节目。请尝试删除部分已录制的节目。"</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"无法访问存储空间"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"无法访问 DVR 使用的部分存储空间。请连接您先前使用的外部驱动器,以重新启用 DVR。如果存储空间已无法再使用,您也可以选择忽略该存储空间。"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"要移除此存储空间吗?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"您的所有录制内容和录制安排计划都将丢失。"</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"要停止录制吗?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"系统将保存已录制的内容。"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"系统将停止录制《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》,因为它与此节目存在冲突。系统将保存已录制的内容。"</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"已排定录制时间,但录制时间存在冲突"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"已开始录制,但存在冲突"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"系统将会录制《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》。"</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"已安排在以下时间录制同一节目:<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>。"</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"已录制"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"此节目已完成录制并保存在 DVR 媒体库中。"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"已排定剧集录制时间"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">已为《<xliff:g id="SERIESNAME_3">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 项录制计划。</item>
+ <item quantity="one">已为《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 项录制计划。</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">已为《<xliff:g id="SERIESNAME_3">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 项录制计划。由于存在冲突,系统将无法录制其中 <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> 集节目。</item>
+ <item quantity="one">已为《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 项录制计划。由于存在冲突,系统将无法录制这集节目。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">已为《<xliff:g id="SERIESNAME_4">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> 项录制计划。由于存在冲突,系统将无法录制此剧集和其他剧集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> 集节目。</item>
+ <item quantity="one">已为《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 项录制计划。由于存在冲突,系统将无法录制此剧集和其他剧集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> 集节目。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">已为《<xliff:g id="SERIESNAME_3">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 项录制计划。由于存在冲突,系统将无法录制其他剧集的 1 集节目。</item>
+ <item quantity="one">已为《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 项录制计划。由于存在冲突,系统将无法录制其他剧集的 1 集节目。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">已为《<xliff:g id="SERIESNAME_4">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> 项录制计划。由于存在冲突,系统将无法录制其他剧集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> 集节目。</item>
+ <item quantity="one">已为《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 项录制计划。由于存在冲突,系统将无法录制其他剧集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> 集节目。</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"未找到录制的节目。"</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"相关录制内容"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(没有节目说明)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d 项录制内容</item>
<item quantity="one">%1$d 项录制内容</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"要停止创建剧集录制时间表吗?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"已录制的剧集仍会保存到 DVR 媒体库中。"</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"停止"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"目前没有任何正在播出的剧集。"</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"没有已录制的剧集。\n一旦有剧集可供录制,系统将立即开始录制。"</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d 分钟)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"今天<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"明天<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"评分"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"已录制的节目"</string>
</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 5fe984d5..05e0b9e8 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"單聲道"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"立體聲"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"播放控制"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"最近觀看的頻道"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"頻道"</string>
<string name="menu_title_options" msgid="7184594626814914022">"電視選項"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"PIP 選項"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"播放控制功能不適用於此頻道"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"播放或暫停"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"向前快轉"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"隱藏式字幕"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"顯示模式"</string>
<string name="options_item_pip" msgid="3951350386626879645">"子母畫面"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"開啟"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"關閉"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"多聲道"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"取得更多頻道"</string>
<string name="options_item_settings" msgid="7623205838542400074">"設定"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"來源"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"切換"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"開啟"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"關閉"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"音效"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"主視窗"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"子母畫面視窗"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"版面配置"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"右下方"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"右上方"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"左上方"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"左下方"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"並排"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"大小"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"大"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"小"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"輸入源"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"電視 (天線/連接線)"</string>
<string name="no_program_information" msgid="1049844207745145132">"沒有節目資訊"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"無資訊"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"已封鎖的頻道"</string>
- <string name="default_language" msgid="4122326459624337928">"不明語言"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"不明語言"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"隱藏式字幕 (%1$d)"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"隱藏式字幕"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"關閉"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"自訂格式"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"標清"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"分組依據"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"這個節目已被封鎖。"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"此節目未分級"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"這個節目的評級為<xliff:g id="RATING">%1$s</xliff:g>。"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"輸入裝置不支援自動掃瞄功能"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"無法啟動「<xliff:g id="TV_INPUT">%s</xliff:g>」的自動掃瞄"</string>
@@ -92,7 +74,6 @@
<item quantity="one">已新增 %1$d 個頻道</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"尚未新增任何頻道"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"調校器"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"家長監護"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"開啟"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"關閉"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"其他國家/地區"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"無"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"無"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"未分級"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"封鎖未分級的節目"</string>
<string name="option_rating_none" msgid="5204552587760414879">"無"</string>
<string name="option_rating_high" msgid="8898400296730158893">"嚴格限制"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"中等限制"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"輸入您的 PIN 即可觀看這個頻道"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"輸入您的 PIN 即可觀看這個節目"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"此節目的內容分級是「<xliff:g id="RATING">%1$s</xliff:g>」。如要觀看此節目,請輸入 PIN"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"此節目未分級。如要觀看此節目,請輸入您的 PIN"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"請輸入您的 PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"如要設定家長監護,請建立 PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"輸入新的 PIN"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"該 PIN 錯誤,請再試一次。"</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"PIN 碼不符,請再試一次"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"請輸入郵遞區號。"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"「直播頻道」應用程式會利用郵遞區號,提供電視頻道的完整電視節目指南。"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"請輸入郵遞區號"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"郵遞區號無效"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"設定"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"自訂頻道清單"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"選擇頻道以建立電視節目指南"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"頻道來源"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"可供設定的新頻道"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"家長監控設定"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"時光平移"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"錄影正在觀看的直播節目,以便暫停播放節目或倒帶。\n警告:此功能會佔用大量儲存空間,因此可能會縮短內部儲存空間的使用壽命。"</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"開放原始碼授權"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"開放原始碼授權"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"傳送意見"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"版本"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"按向右鍵並輸入您的 PIN,以觀看這個頻道"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"按向右鍵並輸入您的 PIN,以觀看這個節目"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"此節目未分級。\n如要觀看此節目,請按向右鍵並輸入您的 PIN"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"這個節目的評級為<xliff:g id="RATING">%1$s</xliff:g>。\n要觀看這個節目,請按向右鍵並輸入您的 PIN。"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"如要觀看此頻道,請使用預設電視直播應用程式。"</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"如要觀看此節目,請使用預設電視直播應用程式。"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"此節目未分級。\n如要觀看此節目,請使用預設的「直播電視」應用程式。"</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"此節目評級為「<xliff:g id="RATING">%1$s</xliff:g>」。\n如要觀看此節目,請使用預設電視直播應用程式。"</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"節目被封鎖"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"此節目未分級"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"這個節目的評級為<xliff:g id="RATING">%1$s</xliff:g>。"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"只限音效"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"訊號微弱"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"按 [選擇]"</b>" 前往 [電視選單]。"</string>
<string name="msg_no_input" msgid="3897674146985427865">"找不到電視輸入"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"找不到電視輸入"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"PIP 不受支援"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"沒有可供 PIP 顯示的輸入"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"調諧器類型不適用;請啟動調諧器類型電視輸入專用的「直播頻道」應用程式。"</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"調校失敗"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"找不到可以處理這項操作的應用程式。"</string>
@@ -226,6 +217,8 @@
<item quantity="other">已預定 %1$d 個錄影</item>
<item quantity="one">已預定 %1$d 個錄影</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"取消錄影"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"停止錄影"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"觀看"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"從頭開始播放"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"恢復播放"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"如果同一時間有太多需要錄影的節目,系統只會錄影優先級別較高的節目。"</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"儲存"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"單次錄影享有最高優先級別"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"取消"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"取消"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"刪除"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"停止"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"查看錄影時間表"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"只錄影這一集"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"改為錄影此節目"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"取消此錄影"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"立即觀看"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"刪除錄影節目…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"可錄影"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"已排定錄影時間"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"錄影時間有衝突"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"正在錄影"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"錄影失敗"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"正在讀取節目以建立錄影時間表"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"正在讀取節目"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"正在讀取節目"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"查看最近的錄影"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》未完成錄影。"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"《<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>》和《<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>》未完成錄影。"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"《<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>》、《<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>》和《<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>》未完成錄影。"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"由於儲存空間不足,因此《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》未完成錄影。"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"由於儲存空間不足,因此《<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>》和《<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>》未完成錄影。"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"由於儲存空間不足,因此《<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>》、《<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>》和《<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>》未完成錄影。"</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR 需要更多儲存空間"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"您可以使用 DVR 錄影節目,但裝置目前的儲存空間不足,因此無法使用 DVR。請連接 <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB 或以上的外置硬碟,然後按步驟格式化,以用作裝置儲存空間。"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"您可以使用 DVR 錄影節目,但裝置目前的儲存空間不足,因此無法使用 DVR。請連接 <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB 或以上的外置硬碟,然後按步驟格式化,以用作裝置儲存空間。"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"儲存空間不足"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"由於儲存空間不足,因此無法錄影此節目。請嘗試刪除部分現有的錄影節目。"</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"無法存取儲存空間"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"系統存取部分 DVR 使用的儲存空間。請連接您先前使用的外置磁碟,然後重新啟用 DVR。如果儲存空間已無法使用,您亦可選擇刪除儲存空間。"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"要刪除儲存空間嗎?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"所有已錄影的內容和時間表將會遺失。"</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"要停止錄影嗎?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"系統將儲存已錄影的內容。"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"由於《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》的錄影時間與此節目有衝突,因此系統將停止錄影並儲存已錄影的內容。"</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"已預定錄影時間,但與錄影時間有衝突"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"已開始錄影,但與其他預定錄影時間有衝突"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"系統將錄影《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》。"</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"已預定在 <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>錄影相同的節目。"</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"已錄影"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"系統已錄影此節目並儲存在 DVR 媒體庫中。"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"已預定劇集錄影時間"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">已為《<xliff:g id="SERIESNAME_3">%2$s</xliff:g>》預定 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 個錄影時間。</item>
+ <item quantity="one">已為《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》預定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 個錄影時間。</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">已為《<xliff:g id="SERIESNAME_3">%2$s</xliff:g>》預定 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 個錄影時間。由於發生衝突,因此系統將不會錄影其中 <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> 集節目。</item>
+ <item quantity="one">已為《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》預定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 個錄影時間。由於發生衝突,因此系統將不會錄影該節目。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">已為《<xliff:g id="SERIESNAME_4">%2$s</xliff:g>》預定 <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> 個錄影時間。由於發生衝突,因此系統將不會錄影此劇集和其他劇集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> 集節目。</item>
+ <item quantity="one">已為《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》預定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 個錄影時間。由於發生衝突,因此系統將不會錄影此劇集和其他劇集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> 集節目。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">已為《<xliff:g id="SERIESNAME_3">%2$s</xliff:g>》預定 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 個錄影時間。由於發生衝突,因此系統將不會錄影其他劇集的 1 集節目。</item>
+ <item quantity="one">已為《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》預定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 個錄影時間。由於發生衝突,因此系統將不會錄影其他劇集的 1 集節目。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">已為《<xliff:g id="SERIESNAME_4">%2$s</xliff:g>》預定 <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> 個錄影時間。由於發生衝突,因此系統將不會錄影其他劇集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> 集節目。</item>
+ <item quantity="one">已為《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》預定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 個錄影時間。由於發生衝突,因此系統將不會錄影其他劇集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> 集節目。</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"找不到已錄影的節目。"</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"相關錄影"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(沒有節目說明)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d 個錄影</item>
<item quantity="one">%1$d 個錄影</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"要停止錄影劇集嗎?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"已錄影的劇集仍將保留在 DVR 媒體庫中。"</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"停止"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"目前沒有任何正在播出的劇集。"</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"沒有可供錄影的劇集。\n系統會在劇集播出時立即錄影。"</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d 分鐘)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"今天<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"明天<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"分數"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"已錄影的節目"</string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index e33998ba..d40ecb0e 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"單聲道"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"立體聲"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"播放控制介面"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"最近觀看的頻道"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"頻道"</string>
<string name="menu_title_options" msgid="7184594626814914022">"電視選項"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"子母畫面選項"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"這個頻道無法使用播放控制介面"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"播放或暫停"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"快轉"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"字幕"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"顯示模式"</string>
<string name="options_item_pip" msgid="3951350386626879645">"子母畫面"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"開啟"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"關閉"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"多聲道"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"取得更多頻道"</string>
<string name="options_item_settings" msgid="7623205838542400074">"設定"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"來源"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"切換"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"開啟"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"關閉"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"音效"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"主視窗"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"子母畫面視窗"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"版面配置"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"右下角"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"右上角"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"左上角"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"左下角"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"並排"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"尺寸"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"大"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"小"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"輸入來源"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"電視 (有線/無線)"</string>
<string name="no_program_information" msgid="1049844207745145132">"沒有節目資訊"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"無資訊"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"封鎖的頻道"</string>
- <string name="default_language" msgid="4122326459624337928">"不明語言"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"不明語言"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"隱藏式輔助字幕 (%1$d)"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"字幕"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"關閉"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"自訂格式設定"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"SD 標準畫質"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"分組依據"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"這個節目遭到封鎖"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"這個節目未分級"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"這個節目的分級是「<xliff:g id="RATING">%1$s</xliff:g>」。"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"輸入裝置不支援自動掃描"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"無法開始「<xliff:g id="TV_INPUT">%s</xliff:g>」的自動掃描作業"</string>
@@ -92,7 +74,6 @@
<item quantity="one">新增了 %1$d 個頻道</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"尚未新增任何頻道"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"協調器"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"家長監護"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"開啟"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"關閉"</string>
@@ -101,13 +82,15 @@
<string name="option_channels_unlock_all" msgid="6839513296447567623">"全部解除封鎖"</string>
<string name="option_channels_subheader_hidden" msgid="4669425935426972078">"隱藏的頻道"</string>
<string name="option_program_restrictions" msgid="241342023067364108">"節目限制"</string>
- <string name="option_change_pin" msgid="2881594075631152566">"變更 PIN"</string>
+ <string name="option_change_pin" msgid="2881594075631152566">"變更 PIN 碼"</string>
<string name="option_country_rating_systems" msgid="7288569813945260224">"分級系統"</string>
<string name="option_ratings" msgid="4009116954188688616">"分級"</string>
<string name="option_see_all_rating_systems" msgid="7702673500014877288">"查看所有分級制度"</string>
<string name="other_countries" msgid="8342216398676184749">"其他國家/地區"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"無"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"無"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"未分級"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"封鎖未分級的節目"</string>
<string name="option_rating_none" msgid="5204552587760414879">"無"</string>
<string name="option_rating_high" msgid="8898400296730158893">"高度限制"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"中度限制"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"輸入您的 PIN 即可觀看這個頻道"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"輸入您的 PIN 即可觀看這個節目"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"這個節目的分級是「<xliff:g id="RATING">%1$s</xliff:g>」。如要觀看此節目,請輸入 PIN 碼"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"這個節目未分級。如要觀看此節目,請輸入你的 PIN 碼"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"請輸入您的 PIN"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"如要設定家長監護,請建立 PIN"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"輸入新的 PIN"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"該 PIN 錯誤,請再試一次。"</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"PIN 碼不符,請再試一次"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"請輸入你的郵遞區號。"</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"直播頻道應用程式會利用郵遞區號提供完整的電視頻道節目指南。"</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"請輸入你的郵遞區號"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"無效的郵遞區號"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"設定"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"自訂頻道清單"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"為您的節目指南選擇頻道"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"頻道來源"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"有可用的新頻道"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"家長監護"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"影片播放操作"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"在觀看時進行錄製,以便將直播節目暫停或倒轉。\n警告:這項功能會密集使用儲存空間,可能會因此縮短內部儲存空間的使用壽命。"</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"開放原始碼授權"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"開放原始碼授權"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"提供意見"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"版本"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"如要觀看這個頻道,請按向右鍵並輸入您的 PIN"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"如要觀看這個節目,請按向右鍵並輸入您的 PIN"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"這個節目未分級。\n如要觀看此節目,請按向右鍵並輸入你的 PIN 碼"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"這個節目的分級是「<xliff:g id="RATING">%1$s</xliff:g>」。\n如要觀看這個節目,請按向右鍵並輸入您的 PIN"</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"如要觀看這個頻道,請使用預設的直播電視應用程式。"</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"如要觀看這個節目,請使用預設的直播電視應用程式。"</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"這個節目未分級。\n如要觀看此節目,請使用預設的直播電視應用程式。"</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"這個節目的分級是「<xliff:g id="RATING">%1$s</xliff:g>」。\n如要觀看這個節目,請使用預設的直播電視應用程式。"</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"節目遭到封鎖"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"這個節目未分級"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"這個節目的分級是「<xliff:g id="RATING">%1$s</xliff:g>」。"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"僅限音訊"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"訊號微弱"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307">"按 [選取]"<b></b>" 即可使用 [電視選單]。"</string>
<string name="msg_no_input" msgid="3897674146985427865">"找不到電視輸入裝置"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"找不到電視輸入裝置"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"不支援子母畫面"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"沒有可透過子母畫面顯示的輸入來源"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"協調器類型不適合;請啟動協調器類型電視輸入裝置專用的 Live TV 應用程式。"</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"協調失敗"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"找不到可以處理這個動作的應用程式。"</string>
@@ -226,6 +217,8 @@
<item quantity="other">已預約錄製 %1$d 個節目</item>
<item quantity="one">已預約錄製 %1$d 個節目</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"取消錄製"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"停止錄製"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"觀看"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"從頭開始播放"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"繼續播放"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"如果同一時段錄製的節目過多,系統只會錄製優先順序較高的節目。"</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"儲存"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"只排定錄製一次的項目優先順序最高"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"取消"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"取消"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"移除"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"停止"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"查看錄影時間表"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"只錄這一集"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"改錄這個節目"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"取消這項錄影預約"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"立即觀看"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"刪除錄影檔案…"</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"可錄影"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"已排定錄影時間"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"錄影衝突"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"錄製中"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"錄製失敗"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"正在讀取節目以建立錄影時間表"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"正在讀取節目"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"正在讀取節目資訊"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"查看最近的錄製項目"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》未錄製完成。"</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"《<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>》和《<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>》未錄製完成。"</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"《<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>》、《<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>》和《<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>》未錄製完成。"</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"儲存空間不足,因此《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》未錄製完成。"</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"儲存空間不足,因此《<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>》和《<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>》未錄製完成。"</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"儲存空間不足,因此《<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>》、《<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g>》和《<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g>》未錄製完成。"</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"DVR 需要更多儲存空間"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"你可以利用 DVR 錄製節目,但目前裝置儲存空間不足,因此無法使用 DVR。請連接 <xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB 以上的外接式磁碟,然後按照相關步驟將該磁碟格式化為裝置儲存空間。"</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"你可以利用 DVR 錄製節目,但目前裝置儲存空間不足,因此無法使用 DVR。請連接 <xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB 以上的外接式磁碟,然後按照相關步驟將該磁碟格式化為裝置儲存空間。"</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"儲存空間不足"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"儲存空間不足,因此無法錄製這個節目。請嘗試刪除一些現有的錄影檔案。"</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"無法存取儲存空間"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"無法存取部分 DVR 使用的儲存空間。請連接你先前使用的外接式磁碟以重新啟用 DVR。如果儲存空間已無法使用,你也可以選擇移除儲存空間。"</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"要移除儲存空間嗎?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"所有錄製內容和錄影時間表都不會保存下來。"</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"要停止錄影嗎?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"系統將儲存已錄製的內容。"</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"由於「<xliff:g id="PROGRAMNAME">%1$s</xliff:g>」與這個節目發生衝突,因此系統將停止錄製。已錄製的內容會保留下來。"</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"已排定錄影時間,但錄影時間發生衝突"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"已開始錄影,但發生衝突"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"系統將會錄製《<xliff:g id="PROGRAMNAME">%1$s</xliff:g>》。"</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"同一個節目已預約在 <xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g> 錄影。"</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"已錄影"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"這個節目已完成錄影並儲存在 DVR 媒體庫中。"</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"已排定影集錄製時間"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="other">已為《<xliff:g id="SERIESNAME_3">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 個錄影時間。</item>
+ <item quantity="one">已為《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 個錄影時間。</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="other">已為《<xliff:g id="SERIESNAME_3">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 個錄影時間。由於發生時間衝突,因此系統將不會錄製其中 <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> 集節目。</item>
+ <item quantity="one">已為《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 個錄影時間。由於發生時間衝突,因此系統將不會錄製這集節目。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="other">已為《<xliff:g id="SERIESNAME_4">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> 個錄影時間。由於發生時間衝突,因此系統將不會錄製這個影集和其他影集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> 集節目。</item>
+ <item quantity="one">已為《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 個錄影時間。由於發生時間衝突,因此系統將不會錄製這個影集和其他影集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> 集節目。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="other">已為《<xliff:g id="SERIESNAME_3">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> 個錄影時間。由於發生時間衝突,因此系統將不會錄製其他影集的 1 集節目。</item>
+ <item quantity="one">已為《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 個錄影時間。由於發生時間衝突,因此系統將不會錄製其他影集的 1 集節目。</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="other">已為《<xliff:g id="SERIESNAME_4">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> 個錄影時間。由於發生時間衝突,因此系統將不會錄製其他影集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> 集節目。</item>
+ <item quantity="one">已為《<xliff:g id="SERIESNAME_1">%2$s</xliff:g>》排定 <xliff:g id="NUMBEROFRECORDINGS_0">%1$d</xliff:g> 個錄影時間。由於發生時間衝突,因此系統將不會錄製其他影集的 <xliff:g id="NUMBEROFCONFLICTEPISODES_2">%3$d</xliff:g> 集節目。</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"找不到錄製的節目。"</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"相關錄影"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(無節目說明)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="other">%1$d 個錄製項目</item>
<item quantity="one">%1$d 個錄製項目</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"要停止建立影集錄製時間表嗎?"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"錄製完畢的集數會保存在 DVR 媒體庫中。"</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"停止"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"目前未播出任何劇集。"</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"目前沒有可供觀看的集數。\n系統會在節目播出時立即錄影。"</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="other">(%1$d 分鐘)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"今天:<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"明天:<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"分數"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"已錄製的節目"</string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index ff1cfb3d..f34cdbd1 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -20,9 +20,8 @@
<string name="audio_channel_mono" msgid="8812941280022167428">"i-mono"</string>
<string name="audio_channel_stereo" msgid="5798223286366598036">"i-stereo"</string>
<string name="menu_title_play_controls" msgid="2490237359425190652">"Izilawuli zokudlala"</string>
- <string name="menu_title_channels" msgid="1801845517674690003">"Iziteshi zakamuva"</string>
+ <string name="menu_title_channels" msgid="1949045451672990132">"Iziteshi"</string>
<string name="menu_title_options" msgid="7184594626814914022">"Izinketho ze-TV"</string>
- <string name="menu_title_pip_options" msgid="4252934960762407689">"Izinketho ze-PIP"</string>
<string name="play_controls_unavailable" msgid="8900698593131693148">"Izilawuli zokudlala azitholakali kulesi siteshi"</string>
<string name="play_controls_description_play_pause" msgid="7225542861669250558">"Dlala noma umise isikhashana"</string>
<string name="play_controls_description_fast_forward" msgid="4414963867482448652">"Ukudlulisa ngokushesha"</string>
@@ -35,33 +34,15 @@
<string name="options_item_closed_caption" msgid="5945274655046367170">"Amazwibela avaliwe"</string>
<string name="options_item_display_mode" msgid="7989243076748680140">"Imodi yesibonisi"</string>
<string name="options_item_pip" msgid="3951350386626879645">"I-PIP"</string>
- <string name="options_item_pip_on" msgid="4647247480009077381">"Vuliwe"</string>
- <string name="options_item_pip_off" msgid="8799500161592387451">"Valiwe"</string>
<string name="options_item_multi_audio" msgid="5118851311937896923">"Umsindo omningi"</string>
<string name="options_item_more_channels" msgid="971040969622943300">"Thola iziteshi eziningi"</string>
<string name="options_item_settings" msgid="7623205838542400074">"Izilungiselelo"</string>
- <string name="pip_options_item_source" msgid="1050948525825308652">"Umthombo"</string>
- <string name="pip_options_item_swap" msgid="7245362207353732048">"Shintsha"</string>
- <string name="pip_options_item_swap_on" msgid="5647182616484983505">"Vuliwe"</string>
- <string name="pip_options_item_swap_off" msgid="3023597229417709768">"Valiwe"</string>
- <string name="pip_options_item_sound" msgid="3107034283791231648">"Umsindo"</string>
- <string name="pip_options_item_sound_main" msgid="1063937534112558691">"Isisekelo"</string>
- <string name="pip_options_item_sound_pip_window" msgid="435064142351853008">"Iwindil le-PIP"</string>
- <string name="pip_options_item_layout" msgid="5126206342060967651">"Isakhiwo"</string>
- <string name="pip_options_item_layout_bottom_right" msgid="5256839015192920238">"Phansi ngakwesokudla"</string>
- <string name="pip_options_item_layout_top_right" msgid="3585067214787055279">"Phezulu ngakwesokudla"</string>
- <string name="pip_options_item_layout_top_left" msgid="2173997010201637462">"Phezulu ngakwesokunxele"</string>
- <string name="pip_options_item_layout_bottom_left" msgid="1727197877968915329">"Phansi ngakwesokunxele"</string>
- <string name="pip_options_item_layout_side_by_side" msgid="9009784972740915779">"ingxenye nenxenye"</string>
- <string name="pip_options_item_size" msgid="5662894110243750158">"Usayizi"</string>
- <string name="pip_options_item_size_big" msgid="6303301565563444718">"Kukhulu"</string>
- <string name="pip_options_item_size_small" msgid="7393731186585004206">"Kuncane"</string>
- <string name="side_panel_title_pip_input_source" msgid="8722544967592970296">"Umthombo wokufaka"</string>
<string name="input_long_label_for_tuner" msgid="3423514011918382209">"I-TV (I-antenna/Intambo)"</string>
<string name="no_program_information" msgid="1049844207745145132">"Alukho ulwazi lohlelo"</string>
<string name="program_title_for_no_information" msgid="384451471906070101">"Alukho ulwazi"</string>
<string name="program_title_for_blocked_channel" msgid="5358005891746983819">"Isiteshi esivinjiwe"</string>
- <string name="default_language" msgid="4122326459624337928">"Ulimi olungaziwa"</string>
+ <string name="multi_audio_unknown_language" msgid="8639884627225598143">"Ulimi olungaziwa"</string>
+ <string name="closed_caption_unknown_language" msgid="4745445516930229353">"Imibhalo engezansi evaliwe engu-%1$d"</string>
<string name="side_panel_title_closed_caption" msgid="2513905054082568780">"Amazwibela avaliwe"</string>
<string name="closed_caption_option_item_off" msgid="4824009036785647753">"Valiwe"</string>
<string name="closed_caption_system_settings" msgid="1856974607743827178">"Yenza ngokwezifiso ukufometha"</string>
@@ -83,6 +64,7 @@
<string name="edit_channels_group_divider_for_sd" msgid="5846195382266436167">"I-SD"</string>
<string name="side_panel_title_group_by" msgid="1783176601425788939">"Qoqa nge-"</string>
<string name="program_guide_content_locked" msgid="198056836554559553">"Lolu hlelo luvinjiwe"</string>
+ <string name="program_guide_content_locked_unrated" msgid="8665707501827594275">"Lolu hlelo alulinganiselwe"</string>
<string name="program_guide_content_locked_format" msgid="514915272862967389">"Lolu hlelo lulinganiselwe nge-<xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="msg_no_setup_activity" msgid="7746893144640239857">"Kokufaka akusekeli ukuskena okuzenzakalelayo"</string>
<string name="msg_unable_to_start_setup_activity" msgid="8402612466599977855">"Ayikwazi ukuqala ukuskena ngokuzenzakalela kwe-\'<xliff:g id="TV_INPUT">%s</xliff:g>\'"</string>
@@ -92,7 +74,6 @@
<item quantity="other">%1$d iziteshi ezingeziwe</item>
</plurals>
<string name="msg_no_channel_added" msgid="2882586037409921925">"Azikho iziteshi ezingeziwe"</string>
- <string name="input_selector_tuner_label" msgid="6631205039926880892">"I-Tuner"</string>
<string name="menu_parental_controls" msgid="2474294054521345840">"Ukulawula kwabazali"</string>
<string name="option_toggle_parental_controls_on" msgid="9122851821454622696">"Vuliwe"</string>
<string name="option_toggle_parental_controls_off" msgid="7797910199040440618">"Valiwe"</string>
@@ -108,6 +89,8 @@
<string name="other_countries" msgid="8342216398676184749">"Amanye amazwe"</string>
<string name="option_no_locked_channel" msgid="2543094883927978444">"Lutho"</string>
<string name="option_no_enabled_rating_system" msgid="4139765018454678381">"Lutho"</string>
+ <string name="unrated_rating_name" msgid="1387302638048393814">"Okungalinganiselwe"</string>
+ <string name="option_block_unrated_programs" msgid="1108474218158184706">"Vimbela izinhlelo ezingalinganiselwe"</string>
<string name="option_rating_none" msgid="5204552587760414879">"Lutho"</string>
<string name="option_rating_high" msgid="8898400296730158893">"Imikhawulo ephezulu"</string>
<string name="option_rating_medium" msgid="6455853836426497151">"Imikhawulo emaphakathi"</string>
@@ -124,6 +107,7 @@
<string name="pin_enter_unlock_channel" msgid="4797922378296393173">"Faka iphinikhodi yakho ukuze ubuke lesi siteshi"</string>
<string name="pin_enter_unlock_program" msgid="7311628843209871203">"Faka iphinikhodi yakho ukuze ubuke lolu hlelo"</string>
<string name="pin_enter_unlock_dvr" msgid="1637468108723176684">"Lolu hlelo lulinganiselwe ku-<xliff:g id="RATING">%1$s</xliff:g>. Faka iphini yakho ukuze ubuke lolu hlelo"</string>
+ <string name="pin_enter_unlock_dvr_unrated" msgid="3911986002480028829">"Lolu hlelo alulinganiselwe. Faka iphinikhodi yakho ukuze ubuke lolu hlelo"</string>
<string name="pin_enter_pin" msgid="249314665028035038">"Faka iphinikhodi yakho"</string>
<string name="pin_enter_create_pin" msgid="3385754356793309946">"Ukuze usethe izilawuli zomzali, dala iphinikhodi"</string>
<string name="pin_enter_new_pin" msgid="1739471585849790384">"Faka iphinikhodi entsha"</string>
@@ -135,22 +119,31 @@
</plurals>
<string name="pin_toast_wrong" msgid="2126295626095048746">"Leyo phini ayilungile. Zama futhi."</string>
<string name="pin_toast_not_match" msgid="4283624338659521768">"Zama futhi, iphinikhodi ayifani"</string>
+ <string name="postal_code_guidance_title" msgid="4144793072363879833">"Faka ikhodi yakho ye-ZIP."</string>
+ <string name="postal_code_guidance_description" msgid="4224511147377561572">"Uhlelo lokusebenza lweziteshi ezibukhoma luzosebenzisa ikhodi ye-ZIP ukuze lunikeze umhlahlandlela wohlelo ophelele weziteshi ze-TV."</string>
+ <string name="postal_code_action_description" msgid="4428720607051109105">"Faka ikhodi yakho ye-ZIP"</string>
+ <string name="postal_code_invalid_warning" msgid="923373584458340746">"Ikhodi ye-ZIP engavumelekile"</string>
<string name="side_panel_title_settings" msgid="8244327316510918755">"Izilungiselelo"</string>
<string name="settings_channel_source_item_customize_channels" msgid="6115770679732624593">"Yenza ngezifiso uhlu lweziteshi"</string>
<string name="settings_channel_source_item_customize_channels_description" msgid="8966243790328235580">"Khetha iziteshi zomhlahlandlela wohlelo lwakho"</string>
<string name="settings_channel_source_item_setup" msgid="4566190088656419070">"Imithombo yeziteshi"</string>
<string name="settings_channel_source_item_setup_new_inputs" msgid="4845822152617430787">"Iziteshi ezintsha ziyatholakala"</string>
<string name="settings_parental_controls" msgid="5449397921700749317">"Ukulawula kwabazali"</string>
+ <string name="settings_trickplay" msgid="7762730842781251582">"I-Timeshift"</string>
+ <string name="settings_trickplay_description" msgid="3060323976172182519">"Rekhoda ngenkathi ubukile ukuze uzokwazi ukumisa okwesikhashana noma ubuyisele emuva izinhlelo ezibukhoma.\nIsexwayiso: Lokhu kungehlisa impilo yesitoreji sangaphakathi ngokusetshenziswa kakhulu kwesitoreji."</string>
<string name="settings_menu_licenses" msgid="1257646083838406103">"Amalayisense womthombo ovulekile"</string>
- <string name="dialog_title_licenses" msgid="4471754920475076623">"Amalayisense womthombo ovulekile"</string>
+ <string name="settings_send_feedback" msgid="6897217561193701829">"Thumela impendulo"</string>
<string name="settings_menu_version" msgid="2604030372029921403">"Inguqulo"</string>
<string name="tvview_channel_locked" msgid="6486375335718400728">"Ukuze ubuke lesi siteshi, cindezela Kwesokudla uphinde ufake i-PIN yakho"</string>
<string name="tvview_content_locked" msgid="391823084917017730">"Ukuze ubuke lolu hlelo, cindezela Kwesokudla uphinde ufake i-PIN yakho"</string>
+ <string name="tvview_content_locked_unrated" msgid="2273799245001356782">"Lolu hlelo alulinganiselwe.\nUkuze ubuke lolu hlelo, cindezela Kwesokudla bese ufaka iphinikhodi yakho"</string>
<string name="tvview_content_locked_format" msgid="3741874636031338247">"Lolu hlelo lulinganiselwe ngo-<xliff:g id="RATING">%1$s</xliff:g>.\nUkuze ubuke lolu hlelo, cindezela Kwesokudla uphinde ufake i-PIN yakho."</string>
<string name="tvview_channel_locked_no_permission" msgid="677653135227590620">"Ukuze ubuke lesi siteshi, sebenzisa uhlelo lokusebenza lwe-TV ebukhoma."</string>
<string name="tvview_content_locked_no_permission" msgid="2279126235895507764">"Ukuze ubuke lolu hlelo, sebenzisa uhlelo lokusebenza oluzenzakalelayo lwe-TV ebukhoma."</string>
+ <string name="tvview_content_locked_unrated_no_permission" msgid="4056090982858455110">"Lolu hlelo alulinganiselwe.\nUkuze ubuke lolu hlelo, sebenzisa uhlelo lokusebenza oluzenzakalelayo lwe-TV elibukhoma."</string>
<string name="tvview_content_locked_format_no_permission" msgid="5690794624572767106">"Lolu hlelo lulinganiselwe ngokungu-<xliff:g id="RATING">%1$s</xliff:g>.\nUkuze ubuke lolu hlelo, sebenzisa uhlelo lokusebenza lwe-TV ebukhoma."</string>
<string name="shrunken_tvview_content_locked" msgid="7686397981042364446">"Uhlelo luvinjiwe"</string>
+ <string name="shrunken_tvview_content_locked_unrated" msgid="4586881678635960742">"Lolu hlelo alulinganiselwe"</string>
<string name="shrunken_tvview_content_locked_format" msgid="3720284198877900916">"Lolu hlelo lulinganiselwe nge-<xliff:g id="RATING">%1$s</xliff:g>"</string>
<string name="tvview_msg_audio_only" msgid="1356866203687173329">"Umsindo kuphela"</string>
<string name="tvview_msg_weak_signal" msgid="1095050812622908976">"Isignali engaqinile"</string>
@@ -181,8 +174,6 @@
<string name="intro_description" msgid="7806473686446937307"><b>"Cindezela okuthi KHETHA"</b>" ukuze ufinyelele imenyu ye-TV."</string>
<string name="msg_no_input" msgid="3897674146985427865">"Akukho kokufaka kwe-TV okutholakele"</string>
<string name="msg_no_specific_input" msgid="2688885987104249852">"Ayikwazi ukuthola kokufaka kwe-TV"</string>
- <string name="msg_no_pip_support" msgid="161508628996629445">"I-PIP ayisekelwe"</string>
- <string name="msg_no_available_input_by_pip" msgid="7038191654524679666">"Akutholakali okokufaka okungaboniswa nge-PIP"</string>
<string name="msg_not_passthrough_input" msgid="4502101097091087411">"uhlobo le-Tuner alufanelekile; Sicela uqalise uhlelo lokusebenza leziteshi ezibukhoma lokufakwayo kwe-TV yohlobo le-tuner."</string>
<string name="msg_tune_failed" msgid="3277419551849972252">"Ukushuna kwehlulekile"</string>
<string name="msg_missing_app" msgid="8291542072400042076">"Alukho uhlelo lokusebenza olutholakalele ukuphatha lesi senzo."</string>
@@ -226,6 +217,8 @@
<item quantity="one">%1$d ukurekhodwa okushejuliwe</item>
<item quantity="other">%1$d ukurekhodwa okushejuliwe</item>
</plurals>
+ <string name="dvr_detail_cancel_recording" msgid="542538232330174145">"Khansela ukurekhoda"</string>
+ <string name="dvr_detail_stop_recording" msgid="3599488040374849367">"Misa ukurekhoda"</string>
<string name="dvr_detail_watch" msgid="7085694764364338215">"Buka"</string>
<string name="dvr_detail_play_from_beginning" msgid="8475543568260411836">"Dlala kusuka ekuqaleni"</string>
<string name="dvr_detail_resume_play" msgid="875591300274416373">"Qalisa ukudlala"</string>
@@ -258,9 +251,6 @@
<string name="dvr_priority_description" msgid="8362040921417154645">"Uma kunezinhlelo eziningi kakhulu okufanele zirekhodwe ngesikhathi esisodwa, yilezo ezinokukhetha okuphezulu ezizorekhodwa."</string>
<string name="dvr_priority_button_action_save" msgid="4773524273649733008">"Londoloza"</string>
<string name="dvr_priority_action_one_time_recording" msgid="8174297042282719478">"Ukurekhoda kwesikhathi esisodwa kunokubaluleka okuphezulu kakhulu"</string>
- <string name="dvr_action_cancel" msgid="8094060199570272625">"Khansela"</string>
- <string name="dvr_action_error_cancel" msgid="6822474458738023531">"Khansela"</string>
- <string name="dvr_action_error_forget_storage" msgid="5869994565663655638">"Khohlwa"</string>
<string name="dvr_action_stop" msgid="1378723485295471381">"Misa"</string>
<string name="dvr_action_view_schedules" msgid="7442990695392774263">"Buka ishejuli yokurekhoda"</string>
<string name="dvr_action_record_episode" msgid="8596182676610326327">"Lolu hlelo olulodwa"</string>
@@ -270,25 +260,28 @@
<string name="dvr_action_record_instead" msgid="6821164728752215738">"Rekhoda lokhu esikhundleni"</string>
<string name="dvr_action_record_cancel" msgid="8644254745772185288">"Khansela lokhu kurekhoda"</string>
<string name="dvr_action_watch_now" msgid="7181211920959075976">"Bukela njengamanje"</string>
+ <string name="dvr_action_delete_recordings" msgid="850785346795261671">"Susa ukurekhodwa..."</string>
<string name="dvr_epg_program_recordable" msgid="609229576209476903">"Okungarekhodeka"</string>
<string name="dvr_epg_program_recording_scheduled" msgid="1367741844291055016">"Ukurekhoda kushejuliwe"</string>
<string name="dvr_epg_program_recording_conflict" msgid="4827911748865195373">"Ukungqubuzana kokurekhoda"</string>
<string name="dvr_epg_program_recording_in_progress" msgid="2158340443975313745">"Iyarekhoda"</string>
<string name="dvr_epg_program_recording_failed" msgid="5589124519442328896">"Ukurekhoda kuhlulekile"</string>
- <string name="dvr_schedule_progress_message_reading_programs" msgid="6502513156469172313">"Ifunda izinhlelo ukuze idale amashejuli okurekhoda"</string>
- <string name="dvr_series_schedules_progress_message_reading_programs" msgid="7221275889560136115">"Izinhlelo ezifundayo"</string>
- <!-- no translation found for dvr_series_schedules_progress_message_updating_programs (6670286486601662465) -->
- <skip />
+ <string name="dvr_series_progress_message_reading_programs" msgid="2961615820635219355">"Izinhlelo ezifundayo"</string>
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings" msgid="137918938589787623">"Buka ukurekhoda kwakamuva"</string>
+ <string name="dvr_error_insufficient_space_title_one_recording" msgid="759510175792505150">"Ukurekhoda kwe-<xliff:g id="PROGRAMNAME">%1$s</xliff:g> akuphelele."</string>
+ <string name="dvr_error_insufficient_space_title_two_recordings" msgid="5518578722556227631">"Ukurekhoda kwe-<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ne-<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> akuphelele."</string>
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings" msgid="5104901174884754363">"Ukurekhoda kwe-<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> and <xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> akuphelele."</string>
+ <string name="dvr_error_insufficient_space_description_one_recording" msgid="9092549220659026111">"Ukurekhoda kwe-<xliff:g id="PROGRAMNAME">%1$s</xliff:g> akuqedanga ngenxa yesitoreji esingaphelele."</string>
+ <string name="dvr_error_insufficient_space_description_two_recordings" msgid="7712799694720979003">"Ukurekhoda kwe-<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g> ne-<xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> akuqedanga ngenxa yesitoreji esingaphelele."</string>
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings" msgid="7877855707777832128">"Ukurekhoda kwe-<xliff:g id="PROGRAMNAME_1">%1$s</xliff:g>, <xliff:g id="PROGRAMNAME_2">%2$s</xliff:g> ne-<xliff:g id="PROGRAMNAME_3">%3$s</xliff:g> akuqedanga ngenxa yesitoreji esingaphelele."</string>
<string name="dvr_error_small_sized_storage_title" msgid="5020225460011469011">"I-DVR idinga isitoreji esiningi"</string>
- <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Uzokwazi ukurekhoda izinhlelo nge-DVR. Kodwa asikho isitoreji esanele kudivayisi yakho manje ukuze i-DVR isebenze. Sicela uxhume idrayivu yangaphandle engu-<xliff:g id="STORAGE_SIZE">%1$s</xliff:g>GB noma enkulu bese ulandela izinyathelo uyifomethe njengesitoreji sedivayisi."</string>
+ <string name="dvr_error_small_sized_storage_description" msgid="8909789097974895119">"Uzokwazi ukurekhoda izinhlelo nge-DVR. Kodwa asikho isitoreji esanele kudivayisi yakho manje ukuze i-DVR isebenze. Sicela uxhume idrayivu yangaphandle engu-<xliff:g id="STORAGE_SIZE">%1$d</xliff:g>GB noma enkulu bese ulandela izinyathelo uyifomethe njengesitoreji sedivayisi."</string>
+ <string name="dvr_error_no_free_space_title" msgid="881897873932403512">"Indawo yokubeka ayanele"</string>
+ <string name="dvr_error_no_free_space_description" msgid="6406038381803431564">"Lolu hlelo ngeke lirekhodwe ngoba asikho isitoreji esanele. Zama ukususa ukurekhoda okukhona."</string>
<string name="dvr_error_missing_storage_title" msgid="691914341845362669">"Isitoreji esilahlekile"</string>
- <string name="dvr_error_missing_storage_description" msgid="1036680750969954236">"Esinye sesitoreji esisetshenziswa yi-DVR silahlekile. Sicela uxhume idrayivu engaphandle oyisebenzise ngaphambilini ukuze uphinde unike amandla i-DVR. Okunye, ungakhetha ukukhohlwa isitoreji uma singasatholakali."</string>
- <string name="dvr_error_forget_storage_title" msgid="4996547357826788002">"Khohlwa isitoreji?"</string>
- <string name="dvr_error_forget_storage_description" msgid="3973761741009546142">"Konke okuqukethwe kwakho okurekhodiwe namashejuli azolahleka."</string>
<string name="dvr_stop_recording_dialog_title" msgid="2587018956502704278">"Misa ukurekhoda?"</string>
<string name="dvr_stop_recording_dialog_description" msgid="4637830189399967761">"Okuqukethwe okurekhodiwe kuzolondolozwa."</string>
- <!-- no translation found for dvr_stop_recording_dialog_description_on_conflict (7876857267536083760) -->
- <skip />
+ <string name="dvr_stop_recording_dialog_description_on_conflict" msgid="7876857267536083760">"Ukurekhodwa kwe-<xliff:g id="PROGRAMNAME">%1$s</xliff:g> kuzomiswa ngoba kugqubuzana nalolu hlelo. Okuqukethwe okurekhodiwe ngeke kulondolozwe."</string>
<string name="dvr_program_conflict_dialog_title" msgid="109323740107060379">"Ukurekhoda kushejuliwe kodwa kunokugqubuzana"</string>
<string name="dvr_channel_conflict_dialog_title" msgid="7461033430572027786">"Ukurekhoda kuqalile kodwa kunokugxubuzana"</string>
<string name="dvr_program_conflict_dialog_description_prefix" msgid="5520062013211648196">"<xliff:g id="PROGRAMNAME">%1$s</xliff:g> izorekhodwa."</string>
@@ -306,17 +299,29 @@
<string name="dvr_already_scheduled_dialog_description" msgid="8170126125996414810">"Uhlelo olufanayo seluvele luhlelwe ukurekhodwa ngo-<xliff:g id="PROGRAMSTARTTIME">%1$s</xliff:g>."</string>
<string name="dvr_already_recorded_dialog_title" msgid="2760294707162057216">"Sekuvele kurekhodiwe"</string>
<string name="dvr_already_recorded_dialog_description" msgid="8966051583682746434">"Lolu hlelo seluvele lurekhodiwe. Lutholakala kulabhulali ye-DVR."</string>
- <!-- no translation found for dvr_series_recording_dialog_title (3521956660855853797) -->
- <skip />
- <!-- no translation found for dvr_series_recording_scheduled_no_conflict (2796926724821316879) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_this_series_conflict (2800805130979023066) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_one_conflict (3632394665556633158) -->
- <!-- no translation found for dvr_series_recording_scheduled_this_and_other_series_conflict (2331412040101938479) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_one_conflict (5213169239215104024) -->
- <!-- no translation found for dvr_series_recording_scheduled_only_other_series_conflict (5159645486201045330) -->
+ <string name="dvr_series_recording_dialog_title" msgid="3521956660855853797">"Ukurekhodwa kochungechunge kuhleliwe"</string>
+ <plurals name="dvr_series_scheduled_no_conflict" formatted="false" msgid="6909096418632555251">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ukurekhodwa kushejulelwe i-<xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ukurekhodwa kushejulelwe i-<xliff:g id="SERIESNAME_3">%2$s</xliff:g>.</item>
+ </plurals>
+ <plurals name="dvr_series_recording_scheduled_only_this_series_conflict" formatted="false" msgid="2341548158607418515">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ukurekhodwa kushejulelwe i-<xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> kwazo ngeke kurekhodwe ngenxa yokushayisana.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ukurekhodwa kushejulelwe i-<xliff:g id="SERIESNAME_3">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTRECORDINGS">%3$d</xliff:g> kwazo ngeke kurekhodwe ngenxa yokushayisana.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict" formatted="false" msgid="6123651855499916154">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ukurekhodwa kushejulelwe i-<xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> iziqephu zalo chungechunge nolunye uchungechunge ngeke zirekhodwe ngenxa yokushayisana.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ukurekhodwa kushejulelwe i-<xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> iziqephu zalo chungechunge nolunye uchungechunge ngeke zirekhodwe ngenxa yokushayisana.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict" formatted="false" msgid="8628389493339609682">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ukurekhodwa kushejulelwe i-<xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 isiqephu solunye uchungechunge ngeke sirekhodwe ngenxa yokushayisana.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_2">%1$d</xliff:g> ukurekhodwa kushejulelwe i-<xliff:g id="SERIESNAME_3">%2$s</xliff:g>. 1 isiqephu solunye uchungechunge ngeke sirekhodwe ngenxa yokushayisana.</item>
+ </plurals>
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts" formatted="false" msgid="1601104768354168073">
+ <item quantity="one"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ukurekhodwa kushejulelwe i-<xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> iziqephu zolunye uchungechunge ngeke zize zirekhodwe ngenxa yokushayisana.</item>
+ <item quantity="other"><xliff:g id="NUMBEROFRECORDINGS_3">%1$d</xliff:g> ukurekhodwa kushejulelwe i-<xliff:g id="SERIESNAME_4">%2$s</xliff:g>. <xliff:g id="NUMBEROFCONFLICTEPISODES_5">%3$d</xliff:g> iziqephu zolunye uchungechunge ngeke zize zirekhodwe ngenxa yokushayisana.</item>
+ </plurals>
<string name="dvr_program_not_found" msgid="3282879532038010202">"Uhlelo olurekhodiwe alutholakali."</string>
<string name="dvr_playback_related_recordings" msgid="6978658039329924961">"Ukurekhodwa okuhlobene"</string>
- <string name="dvr_msg_no_program_description" msgid="2521723281247322645">"(Ayikho incazelo yohlelo)"</string>
<plurals name="dvr_schedules_section_subtitle" formatted="false" msgid="9180744010405976007">
<item quantity="one">%1$d ukurekhoda</item>
<item quantity="other">%1$d ukurekhoda</item>
@@ -336,6 +341,7 @@
<string name="dvr_series_schedules_stop_dialog_title" msgid="4975886236535334420">"Misa ukurekhodwa kochungechunge"</string>
<string name="dvr_series_schedules_stop_dialog_description" msgid="7547266283366940085">"Iziqephu ezirekhodiwe zizohlala zitholakala kulabhulali ye-DVR."</string>
<string name="dvr_series_schedules_stop_dialog_action_stop" msgid="2351839914865142478">"Misa"</string>
+ <string name="dvr_series_schedules_stopped_empty_state" msgid="1464244804664395151">"Azikho iziqephu ezisemoyeni okwamanje."</string>
<string name="dvr_series_schedules_empty_state" msgid="3407962945399698707">"Azikho iziqephu ezitholakalayo.\nZizorekhodwa uma zitholakala."</string>
<plurals name="dvr_schedules_recording_duration" formatted="false" msgid="3701771573063918552">
<item quantity="one">(%1$d amaminithi)</item>
@@ -347,4 +353,5 @@
<string name="dvr_date_today_time" msgid="8359696776305244535">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> namhlanje"</string>
<string name="dvr_date_tomorrow_time" msgid="8364654556105292594">"<xliff:g id="TIME_RANGE">%1$s</xliff:g> kusasa"</string>
<string name="program_guide_critic_score" msgid="340530743913585150">"Isikolo"</string>
+ <string name="recorded_programs_preview_channel" msgid="890404366427245812">"Izinhlelo ezirekhodiwe"</string>
</resources>
diff --git a/res/values/attr.xml b/res/values/attr.xml
deleted file mode 100644
index 1261ea41..00000000
--- a/res/values/attr.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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>
- <declare-styleable name="CurrentProgramState" >
- <attr name="state_current_program" format="boolean" />
- </declare-styleable>
- <declare-styleable name="ProgramTooWideState" >
- <attr name="state_program_too_wide" format="boolean" />
- </declare-styleable>
-</resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
new file mode 100644
index 00000000..a26a9ef2
--- /dev/null
+++ b/res/values/attrs.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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>
+ <declare-styleable name="CurrentProgramState" >
+ <attr name="state_current_program" format="boolean" />
+ </declare-styleable>
+ <declare-styleable name="ProgramTooWideState" >
+ <attr name="state_program_too_wide" format="boolean" />
+ </declare-styleable>
+ <!-- XML attributes that describe the
+ {@link com.android.tv.dvr.ui.FadeBackground FadeBackground} transition. The
+ attributes of the {@link android.R.styleable#Transition Transition} resource are available
+ in addition to the specific attributes of FadeBackground described here. -->
+ <declare-styleable name="FadeBackground">
+ <!-- Equivalent to <code>transitionVisibilityMode</code>, fadingMode works only with the
+ FadeBackground transition. -->
+ <attr name="fadingMode">
+ <!-- FadeBackground will only fade appearing items in. -->
+ <enum name="fade_in" value="1" />
+ <!-- FadeBackground will only fade disappearing items out. -->
+ <enum name="fade_out" value="2" />
+ </attr>
+ </declare-styleable>
+
+ <!-- XML attributes that describe the
+ {@link com.android.tv.menu.widget.PlaybackProgressBar PlaybackProgressBar} widget.
+ The attributes of the {@link com.android.internal.R.styleable.View View} resources are
+ available in addition to the specific attributes of PlaybackProgressBar described here. -->
+ <declare-styleable name="PlaybackProgressBar">
+ <!-- Drawable used for the progress mode. -->
+ <attr name="progressDrawable" format="reference" />
+ </declare-styleable>
+</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index b6b40563..e0a0b99f 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -109,11 +109,11 @@
<!-- TV view -->
<color name="tvview_block_text_color">#80EEEEEE</color>
+ <color name="tvview_block_image_color_filter">#99000000</color>
<!-- Channel banner -->
<color name="channel_banner_text_color">#FFEEEEEE</color>
<color name="channel_banner_episode_text_color">#B3EEEEEE</color>
- <color name="channel_banner_secondary_input_label_color">#B3EEEEEE</color>
<color name="channel_banner_dim_text_color">#80EEEEEE</color>
<!-- Keypad channel switch -->
@@ -121,7 +121,7 @@
<!-- Select input -->
<color name="select_input_text_color_primary">@color/channel_banner_text_color</color>
- <color name="select_input_text_color_secondary">@color/channel_banner_secondary_input_label_color</color>
+ <color name="select_input_text_color_secondary">#B3EEEEEE</color>
<color name="select_input_text_color_disabled">#4DEEEEEE</color>
<!-- Recommendation cards in LeanbackLauncher -->
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8d9e45e1..9d8941fa 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -16,8 +16,12 @@
-->
<resources>
+ <!-- from https://developer.android.com/training/tv/start/layouts.html#structure -->
+ <dimen name="vertical_overscan_safe_margin">27dp</dimen>
+ <dimen name="horizontal_overscan_safe_margin">48dp</dimen>
+
<!-- Main menu -->
- <dimen name="menu_margin_top">@dimen/menu_enter_offset_y_negative</dimen>
+ <dimen name="menu_margin_top">-32dp</dimen>
<dimen name="menu_margin_bottom_min">27dp</dimen>
<dimen name="menu_row_align_from_bottom">124dp</dimen>
<dimen name="menu_row_title_width">300dp</dimen>
@@ -41,7 +45,6 @@
<dimen name="menu_row_title_text_size_deselected">16sp</dimen>
<dimen name="menu_inter_card_spacing">8dp</dimen>
<dimen name="menu_enter_offset_y">32dp</dimen>
- <dimen name="menu_enter_offset_y_negative">-32dp</dimen>
<dimen name="menu_exit_offset_y">32dp</dimen>
<dimen name="menu_row_scroll_up_anim_offset">32dp</dimen>
@@ -102,7 +105,6 @@
<dimen name="action_card_icon_width">32dp</dimen>
<dimen name="action_card_icon_height">32dp</dimen>
<dimen name="action_card_icon_padding">10dp</dimen>
- <dimen name="action_card_padding">12dp</dimen>
<dimen name="action_card_label_font_size">16sp</dimen>
<dimen name="action_card_state_font_size">12sp</dimen>
@@ -115,7 +117,6 @@
<dimen name="side_panel_header_padding_top">27dp</dimen>
<dimen name="side_panel_header_elevation">4dp</dimen>
<dimen name="side_panel_header_text_size">24sp</dimen>
- <dimen name="side_panel_list_padding_top">0dp</dimen>
<dimen name="side_panel_list_padding_bottom">48dp</dimen>
<dimen name="side_panel_list_vertical_margin">0dp</dimen>
<dimen name="side_panel_enter_offset_x">100dp</dimen>
@@ -147,7 +148,6 @@
<!-- Program guide -->
<dimen name="program_guide_shift_start_to_end_x">238dp</dimen>
- <dimen name="program_guide_shift_end_to_start_x">-238dp</dimen>
<dimen name="program_guide_side_panel_width">270dp</dimen>
<dimen name="program_guide_side_panel_margin_start">-238dp</dimen>
<dimen name="program_guide_side_panel_padding_start">56dp</dimen>
@@ -193,7 +193,7 @@
<dimen name="program_guide_table_header_row_height">40dp</dimen>
<dimen name="program_guide_table_header_row_font_size">16sp</dimen>
<dimen name="program_guide_table_header_row_fade_length">24dp</dimen>
- <dimen name="program_guide_table_header_row_overlap">-52dp</dimen>
+ <dimen name="program_guide_table_header_row_overlap">-72dp</dimen>
<dimen name="program_guide_table_item_row_height">64dp</dimen>
<dimen name="program_guide_table_item_padding">16dp</dimen>
<dimen name="program_guide_table_item_compound_drawable_padding">8dp</dimen>
@@ -244,23 +244,9 @@
<dimen name="shrunken_tvview_block_icon_height">60dp</dimen>
<dimen name="shrunken_tvview_block_vertical_spacing">24dp</dimen>
- <!-- PIP view -->
- <dimen name="pipview_margin_horizontal">56dp</dimen>
- <dimen name="pipview_margin_top">27dp</dimen>
- <dimen name="pipview_margin_bottom">27dp</dimen>
- <dimen name="pipview_small_size_width">240dp</dimen>
- <dimen name="pipview_small_size_height">135dp</dimen>
- <dimen name="pipview_large_size_width">384dp</dimen>
- <dimen name="pipview_large_size_height">216dp</dimen>
-
- <!-- PAP View -->
- <dimen name="papview_margin_horizontal">20dp</dimen>
- <dimen name="papview_spacing">24dp</dimen>
-
<!-- Edit channels -->
<dimen name="shrunken_tvview_margin_start">56dp</dimen>
<dimen name="shrunken_tvview_margin_end">32dp</dimen>
- <dimen name="shrunken_tvview_height">288dp</dimen>
<!-- Channel banner -->
<dimen name="channel_banner_width">696dp</dimen>
@@ -274,7 +260,7 @@
<dimen name="channel_banner_channel_logo_height">44dp</dimen>
<dimen name="channel_banner_channel_logo_margin_start">8dp</dimen>
<dimen name="channel_banner_input_logo_size">16dp</dimen>
- <dimen name="channel_banner_program_description_width">536dp</dimen>
+ <dimen name="channel_banner_program_description_width">456dp</dimen>
<dimen name="channel_banner_program_large_text_size">28sp</dimen>
<dimen name="channel_banner_program_medium_text_size">20sp</dimen>
<dimen name="channel_banner_program_large_margin_top">-10sp</dimen>
@@ -290,6 +276,7 @@
<!-- Input banner -->
<dimen name="input_banner_item_height">48dp</dimen>
+ <dimen name="input_banner_item_label_max_width">324dp</dimen>
<!-- Keypad channel switch -->
<dimen name="keypad_channel_switch_channel_number_text_size">
@@ -336,9 +323,7 @@
<!-- DVR screens -->
<eat-comment />
- <dimen name="dvr_card_layout_width">196dp</dimen>
-
- <!--DVR schedules list-->
+ <!-- DVR schedules list -->
<dimen name="dvr_schedules_layout_padding">132dp</dimen>
<dimen name="dvr_schedules_row_divider_height">1dp</dimen>
<dimen name="dvr_schedules_item_width">960dp</dimen>
@@ -349,9 +334,7 @@
<dimen name="dvr_schedules_item_time_start_padding">32dp</dimen>
<dimen name="dvr_schedules_item_time_margin">14dp</dimen>
<dimen name="dvr_schedules_item_info_top_margin">15dp</dimen>
- <dimen name="dvr_schedules_item_conflict_info_top_margin">12dp</dimen>
<dimen name="dvr_schedules_item_conflict_info_bottom_margin">15dp</dimen>
- <dimen name="dvr_schedules_item_schedule_width">56dp</dimen>
<dimen name="dvr_schedules_item_delete_width">46dp</dimen>
<dimen name="dvr_schedules_item_section_margin">32dp</dimen>
<dimen name="dvr_schedules_item_icon_size">18dp</dimen>
@@ -361,26 +344,31 @@
<dimen name="dvr_schedules_header_margin_bottom">24dp</dimen>
<dimen name="dvr_schedules_header_subtitle_margin_top">5dp</dimen>
<dimen name="dvr_schedules_header_icon_container_width">143dp</dimen>
- <dimen name="dvr_schedules_header_icon_size">32dp</dimen>
<dimen name="dvr_schedules_header_icon_horizontal_margin">12dp</dimen>
<dimen name="dvr_schedules_warning_icon_padding">4dp</dimen>
- <!-- card width - margin-->
- <dimen name="dvr_card_image_layout_width">192dp</dimen>
- <dimen name="dvr_card_image_layout_height">108dp</dimen>
- <dimen name="dvr_card_progress_height">2dp</dimen>
+ <!-- DVR Library -->
+ <dimen name="dvr_library_expanded_row_height">175dp</dimen>
+ <dimen name="dvr_library_card_image_layout_width">144dp</dimen>
+ <dimen name="dvr_library_card_image_layout_height">108dp</dimen>
+ <dimen name="dvr_library_card_progress_height">2dp</dimen>
+ <dimen name="dvr_library_card_folded_title_height">20dp</dimen>
+ <dimen name="dvr_library_card_expanded_title_height">36.5dp</dimen>
<!-- DVR playback fragment -->
- <dimen name="dvr_related_recordings_width">146dp</dimen>
- <dimen name="dvr_related_recordings_height">82dp</dimen>
+ <dimen name="dvr_related_recordings_width">108dp</dimen>
+ <dimen name="dvr_related_recordings_height">81dp</dimen>
<!-- This value is used to adjust position of DVR playback controls row when there is no
program description -->
<dimen name="dvr_playback_controls_extra_padding_top">27.5dp</dimen>
- <!-- This value is used to adjust position of DVR playback overlay fragment when there is no
- related recordings -->
- <dimen name="dvr_playback_fragment_extra_padding_top">48dp</dimen>
- <dimen name="lb_playback_controls_padding_top">265dp</dimen>
- <dimen name="lb_playback_controls_padding_bottom">40dp</dimen>
+ <!-- This value is used to adjust the vertical position of DVR playback overlay fragment -->
+ <dimen name="dvr_playback_overlay_padding_top_base">36dp</dimen>
+ <!-- This value is used to adjust the vertical position of DVR playback overlay fragment when
+ there is no related recordings -->
+ <dimen name="dvr_playback_overlay_padding_top_no_related_row">44dp</dimen>
+ <!-- This value is used to adjust the vertical position of DVR playback overlay fragment when
+ there is no secondary controls row -->
+ <dimen name="dvr_playback_overlay_padding_top_no_secondary_row">4dp</dimen>
<!-- details fragment -->
<dimen name="dvr_details_poster_width">219dp</dimen>
@@ -390,6 +378,7 @@
<dimen name="dvr_deletion_check_mark_margin">20dp</dimen>
<dimen name="dvr_details_overview_description_margin_start">12dp</dimen>
<dimen name="dvr_details_overview_description_margin_end">12dp</dimen>
+ <dimen name="dvr_details_description_under_subtitle_baseline_margin">30dp</dimen>
<!-- Below values are used to avoid detail titles' layout changing with two-line titles -->
<dimen name="dvr_details_description_title_resized_text_size">34sp</dimen>
<dimen name="dvr_details_description_title_padding_adjust_top">0dp</dimen>
@@ -401,4 +390,8 @@
button actions list width = 138dp (weight = 0.39) -->
<item name="dvr_settings_button_actions_list_width_weight" format="float" type="dimen">0.39</item>
<item name="dvr_settings_guidedactions_width_weight" format="float" type="string">1.15</item>
+
+ <!-- Preview channel logo size -->
+ <dimen name="preview_channel_logo_width">80dp</dimen>
+ <dimen name="preview_channel_logo_height">80dp</dimen>
</resources>
diff --git a/res/values/google-services.xml b/res/values/google-services.xml
deleted file mode 100755
index 379a3453..00000000
--- a/res/values/google-services.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<resources>
- <string name="firebase_database_url" translatable="false">https://live-channels-1237.firebaseio.com</string>
- <string name="gcm_defaultSenderId" translatable="false">399597460505</string>
- <string name="google_api_key" translatable="false">AIzaSyDK2BtNulo2ltWIogD64y1hBWKrdg9Sa7k</string>
- <string name="google_crash_reporting_api_key" translatable="false">AIzaSyDK2BtNulo2ltWIogD64y1hBWKrdg9Sa7k</string>
- <string name="google_app_id" translatable="false">1:399597460505:android:6c699100869b1467</string>
-</resources>
diff --git a/res/values/integers.xml b/res/values/integers.xml
index 81ccbeb7..003344e3 100644
--- a/res/values/integers.xml
+++ b/res/values/integers.xml
@@ -35,7 +35,10 @@
<integer name="menu_row_selection_anim_duration">250</integer>
<integer name="menu_previous_contents_fade_out_duration">50</integer>
<integer name="menu_current_contents_fade_in_duration">200</integer>
-
+
+ <!-- Option item -->
+ <integer name="option_item_description_max_lines">3</integer>
+
<!-- Side panel -->
<integer name="side_panel_show_duration">60000</integer>
<integer name="side_panel_anim_duration">250</integer>
@@ -74,6 +77,9 @@
<integer name="pin_dialog_exit_offset_y">32</integer>
<integer name="pin_number_scroll_duration">250</integer>
+ <!-- Trickplay Setting -->
+ <integer name="trickplay_description_max_lines">5</integer>
+
<!-- Max recycle view pool size -->
<integer name="max_recycled_view_pool_epg_table_item">50</integer>
<integer name="max_recycled_view_pool_epg_table_row">15</integer>
@@ -87,4 +93,5 @@
<!-- DVR library -->
<integer name="dvr_details_full_text_animation_duration">500</integer>
+ <integer name="dvr_card_title_max_lines_folded">1</integer>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a58f2d36..57049aba 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -35,6 +35,12 @@
<!-- Description of an application permission, listed so the user can choose
whether they want to allow the application to do this. -->
<string name="permdesc_receiveInputEvent" translatable="false">Allows the app to receive input events from Live TV app</string>
+ <!-- Title of an application permission, listed so the user can choose
+ whether they want to allow the application to do this. -->
+ <string name="permlab_customizeTvApp" translatable="false">customize Live TV app</string>
+ <!-- Description of an application permission, listed so the user can choose
+ whether they want to allow the application to do this. -->
+ <string name="permdesc_customizeTvApp" translatable="false">Allows the app to customize Live TV app</string>
<!-- Program information, mainly used for channel banner and program guide. -->
<eat-comment />
@@ -63,11 +69,9 @@
The play means a playback of video and audio. [CHAR LIMIT=NONE] -->
<string name="menu_title_play_controls">Play controls</string>
<!-- Title of the channels row in the main menu. [CHAR LIMIT=NONE] -->
- <string name="menu_title_channels">Recent channels</string>
+ <string name="menu_title_channels">Channels</string>
<!-- Title of the TV option row in the main menu. [CHAR LIMIT=NONE] -->
<string name="menu_title_options">TV options</string>
- <!-- Title of the PIP option row in the main menu. [CHAR LIMIT=NONE] -->
- <string name="menu_title_pip_options">PIP options</string>
<!-- Play speed of 2X, 3X, 4X, 5X -->
<string name="play_controls_speed" translatable="false">%1$dX</string>
@@ -101,12 +105,6 @@
<string name="options_item_display_mode">Display mode</string>
<!-- Label of "PIP (Picture in picture)" item in the TV option row. [CHAR LIMIT=17] -->
<string name="options_item_pip">PIP</string>
- <!-- Description of the "PIP" item in the TV option row indicating that the currently the PIP
- is turned on. [CHAR LIMIT=17] -->
- <string name="options_item_pip_on">On</string>
- <!-- Description of the "PIP" item in the TV option row indicating that the currently the PIP
- is turned off. [CHAR LIMIT=20] -->
- <string name="options_item_pip_off">Off</string>
<!-- Label of "Multi audio" item in the TV option row. [CHAR LIMIT=17] -->
<string name="options_item_multi_audio">Multi-audio</string>
<!-- Label of "Get more channels" item in the TV option row. [CHAR LIMIT=17] -->
@@ -116,54 +114,6 @@
<!-- Label of "Settings" item in the TV option row. [CHAR LIMIT=17] -->
<string name="options_item_settings">Settings</string>
- <!-- Label of "Source" item in the PIP option row. The item enables the user to select
- a specific input (e.g. HDMI 1) for the PIP window. [CHAR LIMIT=17] -->
- <string name="pip_options_item_source">Source</string>
- <!-- Label of "Swap" item in the PIP option row.
- After swapping, the main window and PIP window will show the channels of each other. [CHAR LIMIT=17] -->
- <string name="pip_options_item_swap">Swap</string>
- <!-- Description of the "Swap" item in the PIP option row indicating that the currently the
- windows are swapped. [CHAR LIMIT=20] -->
- <string name="pip_options_item_swap_on">On</string>
- <!-- Description of the "Swap" item in the PIP option row indicating that the currently the
- windows are not swapped. [CHAR LIMIT=20] -->
- <string name="pip_options_item_swap_off">Off</string>
- <!-- Label of "Sound" item in the PIP option row. [CHAR LIMIT=17] -->
- <string name="pip_options_item_sound">Sound</string>
- <!-- Description of the "Sound" item in the PIP option row indicating that the current sound
- source is main window. [CHAR LIMIT=20] -->
- <string name="pip_options_item_sound_main">Main</string>
- <!-- Description of the "Sound" item in the PIP option row indicating that the current sound
- source is PIP window. [CHAR LIMIT=20] -->
- <string name="pip_options_item_sound_pip_window">PIP window</string>
- <!-- Label of "Layout" item in the PIP option row. [CHAR LIMIT=17] -->
- <string name="pip_options_item_layout">Layout</string>
- <!-- Description of the "Layout" item in the PIP option row indicating that the current PIP
- window is at the bottom right corner of the screen. [CHAR LIMIT=20] -->
- <string name="pip_options_item_layout_bottom_right">Bottom right</string>
- <!-- Description of the "Layout" item in the PIP option row indicating that the current PIP
- window is at the top right corner of the screen. [CHAR LIMIT=20] -->
- <string name="pip_options_item_layout_top_right">Top right</string>
- <!-- Description of the "Layout" item in the PIP option row indicating that the current PIP
- window is at the top left corner of the screen. [CHAR LIMIT=20] -->
- <string name="pip_options_item_layout_top_left">Top left</string>
- <!-- Description of the "Layout" item in the PIP option row indicating that the current PIP
- window is at the bottom left corner of the screen. [CHAR LIMIT=20] -->
- <string name="pip_options_item_layout_bottom_left">Bottom left</string>
- <!-- Description of the "Layout" item in the PIP option row indicating that the current PIP
- layout is side-by-side (i.e. Picture and Picture). [CHAR LIMIT=20] -->
- <string name="pip_options_item_layout_side_by_side">Side by side</string>
- <!-- Label of "Size" item in the PIP option row. [CHAR LIMIT=17] -->
- <string name="pip_options_item_size">Size</string>
- <!-- Description of the "Size" item in the PIP option row indicating that the current PIP size
- is big. [CHAR LIMIT=20] -->
- <string name="pip_options_item_size_big">Big</string>
- <!-- Description of the "Size" item in the PIP option row indicating that the current PIP size
- is small. [CHAR LIMIT=20] -->
- <string name="pip_options_item_size_small">Small</string>
-
- <!-- Title of "Input source" option to select an input for PIP. [CHAR LIMIT=30] -->
- <string name="side_panel_title_pip_input_source">Input source</string>
<!-- Label of a unified input for tuner type inputs. [CHAR LIMIT=30] -->
<string name="input_long_label_for_tuner">TV (antenna/cable)</string>
@@ -175,8 +125,11 @@
<!-- Program title for blocked channel [CHAR LIMIT=23] -->
<string name="program_title_for_blocked_channel">Blocked channel</string>
- <!-- Default string for unknown language used in "Closed Caption" and "Multi Audio" options. [CHAR LIMIT=30] -->
- <string name="default_language">Unknown language</string>
+ <!-- Default string for unknown language used in "Multi Audio" options. [CHAR LIMIT=30] -->
+ <string name="multi_audio_unknown_language">Unknown language</string>
+
+ <!-- Default string for unknown language used in "Closed Caption" options. [CHAR LIMIT=30] -->
+ <string name="closed_caption_unknown_language">Closed captions %1$d</string>
<!-- Inside "Closed captions" option side panel -->
<eat-comment />
@@ -238,6 +191,8 @@
<eat-comment />
<!-- Description in the TV guide when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
<string name="program_guide_content_locked">This program is blocked</string>
+ <!-- Description in the TV guide when the current content is unrated and it's restricted by parental control. [CHAR LIMIT=NONE] -->
+ <string name="program_guide_content_locked_unrated">This program is unrated</string>
<!-- Description in the TV guide with the rating when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
<string name="program_guide_content_locked_format">This program is rated <xliff:g id="rating" example="TV_MA">%1$s</xliff:g></string>
@@ -257,11 +212,6 @@
<!-- Message after no channel is added after setting up an input. [CHAR LIMIT=NONE] -->
<string name="msg_no_channel_added">No channels added</string>
- <!-- Inside "Input Selector" option side panel -->
- <eat-comment />
- <!-- Label of a tuner input in "Input Selector" option. [CHAR LIMIT=30] -->
- <string name="input_selector_tuner_label">Tuner</string>
-
<!-- Parental control -->
<eat-comment />
<!-- Title of "Parental Contrals" option. [CHAR LIMIT=30] -->
@@ -304,6 +254,12 @@
[CHAR LIMIT=NONE] -->
<string name="option_no_enabled_rating_system">None</string>
+ <!-- Display name of unrated rating -->
+ <string name="unrated_rating_name">Unrated</string>
+
+ <!-- Label of an item to block unrated programs. [CHAR LIMIT=30] -->
+ <string name="option_block_unrated_programs">Block unrated programs</string>
+
<!-- Label of an item not to select any restriction. [CHAR LIMIT=30] -->
<string name="option_rating_none">None</string>
<!-- Label of an item to select high restriction. [CHAR LIMIT=30] -->
@@ -349,6 +305,9 @@
<!-- Title of PIN dialog when an user is asked to enter PIN to unlock DVR playback.
[CHAR LIMIT=NONE] -->
<string name="pin_enter_unlock_dvr">This program is rated <xliff:g id="rating" example="TV_MA">%1$s</xliff:g>. Enter your PIN to watch this program</string>
+ <!-- Title of PIN dialog when an user is asked to enter PIN to unlock unrated DVR playback.
+ [CHAR LIMIT=NONE] -->
+ <string name="pin_enter_unlock_dvr_unrated">This program is unrated. Enter your PIN to watch this program</string>
<!-- Title of PIN dialog when an user tries to change Parental control setting.
[CHAR LIMIT=NONE] -->
<string name="pin_enter_pin">Enter your PIN</string>
@@ -371,6 +330,15 @@
<!-- Toast message when an user couldn't pass the PIN confirmation. [CHAR LIMIT=NONE] -->
<string name="pin_toast_not_match">Try again, PIN doesn\'t match</string>
+ <!-- Title of postal/zip code input guided step fragment [CHAR LIMIT=30] -->
+ <string name="postal_code_guidance_title">Enter your ZIP Code.</string>
+ <!-- Description of postal/zip code input guided step fragment [CHAR LIMIT=NONE] -->
+ <string name="postal_code_guidance_description">Live TV app will use the ZIP Code to provide a complete program guide for the TV channels.</string>
+ <!-- Description of postal/zip code input edit text view to prompt users entering ZIP Code [CHAR LIMIT=30] -->
+ <string name="postal_code_action_description">Enter your ZIP Code</string>
+ <!-- Warning message shown in description field of postal/zip code input edit text view when user enters an invalid ZIP Code and presses Done [CHAR LIMIT=30] -->
+ <string name="postal_code_invalid_warning">Invalid ZIP Code</string>
+
<!-- menu for "Settings" option -->
<eat-comment />
<!-- Title of "Settings" option. [CHAR LIMIT=30] -->
@@ -387,10 +355,16 @@
<string name="settings_channel_source_item_setup_new_inputs">New channels available</string>
<!-- Label of "Parental controls" item. [CHAR LIMIT=30] -->
<string name="settings_parental_controls">Parental controls</string>
+ <!-- Label of "Timeshift" item. Record while watching so you can pause or rewind live
+ programs.-->
+ <string name="settings_trickplay">Timeshift</string>
+ <!-- Description of "Timeshift" item. This explains what is 'Timeshift' to users. Also warns of
+ the effect of enabling the option. -->
+ <string name="settings_trickplay_description">Record while watching so you can pause or rewind live programs.\nWarning: This may decrease the life of the internal storage by the intensive use of the storage.</string>
<!-- Menu item to show licenses for open source code used in the app [CHAR LIMIT=35] -->
<string name="settings_menu_licenses">Open source licenses</string>
- <!--Title for a dialog box that shows licenses for open source code used in the app [CHAR LIMIT=35] -->
- <string name="dialog_title_licenses">Open source licenses</string>
+ <!-- Menu item to send feedback [CHAR LIMIT=30] -->
+ <string name="settings_send_feedback">Send feedback</string>
<!-- Menu item that shows the application version(eg 1.2.03-final) as a second line below this title [CHAR LIMIT=35] -->
<string name="settings_menu_version">Version</string>
@@ -403,17 +377,23 @@
<string name="tvview_channel_locked">To watch this channel, press Right and enter your PIN</string>
<!-- Description on the locked screen when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
<string name="tvview_content_locked">To watch this program, press Right and enter your PIN</string>
+ <!-- Description on the locked screen when the current content is unrated and it's restricted by parental control. [CHAR LIMIT=NONE] -->
+ <string name="tvview_content_locked_unrated">This program is unrated.\nTo watch this program, press Right and enter your PIN</string>
<!-- Description on the locked screen with the rating when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
<string name="tvview_content_locked_format">This program is rated <xliff:g id="rating" example="TV_MA">%1$s</xliff:g>.\nTo watch this program, press Right and enter your PIN.</string>
<!-- Description on the locked screen when current channel is locked by parental control. [CHAR LIMIT=NONE] -->
<string name="tvview_channel_locked_no_permission">To watch this channel, use the default Live TV app.</string>
<!-- Description on the locked screen when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
<string name="tvview_content_locked_no_permission">To watch this program, use the default Live TV app.</string>
+ <!-- Description on the locked screen when the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
+ <string name="tvview_content_locked_unrated_no_permission">This program is unrated.\nTo watch this program, use the default Live TV app.</string>
<!-- Description on the locked screen with the rating when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
<string name="tvview_content_locked_format_no_permission">This program is rated <xliff:g id="rating" example="TV_MA">%1$s</xliff:g>.\nTo watch this program, use the default Live TV app.</string>
<!-- Description on the locked screen when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
<string name="shrunken_tvview_content_locked">Program is blocked</string>
+ <!-- Description on the locked screen with the rating when the current content is unrated and it's restricted by parental control. [CHAR LIMIT=NONE] -->
+ <string name="shrunken_tvview_content_locked_unrated">This program is unrated</string>
<!-- Description on the locked screen with the rating when the rating of the current content is restricted by parental control. [CHAR LIMIT=NONE] -->
<string name="shrunken_tvview_content_locked_format">This program is rated <xliff:g id="rating" example="TV_MA">%1$s</xliff:g></string>
@@ -486,10 +466,6 @@
<string name="msg_no_input">No TV input found</string>
<!-- Error message when a specific TV input isn't installed. [CHAR LIMIT=NONE] -->
<string name="msg_no_specific_input">Cannot find the TV input</string>
- <!-- Error message when PIP is not supported. [CHAR LIMIT=NONE] -->
- <string name="msg_no_pip_support">PIP is not supported</string>
- <!-- Error message when there is no available input. [CHAR LIMIT=NONE] -->
- <string name="msg_no_available_input_by_pip">There is no available input which can be shown with PIP</string>
<!-- Error message when the selected TV input is a tuner type TV input, not a pass-through type
input. Tuner type inputs such as built-in tuner, external usb tuner, network tuner or
virtual IPTV tuner provide live channels to tune to. As opposed to tuner type input,
@@ -519,22 +495,39 @@
<!-- Debug Options -->
<string name="menu_developer_options" translatable="false">Developer options</string>
<string name="dev_item_watch_history" translatable="false">Watch history</string>
+ <string name="dev_item_dvr_history" translatable="false">DVR history</string>
<string name="dev_item_fetch_epg" translatable="false">Fetch program guide</string>
- <string name="dev_item_send_feedback" translatable="false">Send feedback</string>
<string name="dev_item_store_ts_on" translatable="false">Store TS for debugging: On</string>
<string name="dev_item_store_ts_off" translatable="false">Store TS for debugging: Off</string>
<string name="dev_item_store_ts_description" translatable="false">Store some TS data before exceptions/crash for debugging.</string>
+ <string name="dev_item_show_performance_monitor_log" translatable="false">Show performance log</string>
+
+ <!-- The state of the schedules which is in DVR history. -->
+ <string name="dvr_history_dialog_state_fail" translatable="false">[Fail]</string>
+ <string name="dvr_history_dialog_state_success" translatable="false">[Success]</string>
+ <string name="dvr_history_dialog_state_clip" translatable="false">[Clip]</string>
<!-- Title of Recently watched dialog. It is used for debug purpose. -->
<string name="recently_watched" translatable="false">Recently watched</string>
+ <!-- Title of DVR history dialog. -->
+ <string name="dvr_history_dialog_title" translatable="false">DVR history</string>
+
+ <!-- Display name of DVR recording service's notification channel. -->
+ <string name="dvr_notification_channel_name" translatable="false">Live TV DVR</string>
+ <!-- Content title of DVR recording service's notification. -->
+ <string name="dvr_notification_content_title" translatable="false">Live TV DVR</string>
+ <!-- Content text of DVR recording service's notification during recording. -->
+ <string name="dvr_notification_content_text_recording" translatable="false">Live TV are recording.</string>
+ <!-- Content text of DVR recording service's notification during updating schedules. -->
+ <string name="dvr_notification_content_text_loading" translatable="false">Live TV are updating recording schedules.</string>
+
<!-- EPG Search strings. -->
<!-- Remove translatable="false" once UI is finalized -->
<string name="search_result_no_result" translatable="false">No result</string>
<string name="search_result_title" translatable="false">Search results</string>
- <!-- Onboarding experience.
- TODO: Change translatable to true.-->
+ <!-- Onboarding experience. -->
<eat-comment />
<!-- Text for the channel sources screen in onboarding. -->
<string name="setup_sources_text">Set up your sources</string>
@@ -542,25 +535,11 @@
<string name="setup_sources_description">Live channels combines the experience of traditional TV channels with streaming channels provided by apps.
\n\nGet started by setting up the channel sources already installed. Or browse Google Play Store for more apps that offer live channels.</string>
- <!-- DVR TODO(DVR): make translatable true. -->
- <eat-comment />
- <!-- Dialog message to ask to remove the selected recording schedule. -->
- <string name="epg_dvr_dialog_message_remove_recording_schedule" translatable="false">Cancel recording</string>
- <!-- Dialog message to ask to stop the current recording. -->
- <string name="epg_dvr_dialog_message_stop_recording" translatable="false">Stop recording</string>
- <!-- Item label to schedule program recording. -->
- <string name="epg_dvr_record_program" translatable="false">Record program</string>
- <!-- Item label to schedule whole season recording of a TV show. -->
- <string name="epg_dvr_record_season" translatable="false">Record season</string>
- <!-- Item label to delete a recording schedule when a recording scheduled program is
- clicked in EPG. -->
- <string name="epg_dvr_delete_program" translatable="false">Delete schedule</string>
-
<!-- Menu item label to start DVR manager UI. -->
<string name="channels_item_dvr">Recordings &amp; schedules</string>
<!-- Menu item label to start recording of the current channel. -->
<string name="channels_item_record_start" translatable="false">Start recording</string>
- <!-- Menu item label to start recording of the current channel. -->
+ <!-- Menu item label to stop recording of the current channel. -->
<string name="channels_item_record_stop" translatable="false">Stop recording</string>
<!-- The action to record the current channel for 10 minutes. [CHAR LIMIT=30] -->
@@ -586,15 +565,10 @@
<string name="dvr_main_series">Series</string>
<!-- Header of DVR tab label for recorded programs list without any genre [CHAR LIMIT=20] -->
<string name="dvr_main_others">Others</string>
- <string name="dvr_msg_no_recording_on_the_row" translatable="false">None</string>
- <string name="dvr_msg_channel_unknown" translatable="false">Channel unknown</string>
- <string name="dvr_msg_no_available_tuners_for_recording_channel" translatable="false">No available tuners to record this channel.</string>
- <string name="dvr_msg_channel_already_recording" translatable="false">The channel is already being recorded.</string>
<!-- Toast message that the current channel cannot be recorded. -->
<string name="dvr_msg_cannot_record_channel">The channel cannot be recorded.</string>
<!-- Toast message that the current program cannot be recorded. -->
<string name="dvr_msg_cannot_record_program">The program cannot be recorded.</string>
- <string name="dvr_msg_no_item_in_browse" translatable="false">There is no item.</string>
<!-- Toast message that a new recording schedule has been created from the user action. -->
<string name="dvr_msg_program_scheduled"><xliff:g id="programName" example="Big bang theory">%1$s</xliff:g> has been scheduled to be recorded</string>
<!-- Toast message that a new recording schedule of the current program has been created
@@ -631,9 +605,10 @@
<!-- DVR detailed page -->
<eat-comment />
- <string name="dvr_detail_cancel" translatable="false">Cancel recording</string>
- <string name="dvr_detail_stop_keep" translatable="false">Stop and keep recording</string>
- <string name="dvr_detail_stop_delete" translatable="false">Stop and delete recording</string>
+ <!-- Button label to cancel the recording schedule. -->
+ <string name="dvr_detail_cancel_recording">Cancel recording</string>
+ <!-- Button label to stop the current recording. -->
+ <string name="dvr_detail_stop_recording">Stop recording</string>
<!-- Button label to play recorded programs from beginning.
Displayed when there's no watched history available. [CHAR LIMIT=15] -->
<string name="dvr_detail_watch">Watch</string>
@@ -655,6 +630,7 @@
<!-- Text label to indicate there's more text in the details description [CHAR LIMIT=20] -->
<string name="dvr_detail_read_more">Read more</string>
+
<!-- DVR series settings -->
<eat-comment />
<!-- Title of DVR series deletion [CHAR LIMIT=25] -->
@@ -709,18 +685,10 @@
<!-- DVR epg strings -->
<eat-comment />
- <string name="dvr_action_tune" translatable="false">Tune</string>
- <!-- The action to cancel and close the dialog. [CHAR LIMIT=10] -->
- <string name="dvr_action_cancel">Cancel</string>
<string name="dvr_action_delete_schedule" translatable="false">Delete schedule</string>
<string name="dvr_action_record_program" translatable="false">Record program</string>
- <string name="dvr_action_record_one_episode" translatable="false">Record this episode only</string>
- <string name="dvr_action_error_done" translatable="false">Done</string>
- <string name="dvr_action_error_open_dvr" translatable="false">Open DVR</string>
- <!-- The action to cancel forgetting DVR storage. -->
- <string name="dvr_action_error_cancel">Cancel</string>
- <!-- The action to forget DVR storage which is missing currently -->
- <string name="dvr_action_error_forget_storage">Forget</string>
+ <!-- The action to forget DVR storage which is missing currently. invoke android internal storage settings activity. -->
+ <string name="dvr_action_error_storage_settings" translatable="false">Open storage settings</string>
<!-- The action to stop recording. [CHAR LIMIT=10] -->
<string name="dvr_action_stop">Stop</string>
<!-- The action to open the activity which shows all the schedules.[CHAR LIMIT=32] -->
@@ -749,6 +717,8 @@
<string name="dvr_action_record_cancel">Cancel this recording</string>
<!-- The title of the action to show the details of the recorded program. [CHAR LIMIT=32] -->
<string name="dvr_action_watch_now">Watch now</string>
+ <!-- The title of the action to open the DVR library to delete some recorded programs. [CHAR LIMIT=32] -->
+ <string name="dvr_action_delete_recordings">Delete recordings&#8230;</string>
<!-- Dvr label in epg to indicate the program is recordable. [CHAR LIMIT=30] -->
<string name="dvr_epg_program_recordable">Recordable</string>
<!-- Dvr label in epg to indicate the program is scheduled to be recorded. [CHAR LIMIT=30] -->
@@ -762,28 +732,37 @@
<string name="dvr_epg_program_icon_text" translatable="false">DVR</string>
<string name="dvr_epg_channel_watch_conflict_dialog_title" translatable="false">Upcoming schedules</string>
<string name="dvr_epg_channel_watch_conflict_dialog_description" translatable="false">The programs will not be recorded if you keep watching this channel. Cancel the recordings, or current channel will be blocked when the recording starts.</string>
- <!-- A popup message which informs that Live TV is reading program information to create
- recording schedules. -->
- <string name="dvr_schedule_progress_message_reading_programs">Reading programs to create recording schedules</string>
<!-- A popup message which informs that Live TV is reading program information. -->
- <string name="dvr_series_schedules_progress_message_reading_programs">Reading programs</string>
- <!-- A popup message which informs that Live TV is updating series recording. -->
- <string name="dvr_series_schedules_progress_message_updating_programs">Updating series recording</string>
- <string name="dvr_error_insufficient_space_title" translatable="false">Insufficient storage space</string>
- <string name="dvr_error_insufficient_space_description" translatable="false">No sufficient storage space for recording. Please clean up the storage.</string>
+ <string name="dvr_series_progress_message_reading_programs">Reading programs</string>
+ <!-- Dialog action which let user view the recent recordings. -->
+ <string name="dvr_error_insufficient_space_action_view_recent_recordings">View recent recordings</string>
+ <!-- Dialog title which means there is one recording doesn't complete. -->
+ <string name="dvr_error_insufficient_space_title_one_recording">The recording of <xliff:g id="programName" example="Friends">%1$s</xliff:g> is incomplete.</string>
+ <!-- Dialog title which means there are two recordings don't complete. -->
+ <string name="dvr_error_insufficient_space_title_two_recordings">The recordings of <xliff:g id="programName_1" example="Friends">%1$s</xliff:g> and <xliff:g id="programName_2" example="Friends">%2$s</xliff:g> are incomplete.</string>
+ <!-- Dialog title which means there are three or more recordings don't complete.-->
+ <string name="dvr_error_insufficient_space_title_three_or_more_recordings">The recordings of <xliff:g id="programName_1" example="Friends">%1$s</xliff:g>, <xliff:g id="programName_2" example="Friends">%2$s</xliff:g> and <xliff:g id="programName_3" example="Friends">%3$s</xliff:g> are incomplete.</string>
+ <!-- Description which means there is one recording didn't complete due to no sufficient space.
+ -->
+ <string name="dvr_error_insufficient_space_description_one_recording">The recording of <xliff:g id="programName" example="Friends">%1$s</xliff:g> didn\'t complete due to insufficient storage.</string>
+ <!-- Description which means there are two recordings didn't complete due to no sufficient
+ space. -->
+ <string name="dvr_error_insufficient_space_description_two_recordings">The recordings of <xliff:g id="programName_1" example="Friends">%1$s</xliff:g> and <xliff:g id="programName_2" example="Friends">%2$s</xliff:g> didn\'t complete due to insufficient storage.</string>
+ <!-- Description which means there are three or more recordings didn't complete due to no
+ sufficient space.-->
+ <string name="dvr_error_insufficient_space_description_three_or_more_recordings">The recordings of <xliff:g id="programName_1" example="Friends">%1$s</xliff:g>, <xliff:g id="programName_2" example="Friends">%2$s</xliff:g> and <xliff:g id="programName_3" example="Friends">%3$s</xliff:g> didn\'t complete due to insufficient storage.</string>
<!-- Dialog title which will be shown when the current storage is too small for DVR. -->
<string name="dvr_error_small_sized_storage_title">DVR needs more storage</string>
- <!-- Dialog description which will be shown when tthe current storage is too small for DVR. -->
- <string name="dvr_error_small_sized_storage_description">You will be able to record programs with DVR. However there is not enough storage on your device now for DVR to work. Please connect an external drive that is <xliff:g id="storage size" example="10GB">%1$s</xliff:g>GB or larger and follow the steps to format it as device storage.</string>
+ <!-- Dialog description which will be shown when the current storage is too small for DVR. -->
+ <string name="dvr_error_small_sized_storage_description">You will be able to record programs with DVR. However there is not enough storage on your device now for DVR to work. Please connect an external drive that is <xliff:g id="storage size" example="10GB">%1$d</xliff:g>GB or larger and follow the steps to format it as device storage.</string>
+ <!-- Dialog title which will be shown when there is no free space on the current storage for DVR. -->
+ <string name="dvr_error_no_free_space_title">Not enough storage</string>
+ <!-- Dialog description which will be shown when there is no free space on the current storage for DVR. -->
+ <string name="dvr_error_no_free_space_description">This program will not be recorded because there is not enough storage. Try deleting some existing recordings.</string>
<!-- Dialog title which will be shown when the current DVR storage is not accessible. -->
<string name="dvr_error_missing_storage_title">Missing storage</string>
<!-- Dialog description which will be shown when the current DVR storage is not accessible. -->
- <string name="dvr_error_missing_storage_description">Some of the storage used by DVR is missing. Please connect the external drive you used before to re-enable DVR. Alternately, you can choose to forget the storage if it\'s no longer available.</string>
- <!-- Dialog title which will be shown when you confirmed to forget the current DVR storage. -->
- <string name="dvr_error_forget_storage_title">Forget storage?</string>
- <!-- Dialog description which will be shown when you confirmed to forget the current DVR
- storage. -->
- <string name="dvr_error_forget_storage_description">All your recorded content and schedules will be lost.</string>
+ <string name="dvr_error_missing_storage_description" translatable="false">Some of the storage used by DVR is missing. Please connect the external drive you used before to re-enable DVR. Alternately, you can forget the storage in the storage settings, if it\'s no longer available.</string>
<!-- The recording being requested to play is not existent in storage. It may be deleted. -->
<string name="dvr_toast_recording_deleted" translatable="false">The recording seems to be deleted.</string>
@@ -847,66 +826,53 @@
<string name="dvr_already_recorded_dialog_description">This program has already been recorded. It’s available in the DVR library.</string>
<!-- The title of dialog that notifies the user the series recording has been scheduled. -->
<string name="dvr_series_recording_dialog_title">Series recording scheduled</string>
- <!-- The description of the dialog which notifies how many schedules has been added
- for series recording.-->
- <plurals name="dvr_series_recording_scheduled_no_conflict">
- <item quantity="one">%1$d recording has been scheduled for %2$s.</item>
- <item quantity="other">%1$d recordings have been scheduled for %2$s.</item>
+ <!-- The description of the dialog which notifies how many schedules have been added for the
+ series. -->
+ <plurals name="dvr_series_scheduled_no_conflict">
+ <item quantity="one"><xliff:g id="numberOfRecordings" example="1">%1$d</xliff:g> recording has been scheduled for <xliff:g id="seriesName" example="Friends">%2$s</xliff:g>.</item>
+ <item quantity="other"><xliff:g id="numberOfRecordings" example="5">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="seriesName" example="Friends">%2$s</xliff:g>.</item>
</plurals>
- <!-- The description of the dialog which notifies how many schedules has been added
- for series recording. But some of them won't be recorded due to conflicts. -->
+ <!-- The description of the dialog which notifies how many schedules have been added for the
+ series. But some episodes of this series won't be recorded due to conflict with
+ other schedules. -->
<plurals name="dvr_series_recording_scheduled_only_this_series_conflict">
- <item quantity="one">%1$d recording has been scheduled for %2$s. %3$d of them will not be recorded due to conflicts.</item>
- <item quantity="other">%1$d recordings have been scheduled for %2$s. %3$d of them will not be recorded due to conflicts.</item>
+ <item quantity="one"><xliff:g id="numberOfRecordings" example="1">%1$d</xliff:g> recording has been scheduled for <xliff:g id="seriesName" example="Friends">%2$s</xliff:g>. It will not be recorded due to conflicts.</item>
+ <item quantity="other"><xliff:g id="numberOfRecordings" example="5">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="seriesName" example="Friends">%2$s</xliff:g>. <xliff:g id="numberOfConflictRecordings" example="2">%3$d</xliff:g> of them will not be recorded due to conflicts.</item>
</plurals>
- <!-- The description of the dialog which notifies how many schedules has been added
- for series recording. But only 1 episode of other series won't be recorded due to conflict
+ <!-- The description of the dialog which notifies how many schedules have been added for the
+ series. But some episodes of this and other series won't be recorded due to the episodes
+ of this series conflict with other schedules and the episodes of other series conflict
with this series. -->
- <plurals name="dvr_series_recording_scheduled_this_and_other_series_one_conflict">
- <item quantity="one">%1$d recording has been scheduled for %2$s. 1 episode of this series and other series will not be recorded due to conflicts.</item>
- <item quantity="other">%1$d recordings have been scheduled for %2$s. 1 episode of this series and other series will not be recorded due to conflicts.</item>
+ <plurals name="dvr_series_scheduled_this_and_other_series_conflict">
+ <item quantity="one"><xliff:g id="numberOfRecordings" example="1">%1$d</xliff:g> recording has been scheduled for <xliff:g id="seriesName" example="Friends">%2$s</xliff:g>. <xliff:g id="numberOfConflictEpisodes" example="1">%3$d</xliff:g> episodes of this series and other series will not be recorded due to conflicts.</item>
+ <item quantity="other"><xliff:g id="numberOfRecordings" example="5">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="seriesName" example="Friends">%2$s</xliff:g>. <xliff:g id="numberOfConflictEpisodes" example="2">%3$d</xliff:g> episodes of this series and other series will not be recorded due to conflicts.</item>
</plurals>
- <!-- The description of the dialog which notifies how many schedules has been added
- for series recording. But some episodes of other series won't be recorded due to conflict
- with this. -->
- <plurals name="dvr_series_recording_scheduled_this_and_other_series_conflict">
- <item quantity="one">%1$d recording has been scheduled for %2$s. %3$d episodes of this series and other series will not be recorded due to conflicts.</item>
- <item quantity="other">%1$d recordings have been scheduled for %2$s. %3$d episodes of this series and other series will not be recorded due to conflicts.</item>
- </plurals>
- <!-- The description of the dialog which notifies how many schedules has been added
- for series recording. But only 1 episode of other series won't be recorded due to conflict
- with this series but no conflicts in this series. -->
- <plurals name="dvr_series_recording_scheduled_only_other_series_one_conflict">
- <item quantity="one">%1$d recording has been scheduled for %2$s. 1 episode of other series will not be recorded due to conflicts.</item>
- <item quantity="other">%1$d recordings have been scheduled for %2$s. 1 episode of other series will not be recorded due to conflicts.</item>
+ <!-- The description of the dialog which notifies how many schedules have been added for the
+ series. But only 1 episode of other series won't be recorded due to conflict
+ with this series. -->
+ <plurals name="dvr_series_scheduled_only_other_series_one_conflict">
+ <item quantity="one"><xliff:g id="numberOfRecordings" example="1">%1$d</xliff:g> recording has been scheduled for <xliff:g id="seriesName" example="Friends">%2$s</xliff:g>. 1 episode of other series will not be recorded due to conflicts.</item>
+ <item quantity="other"><xliff:g id="numberOfRecordings" example="5">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="seriesName" example="Friends">%2$s</xliff:g>. 1 episode of other series will not be recorded due to conflicts.</item>
</plurals>
- <!-- The description of the dialog which notifies how many schedules has been added
- for series recording. But some of other series won't be recorded due to conflict with this
- series but no conflicts in this series . -->
- <plurals name="dvr_series_recording_scheduled_only_other_series_conflict">
- <item quantity="one">%1$d recording has been scheduled for %2$s. %3$d episodes of other series will not be recorded due to conflicts.</item>
- <item quantity="other">%1$d recordings have been scheduled for %2$s. %3$d episodes of other series will not be recorded due to conflicts.</item>
+ <!-- The description of the dialog which notifies how many schedules have been added for the
+ series. But some episodes of other series won't be recorded due to conflict with this
+ series. -->
+ <plurals name="dvr_series_scheduled_only_other_series_many_conflicts">
+ <item quantity="one"><xliff:g id="numberOfRecordings" example="1">%1$d</xliff:g> recording has been scheduled for <xliff:g id="seriesName" example="Friends">%2$s</xliff:g>. <xliff:g id="numberOfConflictEpisodes" example="1">%3$d</xliff:g> episodes of other series will not be recorded due to conflicts.</item>
+ <item quantity="other"><xliff:g id="numberOfRecordings" example="5">%1$d</xliff:g> recordings have been scheduled for <xliff:g id="seriesName" example="Friends">%2$s</xliff:g>. <xliff:g id="numberOfConflictEpisodes" example="2">%3$d</xliff:g> episodes of other series will not be recorded due to conflicts.</item>
</plurals>
<!-- DVR playback strings -->
<eat-comment />
- <string name="dvr_now_playing_card_no_title" translatable="false">Recorded Program</string>
<!-- DVR playback activity's warning about the recorded program is not found. -->
<string name="dvr_program_not_found">Recorded program not found.</string>
<!-- Label used in DVR playback activity as the header of the row of related recordings. [CHAR LIMIT=32] -->
<string name="dvr_playback_related_recordings">Related recordings</string>
- <!-- Label used in related recording cards to indicate that the program does not have descriptions. [CHAR LIMIT=32] -->
- <string name="dvr_msg_no_program_description">(No program description)</string>
<!-- DVR channel banner strings -->
<eat-comment />
<string name="dvr_recording_till_format" translatable="false">Recording till <xliff:g id="recordingEndTime" example="9:00pm">%1$s</xliff:g></string>
- <!-- Account Selection strings -->
- <eat-comment />
- <string name="account_selected" translatable="false">%1$s is the selected account</string>
- <string name="no_account_selected" translatable="false">No account available</string>
-
<!-- DVR schedule list strings -->
<eat-comment/>
<!-- Description of list's header about how many recordings in the recording list. -->
@@ -944,6 +910,8 @@
<string name="dvr_series_schedules_stop_dialog_description">Recorded episodes will remain available in the DVR library.</string>
<!-- Action to stop creating the schedules for the series. -->
<string name="dvr_series_schedules_stop_dialog_action_stop">Stop</string>
+ <!-- Description of no episodes in stopped series recording. -->
+ <string name="dvr_series_schedules_stopped_empty_state">No episodes are on air now.</string>
<!-- Description of no episodes in series recording, and the episodes will be recorded once
they are available. -->
<string name="dvr_series_schedules_empty_state">No episodes are available.\nThey will be recorded once they are available.</string>
@@ -974,4 +942,9 @@
<eat-comment/>
<!-- Text that goes after a Critic Score to indicate that it's a score -->
<string name="program_guide_critic_score">Score</string>
+
+ <!-- Preview Channel Name -->
+ <eat-comment/>
+ <!-- Name for recorded programs preview channel -->
+ <string name="recorded_programs_preview_channel">Recorded Programs</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 3a34af52..84885f13 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -92,7 +92,7 @@
<item name="android:textSize">14sp</item>
<item name="android:textColor">@color/lb_basic_card_title_text_color</item>
<item name="android:fontFamily">sans-serif-condensed</item>
- <item name="android:singleLine">true</item>
+ <item name="android:maxLines">@integer/dvr_card_title_max_lines_folded</item>
<item name="android:ellipsize">end</item>
</style>
@@ -143,7 +143,7 @@
<item name="android:layout_height">60dp</item>
</style>
- <style name="TV.Dvr.GuidedActionsListStyle" parent="Widget.Setup.GuidedActionsListStyle">
+ <style name="TV.Dvr.GuidedActionsListStyle" parent="Widget.Leanback.GuidedActionsListStyle">
<item name="android:layout_marginTop">51dp</item>
<item name="android:layout_marginBottom">10dp</item>
<item name="android:layout_marginEnd">56dp</item>
@@ -151,11 +151,8 @@
<style name="TV.Dvr.GuidedActionItemContainerStyle" parent="Widget.Setup.GuidedActionItemContainerStyle">
<item name="android:layout_height">48dp</item>
- <item name="android:layout_marginTop">7dp</item>
- <item name="android:paddingBottom">15dp</item>
<item name="android:paddingEnd">16dp</item>
<item name="android:paddingStart">16dp</item>
- <item name="android:paddingTop">14dp</item>
</style>
<style name="TV.Dvr.GuidedActionItemContainerStyle.Twoline.Action" parent="TV.Dvr.GuidedActionItemContainerStyle">
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 9be64eb8..2165a756 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -114,5 +114,10 @@
<style name="Theme.TV.Dvr.Browse.Details" parent="Theme.Leanback.Details">
<item name="detailsDescriptionTitleStyle">@style/TV.Dvr.Browse.DetailsDescriptionTitleStyle</item>
+ <item name="android:windowSharedElementEnterTransition">@transition/dvr_details_shared_element_enter_transition</item>
+ <item name="android:windowSharedElementReturnTransition">@transition/dvr_details_shared_element_return_transition</item>
+ <!-- Disallows transition overlapping to prevent jankiness caused by ripple effects of
+ clicking DVR cards overlapping with fragment transition. -->
+ <item name="android:windowAllowEnterTransitionOverlap">false</item>
</style>
-</resources>
+</resources> \ No newline at end of file
diff --git a/res/xml/remote_config_defaults.xml b/res/xml/remote_config_defaults.xml
index 742bff21..6ecad191 100644
--- a/res/xml/remote_config_defaults.xml
+++ b/res/xml/remote_config_defaults.xml
@@ -16,7 +16,22 @@
-->
<defaultsMap>
<entry>
+ <key>live_channels_ac3_software_decoder</key>
+ <value>false</value>
+ </entry>
+
+ <entry>
<key>live_channels_epg_host_and_port</key>
<value>datamixer-pa.googleapis.com:443</value>
</entry>
+
+ <entry>
+ <key>live_channels_epg_fetcher_interval_hour</key>
+ <value>4</value>
+ </entry>
+
+ <entry>
+ <key>live_channels_epg_reader_max_channels_per_program_fetch</key>
+ <value>20</value>
+ </entry>
</defaultsMap> \ No newline at end of file
diff --git a/src/com/android/exoplayer/text/SubtitleView.java b/src/com/android/exoplayer/text/SubtitleView.java
index b1161f22..37926eda 100644
--- a/src/com/android/exoplayer/text/SubtitleView.java
+++ b/src/com/android/exoplayer/text/SubtitleView.java
@@ -39,14 +39,12 @@ import java.util.ArrayList;
/**
* Since this class does not exist in recent version of ExoPlayer and used by
- * {@link com.google.android.tv.tuner.cc.CaptionWindowLayout}, this class is copied from
+ * {@link com.android.tv.tuner.cc.CaptionWindowLayout}, this class is copied from
* older version of ExoPlayer.
* A view for rendering a single caption.
*/
@Deprecated
public class SubtitleView extends View {
- // TODO: Change usage of this class to up-to-date class of ExoPlayer.
-
/**
* Ratio of inner padding to font size.
*/
diff --git a/src/com/android/exoplayer2/ext/ffmpeg/FfmpegAudioDecoder.java b/src/com/android/exoplayer2/ext/ffmpeg/FfmpegAudioDecoder.java
new file mode 100644
index 00000000..2b7817dc
--- /dev/null
+++ b/src/com/android/exoplayer2/ext/ffmpeg/FfmpegAudioDecoder.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 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.google.android.exoplayer2.ext.ffmpeg;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
+import com.google.android.exoplayer2.decoder.SimpleOutputBuffer;
+import com.google.android.exoplayer2.util.MimeTypes;
+import com.android.tv.common.SoftPreconditions;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Audio decoder which uses ffmpeg extension of ExoPlayer2. Since {@link FfmpegDecoder} is package
+ * private, expose the decoder via this class. Supported formats are AC3 and MP2.
+ */
+public class FfmpegAudioDecoder {
+ private static final int NUM_DECODER_BUFFERS = 1;
+
+ // The largest AC3 sample size. This is bigger than the largest MP2 sample size (1729).
+ private static final int INITIAL_INPUT_BUFFER_SIZE = 2560;
+ private static boolean AVAILABLE;
+
+ static {
+ AVAILABLE =
+ FfmpegLibrary.supportsFormat(MimeTypes.AUDIO_AC3)
+ && FfmpegLibrary.supportsFormat(MimeTypes.AUDIO_MPEG_L2);
+ }
+
+ private FfmpegDecoder mDecoder;
+ private DecoderInputBuffer mInputBuffer;
+ private SimpleOutputBuffer mOutputBuffer;
+ private boolean mStarted;
+
+ /** Return whether Ffmpeg based software audio decoder is available. */
+ public static boolean isAvailable() {
+ return AVAILABLE;
+ }
+
+ /** Creates an Ffmpeg based software audio decoder. */
+ public FfmpegAudioDecoder(Context context) {
+ if (context.checkSelfPermission("android.permission.INTERNET")
+ == PackageManager.PERMISSION_GRANTED) {
+ throw new IllegalStateException("This code should run in an isolated process");
+ }
+ }
+
+ /**
+ * Decodes an audio sample.
+ *
+ * @param timeUs presentation timestamp of the sample
+ * @param sample data
+ */
+ public void decode(long timeUs, byte[] sample) {
+ SoftPreconditions.checkState(AVAILABLE);
+ mInputBuffer.data.clear();
+ mInputBuffer.data.put(sample);
+ mInputBuffer.data.flip();
+ mInputBuffer.timeUs = timeUs;
+ mDecoder.decode(mInputBuffer, mOutputBuffer, !mStarted);
+ if (!mStarted) {
+ mStarted = true;
+ }
+ }
+
+ /** Returns a decoded sample from decoder. */
+ public ByteBuffer getDecodedSample() {
+ return mOutputBuffer.data;
+ }
+
+ /** Returns the presentation time for the decoded sample. */
+ public long getDecodedTimeUs() {
+ return mOutputBuffer.timeUs;
+ }
+
+ /**
+ * Clear previous decode state if any. Prepares to decode samples of the specified encoding.
+ * This method should be called before using decode.
+ *
+ * @param mime audio encoding
+ */
+ public void resetDecoderState(String mime) {
+ SoftPreconditions.checkState(AVAILABLE);
+ release();
+ try {
+ mDecoder =
+ new FfmpegDecoder(
+ NUM_DECODER_BUFFERS,
+ NUM_DECODER_BUFFERS,
+ INITIAL_INPUT_BUFFER_SIZE,
+ mime,
+ null);
+ mStarted = false;
+ mInputBuffer = mDecoder.createInputBuffer();
+ // Since native JNI requires direct buffer, we should allocate it by #allocateDirect.
+ mInputBuffer.data = ByteBuffer.allocateDirect(INITIAL_INPUT_BUFFER_SIZE);
+ mOutputBuffer = mDecoder.createOutputBuffer();
+ } catch (FfmpegDecoderException e) {
+ // if AVAILABLE is {@code true}, this will not happen.
+ }
+ }
+
+ /** Releases all the resource. */
+ public void release() {
+ SoftPreconditions.checkState(AVAILABLE);
+ if (mDecoder != null) {
+ mDecoder.release();
+ mInputBuffer = null;
+ mOutputBuffer = null;
+ mDecoder = null;
+ }
+ }
+}
diff --git a/src/com/android/exoplayer2/ext/ffmpeg/FfmpegLibrary.java b/src/com/android/exoplayer2/ext/ffmpeg/FfmpegLibrary.java
new file mode 100644
index 00000000..daa77340
--- /dev/null
+++ b/src/com/android/exoplayer2/ext/ffmpeg/FfmpegLibrary.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 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.google.android.exoplayer2.ext.ffmpeg;
+
+import com.google.android.exoplayer2.util.LibraryLoader;
+import com.google.android.exoplayer2.util.MimeTypes;
+
+/**
+ * This class is based on com.google.android.exoplayer2.ext.ffmpeg.FfmpegLibrary from ExoPlayer2
+ * in order to support mp2 decoder.
+ * Configures and queries the underlying native library.
+ */
+public final class FfmpegLibrary {
+
+ private static final LibraryLoader LOADER =
+ new LibraryLoader("avutil", "avresample", "avcodec", "ffmpeg");
+
+ private FfmpegLibrary() {}
+
+ /**
+ * Overrides the names of the FFmpeg native libraries. If an application wishes to call this
+ * method, it must do so before calling any other method defined by this class, and before
+ * instantiating a {@link FfmpegAudioRenderer} instance.
+ */
+ public static void setLibraries(String... libraries) {
+ LOADER.setLibraries(libraries);
+ }
+
+ /**
+ * Returns whether the underlying library is available, loading it if necessary.
+ */
+ public static boolean isAvailable() {
+ return LOADER.isAvailable();
+ }
+
+ /**
+ * Returns the version of the underlying library if available, or null otherwise.
+ */
+ public static String getVersion() {
+ return isAvailable() ? ffmpegGetVersion() : null;
+ }
+
+ /**
+ * Returns whether the underlying library supports the specified MIME type.
+ */
+ public static boolean supportsFormat(String mimeType) {
+ if (!isAvailable()) {
+ return false;
+ }
+ String codecName = getCodecName(mimeType);
+ return codecName != null && ffmpegHasDecoder(codecName);
+ }
+
+ /**
+ * Returns the name of the FFmpeg decoder that could be used to decode {@code mimeType}.
+ */
+ /* package */ static String getCodecName(String mimeType) {
+ switch (mimeType) {
+ case MimeTypes.AUDIO_MPEG_L2:
+ return "mp2";
+ case MimeTypes.AUDIO_AC3:
+ return "ac3";
+ default:
+ return null;
+ }
+ }
+
+ private static native String ffmpegGetVersion();
+ private static native boolean ffmpegHasDecoder(String codecName);
+
+}
diff --git a/src/com/android/tv/ApplicationSingletons.java b/src/com/android/tv/ApplicationSingletons.java
index fd125d52..ac7d4c4a 100644
--- a/src/com/android/tv/ApplicationSingletons.java
+++ b/src/com/android/tv/ApplicationSingletons.java
@@ -20,12 +20,15 @@ import com.android.tv.analytics.Analytics;
import com.android.tv.analytics.Tracker;
import com.android.tv.config.RemoteConfig;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.DvrStorageStatusManager;
import com.android.tv.dvr.DvrWatchedPositionManager;
+import com.android.tv.dvr.recorder.RecordingScheduler;
+import com.android.tv.perf.PerformanceMonitor;
import com.android.tv.util.AccountHelper;
import com.android.tv.util.TvInputManagerHelper;
@@ -38,6 +41,22 @@ public interface ApplicationSingletons {
ChannelDataManager getChannelDataManager();
+ /**
+ * Checks if the {@link ChannelDataManager} instance has been created and all the channels has
+ * been loaded.
+ */
+ boolean isChannelDataManagerLoadFinished();
+
+ ProgramDataManager getProgramDataManager();
+
+ /**
+ * Checks if the {@link ProgramDataManager} instance has been created and the current programs
+ * for all the channels has been loaded.
+ */
+ boolean isProgramDataManagerCurrentProgramsLoadFinished();
+
+ PreviewDataManager getPreviewDataManager();
+
DvrDataManager getDvrDataManager();
DvrStorageStatusManager getDvrStorageStatusManager();
@@ -46,12 +65,12 @@ public interface ApplicationSingletons {
DvrManager getDvrManager();
+ RecordingScheduler getRecordingScheduler();
+
DvrWatchedPositionManager getDvrWatchedPositionManager();
InputSessionManager getInputSessionManager();
- ProgramDataManager getProgramDataManager();
-
Tracker getTracker();
TvInputManagerHelper getTvInputManagerHelper();
@@ -61,4 +80,8 @@ public interface ApplicationSingletons {
AccountHelper getAccountHelper();
RemoteConfig getRemoteConfig();
+
+ boolean isRunningInMainProcess();
+
+ PerformanceMonitor getPerformanceMonitor();
}
diff --git a/src/com/android/tv/AudioManagerHelper.java b/src/com/android/tv/AudioManagerHelper.java
new file mode 100644
index 00000000..4fca06ac
--- /dev/null
+++ b/src/com/android/tv/AudioManagerHelper.java
@@ -0,0 +1,108 @@
+package com.android.tv;
+
+import android.app.Activity;
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Build;
+
+import com.android.tv.receiver.AudioCapabilitiesReceiver;
+import com.android.tv.ui.TunableTvView;
+
+/**
+ * A helper class to help {@link MainActivity} to handle audio-related stuffs.
+ */
+class AudioManagerHelper implements AudioManager.OnAudioFocusChangeListener {
+ private static final float AUDIO_MAX_VOLUME = 1.0f;
+ private static final float AUDIO_MIN_VOLUME = 0.0f;
+ private static final float AUDIO_DUCKING_VOLUME = 0.3f;
+
+ private final Activity mActivity;
+ private final TunableTvView mTvView;
+ private final AudioManager mAudioManager;
+ private final AudioCapabilitiesReceiver mAudioCapabilitiesReceiver;
+
+ private boolean mAc3PassthroughSupported;
+ private int mAudioFocusStatus = AudioManager.AUDIOFOCUS_LOSS;
+
+ AudioManagerHelper(Activity activity, TunableTvView tvView) {
+ mActivity = activity;
+ mTvView = tvView;
+ mAudioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
+ mAudioCapabilitiesReceiver = new AudioCapabilitiesReceiver(activity,
+ new AudioCapabilitiesReceiver.OnAc3PassthroughCapabilityChangeListener() {
+ @Override
+ public void onAc3PassthroughCapabilityChange(boolean capability) {
+ mAc3PassthroughSupported = capability;
+ }
+ });
+ mAudioCapabilitiesReceiver.register();
+ }
+
+ /**
+ * Sets suitable volume to {@link TunableTvView} according to the current audio focus.
+ * If the focus status is {@link AudioManager#AUDIOFOCUS_LOSS} and the activity is under PIP
+ * mode, this method will finish the activity.
+ */
+ void setVolumeByAudioFocusStatus() {
+ if (mTvView.isPlaying()) {
+ switch (mAudioFocusStatus) {
+ case AudioManager.AUDIOFOCUS_GAIN:
+ mTvView.setStreamVolume(AUDIO_MAX_VOLUME);
+ break;
+ case AudioManager.AUDIOFOCUS_LOSS:
+ if (Features.PICTURE_IN_PICTURE.isEnabled(mActivity)
+ && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
+ && mActivity.isInPictureInPictureMode()) {
+ mActivity.finish();
+ break;
+ }
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+ mTvView.setStreamVolume(AUDIO_MIN_VOLUME);
+ break;
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+ mTvView.setStreamVolume(AUDIO_DUCKING_VOLUME);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Tries to request audio focus from {@link AudioManager} and set volume according to the
+ * returned result.
+ */
+ void requestAudioFocus() {
+ int result = mAudioManager.requestAudioFocus(this,
+ AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
+ mAudioFocusStatus = (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) ?
+ AudioManager.AUDIOFOCUS_GAIN : AudioManager.AUDIOFOCUS_LOSS;
+ setVolumeByAudioFocusStatus();
+ }
+
+ /**
+ * Abandons audio focus.
+ */
+ void abandonAudioFocus() {
+ mAudioFocusStatus = AudioManager.AUDIOFOCUS_LOSS;
+ mAudioManager.abandonAudioFocus(this);
+ }
+
+ /**
+ * Returns {@code true} if the device supports AC3 pass-through.
+ */
+ boolean isAc3PassthroughSupported() {
+ return mAc3PassthroughSupported;
+ }
+
+ /**
+ * Release the resources the helper class may occupied.
+ */
+ void release() {
+ mAudioCapabilitiesReceiver.unregister();
+ }
+
+ @Override
+ public void onAudioFocusChange(int focusChange) {
+ mAudioFocusStatus = focusChange;
+ setVolumeByAudioFocusStatus();
+ }
+}
diff --git a/src/com/android/tv/Features.java b/src/com/android/tv/Features.java
index 7e8e3689..2052f2e7 100644
--- a/src/com/android/tv/Features.java
+++ b/src/com/android/tv/Features.java
@@ -16,22 +16,29 @@
package com.android.tv;
-import static com.android.tv.common.feature.EngOnlyFeature.ENG_ONLY_FEATURE;
-import static com.android.tv.common.feature.FeatureUtils.AND;
-import static com.android.tv.common.feature.FeatureUtils.OFF;
-import static com.android.tv.common.feature.FeatureUtils.ON;
-import static com.android.tv.common.feature.FeatureUtils.OR;
-
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.VisibleForTesting;
-import android.support.v4.os.BuildCompat;
+import android.text.TextUtils;
+import android.util.Log;
import com.android.tv.common.feature.Feature;
import com.android.tv.common.feature.GServiceFeature;
import com.android.tv.common.feature.PropertyFeature;
+import com.android.tv.config.RemoteConfig;
+import com.android.tv.experiments.Experiments;
+import com.android.tv.util.LocationUtils;
import com.android.tv.util.PermissionUtils;
+import com.android.tv.util.Utils;
+
+import java.util.Locale;
+
+import static com.android.tv.common.feature.EngOnlyFeature.ENG_ONLY_FEATURE;
+import static com.android.tv.common.feature.FeatureUtils.AND;
+import static com.android.tv.common.feature.FeatureUtils.OFF;
+import static com.android.tv.common.feature.FeatureUtils.ON;
+import static com.android.tv.common.feature.FeatureUtils.OR;
/**
* List of {@link Feature} for the Live TV App.
@@ -39,6 +46,9 @@ import com.android.tv.util.PermissionUtils;
* <p>Remove the {@code Feature} once it is launched.
*/
public final class Features {
+ private static final String TAG = "Features";
+ private static final boolean DEBUG = false;
+
/**
* UI for opting in to analytics.
*
@@ -57,17 +67,40 @@ public final class Features {
public static final Feature EPG_SEARCH =
new PropertyFeature("feature_tv_use_epg_search", false);
- public static final Feature TUNER = new Feature() {
- @Override
- public boolean isEnabled(Context context) {
+ public static final Feature TUNER =
+ new Feature() {
+ @Override
+ public boolean isEnabled(Context context) {
- // This is special handling just for USB Tuner.
- // It does not require any N API's but relies on a improvements in N for AC3 support
- // After release, change class to this to just be {@link BuildCompat#isAtLeastN()}.
- return Build.VERSION.SDK_INT > Build.VERSION_CODES.M || BuildCompat.isAtLeastN();
- }
+ if (Utils.isDeveloper()) {
+ // we enable tuner for developers to test tuner in any platform.
+ return true;
+ }
- };
+ // This is special handling just for USB Tuner.
+ // It does not require any N API's but relies on a improvements in N for AC3 support
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
+ }
+ };
+
+ /**
+ * Use network tuner if it is available and there is no other tuner types.
+ */
+ public static final Feature NETWORK_TUNER =
+ new Feature() {
+ @Override
+ public boolean isEnabled(Context context) {
+ if (!TUNER.isEnabled(context)) {
+ return false;
+ }
+ if (Utils.isDeveloper()) {
+ // Network tuner will be enabled for developers.
+ return true;
+ }
+ return Locale.US.getCountry().equalsIgnoreCase(
+ LocationUtils.getCurrentCountry(context));
+ }
+ };
private static final String GSERVICE_KEY_UNHIDE = "live_channels_unhide";
/**
@@ -82,22 +115,75 @@ public final class Features {
}
});
- public static final Feature PICTURE_IN_PICTURE = new Feature() {
- private Boolean mEnabled;
+ public static final Feature PICTURE_IN_PICTURE =
+ new Feature() {
+ private Boolean mEnabled;
- @Override
- public boolean isEnabled(Context context) {
- if (mEnabled == null) {
- mEnabled = context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_PICTURE_IN_PICTURE);
- }
- return mEnabled;
- }
- };
+ @Override
+ public boolean isEnabled(Context context) {
+ if (mEnabled == null) {
+ mEnabled =
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
+ && context.getPackageManager()
+ .hasSystemFeature(
+ PackageManager.FEATURE_PICTURE_IN_PICTURE);
+ }
+ return mEnabled;
+ }
+ };
- /**
- * Enable a conflict dialog between currently watched channel and upcoming recording.
- */
+ /** Use AC3 software decode. */
+ public static final Feature AC3_SOFTWARE_DECODE =
+ new Feature() {
+ private final String[] SUPPORTED_REGIONS = {};
+
+ private Boolean mEnabled;
+
+ @Override
+ public boolean isEnabled(Context context) {
+ if (mEnabled == null) {
+ if (mEnabled == null) {
+ // We will not cache the result of fallback solution.
+ String country = LocationUtils.getCurrentCountry(context);
+ for (int i = 0; i < SUPPORTED_REGIONS.length; ++i) {
+ if (SUPPORTED_REGIONS[i].equalsIgnoreCase(country)) {
+ return true;
+ }
+ }
+ if (DEBUG) Log.d(TAG, "AC3 flag false after country check");
+ return false;
+ }
+ }
+ if (DEBUG) Log.d(TAG, "AC3 flag " + mEnabled);
+ return mEnabled;
+ }
+ };
+
+ /** Show postal code fragment before channel scan. */
+ public static final Feature ENABLE_CLOUD_EPG_REGION =
+ new Feature() {
+ private final String[] SUPPORTED_REGIONS = {
+ };
+
+
+ @Override
+ public boolean isEnabled(Context context) {
+ if (!Experiments.CLOUD_EPG.get()) {
+ if (DEBUG) Log.d(TAG, "Experiments.CLOUD_EPG is false");
+ return false;
+ }
+ String country = LocationUtils.getCurrentCountry(context);
+ for (int i = 0; i < SUPPORTED_REGIONS.length; i++) {
+ if (SUPPORTED_REGIONS[i].equalsIgnoreCase(country)) {
+ return true;
+ }
+ }
+ if (DEBUG) Log.d(TAG, "EPG flag false after country check");
+ return false;
+ }
+ };
+
+ /** Enable a conflict dialog between currently watched channel and upcoming recording. */
public static final Feature SHOW_UPCOMING_CONFLICT_DIALOG = OFF;
/**
@@ -105,6 +191,11 @@ public final class Features {
*/
public static final Feature USE_PARTNER_INPUT_BLACKLIST = ON;
+ /**
+ * Enable Dvb parsers and listeners.
+ */
+ public static final Feature ENABLE_FILE_DVB = OFF;
+
@VisibleForTesting
public static final Feature TEST_FEATURE = new PropertyFeature("test_feature", false);
diff --git a/src/com/android/tv/InputSessionManager.java b/src/com/android/tv/InputSessionManager.java
index e4b0f456..2978f409 100644
--- a/src/com/android/tv/InputSessionManager.java
+++ b/src/com/android/tv/InputSessionManager.java
@@ -37,7 +37,6 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
-import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.ui.TunableTvView;
import com.android.tv.ui.TunableTvView.OnTuneListener;
@@ -73,6 +72,8 @@ public class InputSessionManager {
Collections.synchronizedSet(new ArraySet<>());
private final Set<OnTvViewChannelChangeListener> mOnTvViewChannelChangeListeners =
new ArraySet<>();
+ private final Set<OnRecordingSessionChangeListener> mOnRecordingSessionChangeListeners =
+ new ArraySet<>();
public InputSessionManager(Context context) {
mContext = context.getApplicationContext();
@@ -113,6 +114,9 @@ public class InputSessionManager {
RecordingSession session = new RecordingSession(inputId, tag, callback, handler, endTimeMs);
mRecordingSessions.add(session);
if (DEBUG) Log.d(TAG, "Recording session created: " + session);
+ for (OnRecordingSessionChangeListener listener : mOnRecordingSessionChangeListeners) {
+ listener.onRecordingSessionChange(true, mRecordingSessions.size());
+ }
return session;
}
@@ -123,6 +127,9 @@ public class InputSessionManager {
mRecordingSessions.remove(session);
session.release();
if (DEBUG) Log.d(TAG, "Recording session released: " + session);
+ for (OnRecordingSessionChangeListener listener : mOnRecordingSessionChangeListeners) {
+ listener.onRecordingSessionChange(false, mRecordingSessions.size());
+ }
}
/**
@@ -148,9 +155,17 @@ public class InputSessionManager {
}
}
- /**
- * Returns the current {@link TvView} channel.
- */
+ /** Adds the {@link OnRecordingSessionChangeListener}. */
+ public void addOnRecordingSessionChangeListener(OnRecordingSessionChangeListener listener) {
+ mOnRecordingSessionChangeListeners.add(listener);
+ }
+
+ /** Removes the {@link OnRecordingSessionChangeListener}. */
+ public void removeRecordingSessionChangeListener(OnRecordingSessionChangeListener listener) {
+ mOnRecordingSessionChangeListeners.remove(listener);
+ }
+
+ /** Returns the current {@link TvView} channel. */
@MainThread
public Uri getCurrentTvViewChannelUri() {
for (TvViewSession session : mTvViewSessions) {
@@ -249,7 +264,7 @@ public class InputSessionManager {
mTvView.setCallback(new DelegateTvInputCallback(mCallback) {
@Override
public void onConnectionFailed(String inputId) {
- if (DEBUG) Log.d(TAG, "TvViewSession: commection failed");
+ if (DEBUG) Log.d(TAG, "TvViewSession: connection failed");
mTuned = false;
mNeedToBeRetuned = false;
super.onConnectionFailed(inputId);
@@ -546,4 +561,9 @@ public class InputSessionManager {
public interface OnTvViewChannelChangeListener {
void onTvViewChannelChange(@Nullable Uri channelUri);
}
+
+ /** Called when recording session is created or destroyed. */
+ public interface OnRecordingSessionChangeListener {
+ void onRecordingSessionChange(boolean create, int count);
+ }
}
diff --git a/src/com/android/tv/MainActivity.java b/src/com/android/tv/MainActivity.java
index 58850b5f..ed5f79a1 100644
--- a/src/com/android/tv/MainActivity.java
+++ b/src/com/android/tv/MainActivity.java
@@ -27,14 +27,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
import android.hardware.display.DisplayManager;
-import android.media.AudioManager;
-import android.media.MediaMetadata;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
import android.media.tv.TvContentRating;
import android.media.tv.TvContract;
import android.media.tv.TvContract.Channels;
@@ -44,7 +37,6 @@ import android.media.tv.TvInputManager.TvInputCallback;
import android.media.tv.TvTrackInfo;
import android.media.tv.TvView.OnUnhandledInputEventListener;
import android.net.Uri;
-import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -71,7 +63,6 @@ import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.Toast;
-import com.android.tv.analytics.DurationTimer;
import com.android.tv.analytics.SendChannelStatusRunnable;
import com.android.tv.analytics.SendConfigInfoRunnable;
import com.android.tv.analytics.Tracker;
@@ -91,26 +82,30 @@ import com.android.tv.data.ProgramDataManager;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.data.epg.EpgFetcher;
+import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dialog.PinDialogFragment;
+import com.android.tv.dialog.PinDialogFragment.OnPinCheckedListener;
import com.android.tv.dialog.SafeDismissDialogFragment;
-import com.android.tv.dvr.ConflictChecker;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.recorder.ConflictChecker;
import com.android.tv.dvr.ui.DvrStopRecordingFragment;
-import com.android.tv.dvr.ui.HalfSizedDialogFragment;
-import com.android.tv.experiments.Experiments;
+import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.menu.Menu;
import com.android.tv.onboarding.OnboardingActivity;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
-import com.android.tv.receiver.AudioCapabilitiesReceiver;
+import com.android.tv.perf.EventNames;
+import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.perf.StubPerformanceMonitor;
+import com.android.tv.perf.TimerEvent;
+import com.android.tv.recommendation.ChannelPreviewUpdater;
import com.android.tv.recommendation.NotificationService;
import com.android.tv.search.ProgramGuideSearchFragment;
+import com.android.tv.tuner.TunerInputController;
import com.android.tv.tuner.TunerPreferences;
import com.android.tv.tuner.setup.TunerSetupActivity;
import com.android.tv.tuner.tvinput.TunerTvInputService;
-import com.android.tv.ui.AppLayerTvView;
import com.android.tv.ui.ChannelBannerView;
import com.android.tv.ui.InputBannerView;
import com.android.tv.ui.KeypadChannelSwitchView;
@@ -128,23 +123,22 @@ import com.android.tv.ui.sidepanel.DisplayModeFragment;
import com.android.tv.ui.sidepanel.MultiAudioFragment;
import com.android.tv.ui.sidepanel.SettingsFragment;
import com.android.tv.ui.sidepanel.SideFragment;
+import com.android.tv.ui.sidepanel.parentalcontrols.ParentalControlsFragment;
import com.android.tv.util.AccountHelper;
import com.android.tv.util.CaptionSettings;
+import com.android.tv.util.Debug;
+import com.android.tv.util.DurationTimer;
import com.android.tv.util.ImageCache;
-import com.android.tv.util.ImageLoader;
import com.android.tv.util.OnboardingUtils;
import com.android.tv.util.PermissionUtils;
-import com.android.tv.util.PipInputManager;
-import com.android.tv.util.PipInputManager.PipInput;
import com.android.tv.util.RecurringRunner;
-import com.android.tv.util.SearchManagerHelper;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.SystemProperties;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.TvSettings;
-import com.android.tv.util.TvSettings.PipSound;
import com.android.tv.util.TvTrackInfoUtils;
import com.android.tv.util.Utils;
+import com.android.tv.util.ViewCache;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -159,8 +153,7 @@ import java.util.concurrent.TimeUnit;
/**
* The main activity for the Live TV app.
*/
-public class MainActivity extends Activity implements AudioManager.OnAudioFocusChangeListener,
- OnActionClickListener {
+public class MainActivity extends Activity implements OnActionClickListener, OnPinCheckedListener {
private static final String TAG = "MainActivity";
private static final boolean DEBUG = false;
@@ -175,18 +168,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private static final boolean USE_BACK_KEY_LONG_PRESS = false;
- private static final float AUDIO_MAX_VOLUME = 1.0f;
- private static final float AUDIO_MIN_VOLUME = 0.0f;
- private static final float AUDIO_DUCKING_VOLUME = 0.3f;
private static final float FRAME_RATE_FOR_FILM = 23.976f;
private static final float FRAME_RATE_EPSILON = 0.1f;
- private static final float MEDIA_SESSION_STOPPED_SPEED = 0.0f;
- private static final float MEDIA_SESSION_PLAYING_SPEED = 1.0f;
-
private static final int PERMISSIONS_REQUEST_READ_TV_LISTINGS = 1;
- private static final int PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 2;
private static final String PERMISSION_READ_TV_LISTINGS = "android.permission.READ_TV_LISTINGS";
// Tracker screen names.
@@ -211,49 +197,26 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
+ private static final IntentFilter SYSTEM_INTENT_FILTER = new IntentFilter();
+ static {
+ SYSTEM_INTENT_FILTER.addAction(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED);
+ SYSTEM_INTENT_FILTER.addAction(Intent.ACTION_SCREEN_OFF);
+ SYSTEM_INTENT_FILTER.addAction(Intent.ACTION_SCREEN_ON);
+ SYSTEM_INTENT_FILTER.addAction(Intent.ACTION_TIME_CHANGED);
+ }
+
private static final int REQUEST_CODE_START_SETUP_ACTIVITY = 1;
- private static final int REQUEST_CODE_START_SYSTEM_CAPTIONING_SETTINGS = 2;
private static final String KEY_INIT_CHANNEL_ID = "com.android.tv.init_channel_id";
- private static final String MEDIA_SESSION_TAG = "com.android.tv.mediasession";
-
// Change channels with key long press.
private static final int CHANNEL_CHANGE_NORMAL_SPEED_DURATION_MS = 3000;
private static final int CHANNEL_CHANGE_DELAY_MS_IN_MAX_SPEED = 50;
private static final int CHANNEL_CHANGE_DELAY_MS_IN_NORMAL_SPEED = 200;
private static final int CHANNEL_CHANGE_INITIAL_DELAY_MILLIS = 500;
- private static final int FIRST_STREAM_INFO_UPDATE_DELAY_MILLIS = 500;
private static final int MSG_CHANNEL_DOWN_PRESSED = 1000;
private static final int MSG_CHANNEL_UP_PRESSED = 1001;
- private static final int MSG_UPDATE_CHANNEL_BANNER_BY_INFO_UPDATE = 1002;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW, UPDATE_CHANNEL_BANNER_REASON_TUNE,
- UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST, UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO,
- UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK})
- private @interface ChannelBannerUpdateReason {}
- /**
- * Updates channel banner because the channel banner is forced to show.
- */
- private static final int UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW = 1;
- /**
- * Updates channel banner because of tuning.
- */
- private static final int UPDATE_CHANNEL_BANNER_REASON_TUNE = 2;
- /**
- * Updates channel banner because of fast tuning.
- */
- private static final int UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST = 3;
- /**
- * Updates channel banner because of info updating.
- */
- private static final int UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO = 4;
- /**
- * Updates channel banner because the current watched channel is locked or unlocked.
- */
- private static final int UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK = 5;
private static final int TVVIEW_SET_MAIN_TIMEOUT_MS = 3000;
@@ -261,12 +224,14 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
// Delay 1 second in order not to interrupt the first tune.
private static final long LAZY_INITIALIZATION_DELAY = TimeUnit.SECONDS.toMillis(1);
+ private static final int UNDEFINED_TRACK_INDEX = -1;
+ private static final long START_UP_TIMER_RESET_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(3);
+
private AccessibilityManager mAccessibilityManager;
private ChannelDataManager mChannelDataManager;
private ProgramDataManager mProgramDataManager;
private TvInputManagerHelper mTvInputManagerHelper;
private ChannelTuner mChannelTuner;
- private PipInputManager mPipInputManager;
private final TvOptionsManager mTvOptionsManager = new TvOptionsManager(this);
private TvViewUiManager mTvViewUiManager;
private TimeShiftManager mTimeShiftManager;
@@ -278,12 +243,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private View mContentView;
private TunableTvView mTvView;
- private TunableTvView mPipView;
private Bundle mTuneParams;
- private boolean mChannelBannerHiddenBySideFragment;
- // TODO: Move the scene views into TvTransitionManager or TvOverlayManager.
- private ChannelBannerView mChannelBannerView;
- private KeypadChannelSwitchView mKeypadChannelSwitchView;
@Nullable
private Uri mInitChannelUri;
@Nullable
@@ -293,20 +253,13 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private boolean mShowSelectInputView;
private TvInputInfo mInputToSetUp;
private final List<MemoryManageable> mMemoryManageables = new ArrayList<>();
- private MediaSession mMediaSession;
- private int mNowPlayingCardWidth;
- private int mNowPlayingCardHeight;
+ private MediaSessionWrapper mMediaSessionWrapper;
private final MyOnTuneListener mOnTuneListener = new MyOnTuneListener();
private String mInputIdUnderSetup;
private boolean mIsSetupActivityCalledByPopup;
- private AudioManager mAudioManager;
- private int mAudioFocusStatus;
+ private AudioManagerHelper mAudioManagerHelper;
private boolean mTunePending;
- private boolean mPipEnabled;
- private Channel mPipChannel;
- private boolean mPipSwap;
- @PipSound private int mPipSound = TvSettings.PIP_SOUND_MAIN; // Default
private boolean mDebugNonFullSizeScreen;
private boolean mActivityResumed;
private boolean mActivityStarted;
@@ -316,10 +269,10 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private boolean mBackKeyPressed;
private boolean mNeedShowBackKeyGuide;
private boolean mVisibleBehind;
- private boolean mAc3PassthroughSupported;
private boolean mShowNewSourcesFragment = true;
private String mTunerInputId;
private boolean mOtherActivityLaunched;
+ private PerformanceMonitor mPerformanceMonitor;
private boolean mIsFilmModeSet;
private float mDefaultRefreshRate;
@@ -331,11 +284,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private boolean mIsCurrentChannelUnblockedByUser;
private boolean mWasChannelUnblockedBeforeShrunkenByUser;
private Channel mChannelBeforeShrunkenTvView;
- private Channel mPipChannelBeforeShrunkenTvView;
private boolean mIsCompletingShrunkenTvView;
- // TODO: Need to consider the case that TIS explicitly request PIN code while TV view is
- // shrunken.
private TvContentRating mLastAllowedRatingForCurrentChannel;
private TvContentRating mAllowedRatingBeforeShrunken;
@@ -346,42 +296,46 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private static final int MAX_RECENT_CHANNELS = 5;
private final ArrayDeque<Long> mRecentChannels = new ArrayDeque<>(MAX_RECENT_CHANNELS);
- private AudioCapabilitiesReceiver mAudioCapabilitiesReceiver;
private RecurringRunner mSendConfigInfoRecurringRunner;
private RecurringRunner mChannelStatusRecurringRunner;
- // A caller which started this activity. (e.g. TvSearch)
- private String mSource;
-
private final Handler mHandler = new MainActivityHandler(this);
private final Set<OnActionClickListener> mOnActionClickListeners = new ArraySet<>();
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
- if (DEBUG) Log.d(TAG, "Received ACTION_SCREEN_OFF");
- // We need to stop TvView, when the screen is turned off. If not and TIS uses
- // MediaPlayer, a device may not go to the sleep mode and audio can be heard,
- // because MediaPlayer keeps playing media by its wake lock.
- mScreenOffIntentReceived = true;
- markCurrentChannelDuringScreenOff();
- stopAll(true);
- } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
- if (DEBUG) Log.d(TAG, "Received ACTION_SCREEN_ON");
- if (!mActivityResumed && mVisibleBehind) {
- // ACTION_SCREEN_ON is usually called after onResume. But, if media is played
- // under launcher with requestVisibleBehind(true), onResume will not be called.
- // In this case, we need to resume TvView and PipView explicitly.
- resumeTvIfNeeded();
- resumePipIfNeeded();
- }
- } else if (intent.getAction().equals(
- TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED)) {
- if (DEBUG) Log.d(TAG, "Received parental control settings change");
- checkChannelLockNeeded(mTvView);
- checkChannelLockNeeded(mPipView);
- applyParentalControlSettings();
+ switch (intent.getAction()) {
+ case Intent.ACTION_SCREEN_OFF:
+ if (DEBUG) Log.d(TAG, "Received ACTION_SCREEN_OFF");
+ // We need to stop TvView, when the screen is turned off. If not and TIS uses
+ // MediaPlayer, a device may not go to the sleep mode and audio can be heard,
+ // because MediaPlayer keeps playing media by its wake lock.
+ mScreenOffIntentReceived = true;
+ markCurrentChannelDuringScreenOff();
+ stopAll(true);
+ break;
+ case Intent.ACTION_SCREEN_ON:
+ if (DEBUG) Log.d(TAG, "Received ACTION_SCREEN_ON");
+ if (!mActivityResumed && mVisibleBehind) {
+ // ACTION_SCREEN_ON is usually called after onResume. But, if media is
+ // played under launcher with requestVisibleBehind(true), onResume will
+ // not be called. In this case, we need to resume TvView explicitly.
+ resumeTvIfNeeded();
+ }
+ break;
+ case TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED:
+ if (DEBUG) Log.d(TAG, "Received parental control settings change");
+ applyParentalControlSettings();
+ checkChannelLockNeeded(mTvView, null);
+ break;
+ case Intent.ACTION_TIME_CHANGED:
+ // Re-tune the current channel to prevent incorrect behavior of trick-play.
+ // See: b/37393628
+ if (mChannelTuner.getCurrentChannel() != null) {
+ tune(true);
+ }
+ break;
}
}
};
@@ -397,8 +351,9 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
Channel channel = mTvView.getCurrentChannel();
if (channel != null && channel.getId() == channelId) {
- updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO);
- updateMediaSession();
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO);
+ mMediaSessionWrapper.update(mTvView.isBlocked(), channel, program);
}
}
};
@@ -407,36 +362,39 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
new ChannelTuner.Listener() {
@Override
public void onLoadFinished() {
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
+ "MainActivity.mChannelTunerListener.onLoadFinished");
SetupUtils.getInstance(MainActivity.this).markNewChannelsBrowsable();
if (mActivityResumed) {
resumeTvIfNeeded();
- resumePipIfNeeded();
}
- mKeypadChannelSwitchView.setChannels(mChannelTuner.getBrowsableChannelList());
+ mOverlayManager.onBrowsableChannelsUpdated();
}
@Override
public void onBrowsableChannelListChanged() {
- mKeypadChannelSwitchView.setChannels(mChannelTuner.getBrowsableChannelList());
+ mOverlayManager.onBrowsableChannelsUpdated();
}
@Override
public void onCurrentChannelUnavailable(Channel channel) {
- // TODO: handle the case that a channel is suddenly removed from DB.
+ if (mChannelTuner.moveToAdjacentBrowsableChannel(true)) {
+ tune(true);
+ } else {
+ stopTv("onCurrentChannelUnavailable()", false);
+ }
}
@Override
- public void onChannelChanged(Channel previousChannel, Channel currentChannel) {
- }
+ public void onChannelChanged(Channel previousChannel, Channel currentChannel) {}
};
- private final Runnable mRestoreMainViewRunnable =
- new Runnable() {
- @Override
- public void run() {
- restoreMainTvView();
- }
- };
+ private final Runnable mRestoreMainViewRunnable = new Runnable() {
+ @Override
+ public void run() {
+ restoreMainTvView();
+ }
+ };
private ProgramGuideSearchFragment mSearchFragment;
private final TvInputCallback mTvInputCallback = new TvInputCallback() {
@@ -456,54 +414,54 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
boolean parentalControlEnabled = mTvInputManagerHelper.getParentalControlSettings()
.isParentalControlsEnabled();
mTvView.onParentalControlChanged(parentalControlEnabled);
- mPipView.onParentalControlChanged(parentalControlEnabled);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ ChannelPreviewUpdater.getInstance(this).updatePreviewDataForChannelsImmediately();
+ }
}
@Override
protected void onCreate(Bundle savedInstanceState) {
+ TimerEvent timer = StubPerformanceMonitor.startBootstrapTimer();
+ DurationTimer startUpDebugTimer = Debug.getTimer(Debug.TAG_START_UP_TIMER);
+ if (!startUpDebugTimer.isStarted()
+ || startUpDebugTimer.getDuration() > START_UP_TIMER_RESET_THRESHOLD_MS) {
+ // TvApplication can start by other reason before MainActivty is launched.
+ // In this case, we restart the timer.
+ startUpDebugTimer.start();
+ }
+ startUpDebugTimer.log("MainActivity.onCreate");
if (DEBUG) Log.d(TAG,"onCreate()");
TvApplication.setCurrentRunningProcess(this, true);
super.onCreate(savedInstanceState);
+ ApplicationSingletons applicationSingletons = TvApplication.getSingletons(this);
+ if (!applicationSingletons.getTvInputManagerHelper().hasTvInputManager()) {
+ Log.wtf(TAG, "Stopping because device does not have a TvInputManager");
+ finishAndRemoveTask();
+ return;
+ }
+ mPerformanceMonitor = applicationSingletons.getPerformanceMonitor();
- boolean isPassthroughInput = TvContract.isChannelUriForPassthroughInput(getIntent()
- .getData());
- boolean skipToShowOnboarding = Intent.ACTION_VIEW.equals(getIntent().getAction())
+ TvApplication tvApplication = (TvApplication) getApplication();
+ mChannelDataManager = tvApplication.getChannelDataManager();
+ // In API 23, TvContract.isChannelUriForPassthroughInput is hidden.
+ boolean isPassthroughInput =
+ TvContract.isChannelUriForPassthroughInput(getIntent().getData());
+ boolean tuneToPassthroughInput = Intent.ACTION_VIEW.equals(getIntent().getAction())
&& isPassthroughInput;
- if (OnboardingUtils.needToShowOnboarding(this) && !skipToShowOnboarding
+ boolean channelLoadedAndNoChannelAvailable = mChannelDataManager.isDbLoadFinished()
+ && mChannelDataManager.getChannelCount() <= 0;
+ if ((OnboardingUtils.isFirstRunWithCurrentVersion(this)
+ || channelLoadedAndNoChannelAvailable)
+ && !tuneToPassthroughInput
&& !TvCommonUtils.isRunningInTest()) {
- // TODO: The onboarding is turned off in test, because tests are broken by the
- // onboarding. We need to enable the feature for tests later.
- startActivity(OnboardingActivity.buildIntent(this, getIntent()));
- finish();
+ startOnboardingActivity();
return;
}
-
- // Check this permission for the EPG fetch.
- // TODO: check {@link shouldShowRequestPermissionRationale}.
- // While testing, no way to allow the permission when the dialog shows up. So we'd better
- // not show the dialog.
- if (!TvCommonUtils.isRunningInTest() && Utils.hasInternalTvInputs(this, true)
- && checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION)
- != PackageManager.PERMISSION_GRANTED) {
- requestPermissions(new String[] {android.Manifest.permission.ACCESS_COARSE_LOCATION},
- PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
- }
-
- DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
- Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
- Point size = new Point();
- display.getSize(size);
- int screenWidth = size.x;
- int screenHeight = size.y;
- mDefaultRefreshRate = display.getRefreshRate();
-
setContentView(R.layout.activity_tv);
- mContentView = findViewById(android.R.id.content);
+ mProgramDataManager = tvApplication.getProgramDataManager();
+ mTvInputManagerHelper = tvApplication.getTvInputManagerHelper();
mTvView = (TunableTvView) findViewById(R.id.main_tunable_tv_view);
- int shrunkenTvViewHeight = getResources().getDimensionPixelSize(
- R.dimen.shrunken_tvview_height);
- mTvView.initialize((AppLayerTvView) findViewById(R.id.main_tv_view), false, screenHeight,
- shrunkenTvViewHeight);
+ mTvView.initialize(mProgramDataManager, mTvInputManagerHelper);
mTvView.setOnUnhandledInputEventListener(new OnUnhandledInputEventListener() {
@Override
public boolean onUnhandledInputEvent(InputEvent event) {
@@ -526,7 +484,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return false;
}
});
-
long channelId = Utils.getLastWatchedChannelId(this);
String inputId = Utils.getLastWatchedTunerInputId(this);
if (!isPassthroughInput && inputId != null
@@ -534,27 +491,21 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mTvView.warmUpInput(inputId, TvContract.buildChannelUri(channelId));
}
- TvApplication tvApplication = (TvApplication) getApplication();
tvApplication.getMainActivityWrapper().onMainActivityCreated(this);
if (BuildConfig.ENG && SystemProperties.ALLOW_STRICT_MODE.getValue()) {
Toast.makeText(this, "Using Strict Mode for eng builds", Toast.LENGTH_SHORT).show();
}
mTracker = tvApplication.getTracker();
- mTvInputManagerHelper = tvApplication.getTvInputManagerHelper();
if (Features.TUNER.isEnabled(this)) {
mTvInputManagerHelper.addCallback(mTvInputCallback);
}
mTunerInputId = TunerTvInputService.getInputId(this);
- mChannelDataManager = tvApplication.getChannelDataManager();
- mProgramDataManager = tvApplication.getProgramDataManager();
mProgramDataManager.addOnCurrentProgramUpdatedListener(Channel.INVALID_ID,
mOnCurrentProgramUpdatedListener);
mProgramDataManager.setPrefetchEnabled(true);
mChannelTuner = new ChannelTuner(mChannelDataManager, mTvInputManagerHelper);
mChannelTuner.addListener(mChannelTunerListener);
mChannelTuner.start();
- mPipInputManager = new PipInputManager(this, mTvInputManagerHelper, mChannelTuner);
- mPipInputManager.start();
mMemoryManageables.add(mProgramDataManager);
mMemoryManageables.add(ImageCache.getInstance());
mMemoryManageables.add(TvContentRatingCache.getInstance());
@@ -565,28 +516,29 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
new OnCurrentProgramUpdatedListener() {
@Override
public void onCurrentProgramUpdated(long channelId, Program program) {
- updateMediaSession();
+ mMediaSessionWrapper.update(mTvView.isBlocked(), getCurrentChannel(),
+ program);
switch (mTimeShiftManager.getLastActionId()) {
case TimeShiftManager.TIME_SHIFT_ACTION_ID_REWIND:
case TimeShiftManager.TIME_SHIFT_ACTION_ID_FAST_FORWARD:
case TimeShiftManager.TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS:
case TimeShiftManager.TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT:
- updateChannelBannerAndShowIfNeeded(
- UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW);
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW);
break;
case TimeShiftManager.TIME_SHIFT_ACTION_ID_PAUSE:
case TimeShiftManager.TIME_SHIFT_ACTION_ID_PLAY:
default:
- updateChannelBannerAndShowIfNeeded(
- UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO);
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO);
break;
}
}
});
- mPipView = (TunableTvView) findViewById(R.id.pip_tunable_tv_view);
- mPipView.initialize((AppLayerTvView) findViewById(R.id.pip_tv_view), true, screenHeight,
- shrunkenTvViewHeight);
+ DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
+ Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+ mDefaultRefreshRate = display.getRefreshRate();
if (!PermissionUtils.hasAccessWatchedHistory(this)) {
WatchedHistoryManager watchedHistoryManager = new WatchedHistoryManager(
@@ -594,17 +546,15 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
watchedHistoryManager.start();
mTvView.setWatchedHistoryManager(watchedHistoryManager);
}
- mTvViewUiManager = new TvViewUiManager(this, mTvView, mPipView,
+ mTvViewUiManager = new TvViewUiManager(this, mTvView,
(FrameLayout) findViewById(android.R.id.content), mTvOptionsManager);
- mPipView.setFixedSurfaceSize(screenWidth / 2, screenHeight / 2);
- mPipView.setBlockScreenType(TunableTvView.BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW);
-
+ mContentView = findViewById(android.R.id.content);
ViewGroup sceneContainer = (ViewGroup) findViewById(R.id.scene_container);
- mChannelBannerView = (ChannelBannerView) getLayoutInflater().inflate(
+ ChannelBannerView channelBannerView = (ChannelBannerView) getLayoutInflater().inflate(
R.layout.channel_banner, sceneContainer, false);
- mKeypadChannelSwitchView = (KeypadChannelSwitchView) getLayoutInflater().inflate(
- R.layout.keypad_channel_switch, sceneContainer, false);
+ KeypadChannelSwitchView keypadChannelSwitchView = (KeypadChannelSwitchView)
+ getLayoutInflater().inflate(R.layout.keypad_channel_switch, sceneContainer, false);
InputBannerView inputBannerView = (InputBannerView) getLayoutInflater()
.inflate(R.layout.input_banner, sceneContainer, false);
SelectInputView selectInputView = (SelectInputView) getLayoutInflater()
@@ -641,26 +591,12 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
});
mSearchFragment = new ProgramGuideSearchFragment();
- mOverlayManager = new TvOverlayManager(this, mChannelTuner, mTvView,
- mKeypadChannelSwitchView, mChannelBannerView, inputBannerView,
+ mOverlayManager = new TvOverlayManager(this, mChannelTuner, mTvView, mTvOptionsManager,
+ keypadChannelSwitchView, channelBannerView, inputBannerView,
selectInputView, sceneContainer, mSearchFragment);
- mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- mAudioFocusStatus = AudioManager.AUDIOFOCUS_LOSS;
-
- mMediaSession = new MediaSession(this, MEDIA_SESSION_TAG);
- mMediaSession.setCallback(new MediaSession.Callback() {
- @Override
- public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
- // Consume the media button event here. Should not send it to other apps.
- return true;
- }
- });
- mMediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
- MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
- mNowPlayingCardWidth = getResources().getDimensionPixelSize(
- R.dimen.notif_card_img_max_width);
- mNowPlayingCardHeight = getResources().getDimensionPixelSize(R.dimen.notif_card_img_height);
+ mAudioManagerHelper = new AudioManagerHelper(this, mTvView);
+ mMediaSessionWrapper = new MediaSessionWrapper(this);
mTvViewUiManager.restoreDisplayMode(false);
if (!handleIntent(getIntent())) {
@@ -668,15 +604,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return;
}
- mAudioCapabilitiesReceiver = new AudioCapabilitiesReceiver(this,
- new AudioCapabilitiesReceiver.OnAc3PassthroughCapabilityChangeListener() {
- @Override
- public void onAc3PassthroughCapabilityChange(boolean capability) {
- mAc3PassthroughSupported = capability;
- }
- });
- mAudioCapabilitiesReceiver.register();
-
mAccessibilityManager =
(AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
mSendConfigInfoRecurringRunner = new RecurringRunner(this, TimeUnit.DAYS.toMillis(1),
@@ -692,6 +619,13 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mDvrConflictChecker = new ConflictChecker(this);
}
initForTest();
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity.onCreate end");
+ mPerformanceMonitor.stopTimer(timer, EventNames.MAIN_ACTIVITY_ONCREATE);
+ }
+
+ private void startOnboardingActivity() {
+ startActivity(OnboardingActivity.buildIntent(this, getIntent()));
+ finish();
}
@Override
@@ -705,32 +639,21 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
- switch (requestCode) {
- case PERMISSIONS_REQUEST_READ_TV_LISTINGS:
- if (grantResults.length > 0
- && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- // Start reload of dependent data
- mChannelDataManager.reload();
- mProgramDataManager.reload();
-
- // Restart live channels.
- Intent intent = getIntent();
- finish();
- startActivity(intent);
- } else {
- Toast.makeText(this, R.string.msg_read_tv_listing_permission_denied,
- Toast.LENGTH_LONG).show();
- finish();
- }
- break;
- case PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION:
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
- && Experiments.CLOUD_EPG.get()) {
- EpgFetcher.getInstance(this).startImmediately();
- } else {
- EpgFetcher.getInstance(this).stop();
- }
- break;
+ if (requestCode == PERMISSIONS_REQUEST_READ_TV_LISTINGS) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ // Start reload of dependent data
+ mChannelDataManager.reload();
+ mProgramDataManager.reload();
+
+ // Restart live channels.
+ Intent intent = getIntent();
+ finish();
+ startActivity(intent);
+ } else {
+ Toast.makeText(this, R.string.msg_read_tv_listing_permission_denied,
+ Toast.LENGTH_LONG).show();
+ finish();
+ }
}
}
@@ -781,6 +704,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
@Override
protected void onStart() {
+ TimerEvent timer = mPerformanceMonitor.startTimer();
if (DEBUG) Log.d(TAG,"onStart()");
super.onStart();
mScreenOffIntentReceived = false;
@@ -789,23 +713,25 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mMainDurationTimer.start();
applyParentalControlSettings();
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED);
- intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
- intentFilter.addAction(Intent.ACTION_SCREEN_ON);
- registerReceiver(mBroadcastReceiver, intentFilter);
+ registerReceiver(mBroadcastReceiver, SYSTEM_INTENT_FILTER);
- Intent notificationIntent = new Intent(this, NotificationService.class);
- notificationIntent.setAction(NotificationService.ACTION_SHOW_RECOMMENDATION);
- startService(notificationIntent);
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+ Intent notificationIntent = new Intent(this, NotificationService.class);
+ notificationIntent.setAction(NotificationService.ACTION_SHOW_RECOMMENDATION);
+ startService(notificationIntent);
+ }
+ TunerInputController.executeNetworkTunerDiscoveryAsyncTask(this);
+
+ EpgFetcher.getInstance(this).fetchImmediatelyIfNeeded();
+ mPerformanceMonitor.stopTimer(timer, EventNames.MAIN_ACTIVITY_ONSTART);
}
@Override
protected void onResume() {
+ TimerEvent timer = mPerformanceMonitor.startTimer();
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity.onResume start");
if (DEBUG) Log.d(TAG, "onResume()");
super.onResume();
- // Refresh the remote config, it is throttled automatically.
- TvApplication.getSingletons(this).getRemoteConfig().fetch(null);
if (!PermissionUtils.hasAccessAllEpg(this)
&& checkSelfPermission(PERMISSION_READ_TV_LISTINGS)
!= PackageManager.PERMISSION_GRANTED) {
@@ -819,23 +745,23 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mActivityResumed = true;
mShowNewSourcesFragment = true;
mOtherActivityLaunched = false;
- int result = mAudioManager.requestAudioFocus(MainActivity.this,
- AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
- mAudioFocusStatus = (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) ?
- AudioManager.AUDIOFOCUS_GAIN : AudioManager.AUDIOFOCUS_LOSS;
- setVolumeByAudioFocusStatus();
+ mAudioManagerHelper.requestAudioFocus();
if (mTvView.isPlaying()) {
// Every time onResume() is called the activity will be assumed to not have requested
// visible behind.
requestVisibleBehind(true);
}
- if (Utils.hasRecordingFailedReason(getApplicationContext(),
- TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE)) {
+ Set<String> failedScheduledRecordingInfoSet =
+ Utils.getFailedScheduledRecordingInfoSet(getApplicationContext());
+ if (Utils.hasRecordingFailedReason(
+ getApplicationContext(), TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE)
+ && !failedScheduledRecordingInfoSet.isEmpty()) {
runAfterAttachedToWindow(new Runnable() {
@Override
public void run() {
- DvrUiHelper.showDvrInsufficientSpaceErrorDialog(MainActivity.this);
+ DvrUiHelper.showDvrInsufficientSpaceErrorDialog(MainActivity.this,
+ failedScheduledRecordingInfoSet);
}
});
}
@@ -843,13 +769,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (mChannelTuner.areAllChannelsLoaded()) {
SetupUtils.getInstance(this).markNewChannelsBrowsable();
resumeTvIfNeeded();
- resumePipIfNeeded();
}
mOverlayManager.showMenuWithTimeShiftPauseIfNeeded();
- // Note: The following codes are related to pop up an overlay UI after resume.
- // When the following code is changed, please check the variable
- // willShowOverlayUiAfterResume in updateChannelBannerAndShowIfNeeded.
+ // NOTE: The following codes are related to pop up an overlay UI after resume. When
+ // the following code is changed, please modify willShowOverlayUiWhenResume() accordingly.
if (mInputToSetUp != null) {
startSetupActivity(mInputToSetUp, false);
mInputToSetUp = null;
@@ -881,6 +805,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (mDvrConflictChecker != null) {
mDvrConflictChecker.start();
}
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity.onResume end");
+ mPerformanceMonitor.stopTimer(timer, EventNames.MAIN_ACTIVITY_ONRESUME);
}
@Override
@@ -893,18 +819,12 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mActivityResumed = false;
mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_DEFAULT);
mTvView.setBlockScreenType(TunableTvView.BLOCK_SCREEN_TYPE_NO_UI);
- if (mPipEnabled) {
- mTvViewUiManager.hidePipForPause();
- }
mBackKeyPressed = false;
mShowLockedChannelsTemporarily = false;
mShouldTuneToTunerChannel = false;
if (!mVisibleBehind) {
- mAudioFocusStatus = AudioManager.AUDIOFOCUS_LOSS;
- mAudioManager.abandonAudioFocus(this);
- if (mMediaSession.isActive()) {
- mMediaSession.setActive(false);
- }
+ mAudioManagerHelper.abandonAudioFocus();
+ mMediaSessionWrapper.setPlaybackState(false);
mTracker.sendScreenView("");
} else {
mTracker.sendScreenView(SCREEN_BEHIND_NAME);
@@ -933,6 +853,32 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return state;
}
+ @Override
+ public void onPinChecked(boolean checked, int type, String rating) {
+ if (checked) {
+ switch (type) {
+ case PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_CHANNEL:
+ blockOrUnblockScreen(mTvView, false);
+ mIsCurrentChannelUnblockedByUser = true;
+ break;
+ case PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_PROGRAM:
+ TvContentRating unblockedRating = TvContentRating.unflattenFromString(rating);
+ mLastAllowedRatingForCurrentChannel = unblockedRating;
+ mTvView.unblockContent(unblockedRating);
+ break;
+ case PinDialogFragment.PIN_DIALOG_TYPE_ENTER_PIN:
+ mOverlayManager.getSideFragmentManager()
+ .show(new ParentalControlsFragment(), false);
+ // Pass through.
+ case PinDialogFragment.PIN_DIALOG_TYPE_NEW_PIN:
+ mOverlayManager.getSideFragmentManager().showSidePanel(true);
+ break;
+ }
+ } else if (type == PinDialogFragment.PIN_DIALOG_TYPE_ENTER_PIN) {
+ mOverlayManager.getSideFragmentManager().hideAll(false);
+ }
+ }
+
private void resumeTvIfNeeded() {
if (DEBUG) Log.d(TAG, "resumeTvIfNeeded()");
if (!mTvView.isPlaying() || mInitChannelUri != null
@@ -962,21 +908,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mTvView.setBlockScreenType(getDesiredBlockScreenType());
}
- private void resumePipIfNeeded() {
- if (mPipEnabled && !(mPipView.isPlaying() && mPipView.isShown())) {
- if (mPipInputManager.areInSamePipInput(
- mChannelTuner.getCurrentChannel(), mPipChannel)) {
- enablePipView(false, false);
- } else {
- if (!mPipView.isPlaying()) {
- startPip(false);
- } else {
- mTvViewUiManager.showPipForResume();
- }
- }
- }
- }
-
private void startTv(Uri channelUri) {
if (DEBUG) Log.d(TAG, "startTv Uri=" + channelUri);
if ((channelUri == null || !TvContract.isChannelUriForPassthroughInput(channelUri))
@@ -993,7 +924,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
// TV has already started.
if (channelUri == null || channelUri.equals(mChannelTuner.getCurrentChannelUri())) {
// Simply adjust the volume without tune.
- setVolumeByAudioFocusStatus();
+ mAudioManagerHelper.setVolumeByAudioFocusStatus();
return;
}
stopTv();
@@ -1027,9 +958,9 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
}
- mTvView.start(mTvInputManagerHelper);
- setVolumeByAudioFocusStatus();
- tune();
+ mTvView.start();
+ mAudioManagerHelper.setVolumeByAudioFocusStatus();
+ tune(true);
}
@Override
@@ -1072,7 +1003,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private void stopAll(boolean keepVisibleBehind) {
mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION);
stopTv("stopAll()", keepVisibleBehind);
- stopPip();
}
public TvInputManagerHelper getTvInputManagerHelper() {
@@ -1127,10 +1057,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
public void startSystemCaptioningSettingsActivity() {
Intent intent = new Intent(Settings.ACTION_CAPTIONING_SETTINGS);
- mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_WITHOUT_ANIMATION
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANEL_HISTORY);
try {
- startActivityForResultSafe(intent, REQUEST_CODE_START_SYSTEM_CAPTIONING_SETTINGS);
+ startActivitySafe(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, getString(R.string.msg_unable_to_start_system_captioning_settings),
Toast.LENGTH_SHORT).show();
@@ -1145,10 +1073,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return mProgramDataManager;
}
- public PipInputManager getPipInputManager() {
- return mPipInputManager;
- }
-
public TvOptionsManager getTvOptionsManager() {
return mTvOptionsManager;
}
@@ -1185,13 +1109,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
/**
- * Returns true if the current connected TV supports AC3 passthough.
- */
- public boolean isAc3PassthroughSupported() {
- return mAc3PassthroughSupported;
- }
-
- /**
* Returns the current program which the user is watching right now.<p>
*
* It might be a live program. If the time shifting is available, it can be a past program, too.
@@ -1218,8 +1135,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
private Channel getBrowsableChannel() {
- // TODO: mChannelMap could be dirty for a while when the browsablity of channels
- // are changed. In that case, we shouldn't use the value from mChannelMap.
Channel curChannel = mChannelTuner.getCurrentChannel();
if (curChannel != null && curChannel.isBrowsable()) {
return curChannel;
@@ -1254,9 +1169,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
// Show ChannelSourcesFragment only if all the channels are loaded.
return;
}
- Channel currentChannel = mChannelTuner.getCurrentChannel();
- long channelId = currentChannel == null ? Channel.INVALID_ID : currentChannel.getId();
- mOverlayManager.getSideFragmentManager().show(new SettingsFragment(channelId));
+ mOverlayManager.getSideFragmentManager().show(new SettingsFragment());
}
public void showMerchantCollection() {
@@ -1272,19 +1185,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mChannelBeforeShrunkenTvView = mTvView.getCurrentChannel();
mWasChannelUnblockedBeforeShrunkenByUser = mIsCurrentChannelUnblockedByUser;
mAllowedRatingBeforeShrunken = mLastAllowedRatingForCurrentChannel;
-
- if (willMainViewBeTunerInput && mChannelTuner.isCurrentChannelPassthrough()
- && mPipEnabled) {
- mPipChannelBeforeShrunkenTvView = mPipChannel;
- enablePipView(false, false);
- } else {
- mPipChannelBeforeShrunkenTvView = null;
- }
mTvViewUiManager.startShrunkenTvView();
if (showLockedChannelsTemporarily) {
mShowLockedChannelsTemporarily = true;
- checkChannelLockNeeded(mTvView);
+ checkChannelLockNeeded(mTvView, null);
}
mTvView.setBlockScreenType(getDesiredBlockScreenType());
@@ -1320,23 +1225,15 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mIsCompletingShrunkenTvView = false;
mIsCurrentChannelUnblockedByUser = mWasChannelUnblockedBeforeShrunkenByUser;
mTvView.setBlockScreenType(getDesiredBlockScreenType());
- if (mPipChannelBeforeShrunkenTvView != null) {
- enablePipView(true, false);
- mPipChannelBeforeShrunkenTvView = null;
- }
}
};
mTvViewUiManager.fadeOutTvView(tuneAction);
// Will automatically fade-in when video becomes available.
} else {
- checkChannelLockNeeded(mTvView);
+ checkChannelLockNeeded(mTvView, null);
mIsCompletingShrunkenTvView = false;
mIsCurrentChannelUnblockedByUser = mWasChannelUnblockedBeforeShrunkenByUser;
mTvView.setBlockScreenType(getDesiredBlockScreenType());
- if (mPipChannelBeforeShrunkenTvView != null) {
- enablePipView(true, false);
- mPipChannelBeforeShrunkenTvView = null;
- }
}
}
@@ -1344,37 +1241,41 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return mTvViewUiManager.isUnderShrunkenTvView() || mIsCompletingShrunkenTvView;
}
+ /**
+ * Returns {@code true} if the tunable tv view is blocked by resource conflict or by parental
+ * control, otherwise {@code false}.
+ */
+ public boolean isScreenBlockedByResourceConflictOrParentalControl() {
+ return mTvView.getVideoUnavailableReason()
+ == TunableTvView.VIDEO_UNAVAILABLE_REASON_NO_RESOURCE || mTvView.isBlocked();
+ }
+
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case REQUEST_CODE_START_SETUP_ACTIVITY:
- if (resultCode == RESULT_OK) {
- int count = mChannelDataManager.getChannelCountForInput(mInputIdUnderSetup);
- String text;
- if (count > 0) {
- text = getResources().getQuantityString(R.plurals.msg_channel_added,
- count, count);
- } else {
- text = getString(R.string.msg_no_channel_added);
- }
- Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
- mInputIdUnderSetup = null;
- if (mChannelTuner.getCurrentChannel() == null) {
- mChannelTuner.moveToAdjacentBrowsableChannel(true);
- }
- if (mTunePending) {
- tune();
- }
+ if (requestCode == REQUEST_CODE_START_SETUP_ACTIVITY) {
+ if (resultCode == RESULT_OK) {
+ int count = mChannelDataManager.getChannelCountForInput(mInputIdUnderSetup);
+ String text;
+ if (count > 0) {
+ text = getResources().getQuantityString(R.plurals.msg_channel_added,
+ count, count);
} else {
- mInputIdUnderSetup = null;
+ text = getString(R.string.msg_no_channel_added);
}
- if (!mIsSetupActivityCalledByPopup) {
- mOverlayManager.getSideFragmentManager().showSidePanel(false);
+ Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT).show();
+ mInputIdUnderSetup = null;
+ if (mChannelTuner.getCurrentChannel() == null) {
+ mChannelTuner.moveToAdjacentBrowsableChannel(true);
}
- break;
- case REQUEST_CODE_START_SYSTEM_CAPTIONING_SETTINGS:
+ if (mTunePending) {
+ tune(true);
+ }
+ } else {
+ mInputIdUnderSetup = null;
+ }
+ if (!mIsSetupActivityCalledByPopup) {
mOverlayManager.getSideFragmentManager().showSidePanel(false);
- break;
+ }
}
if (data != null) {
String errorMessage = data.getStringExtra(LauncherActivity.ERROR_MESSAGE);
@@ -1418,18 +1319,12 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
// while gamepads support DPAD_CENTER and BACK by fallback.
// Since we don't expect that TIS want to handle gamepad buttons now,
// blacklist gamepad buttons and wait for next fallback keys.
- // TODO) Need to consider other fallback keys (e.g. ESCAPE)
+ // TODO: Need to consider other fallback keys (e.g. ESCAPE)
return super.dispatchKeyEvent(event);
}
return dispatchKeyEventToSession(event) || super.dispatchKeyEvent(event);
}
- @Override
- public void onAudioFocusChange(int focusChange) {
- mAudioFocusStatus = focusChange;
- setVolumeByAudioFocusStatus();
- }
-
/**
* Notifies the key input focus is changed to the TV view.
*/
@@ -1449,18 +1344,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (!mTvView.isPlaying()) {
mCaptionSettings = new CaptionSettings(this);
}
-
- // Handle the passed key press, if any. Note that only the key codes that are currently
- // handled in the TV app will be handled via Intent.
- // TODO: Consider defining a separate intent filter as passing data of mime type
- // vnd.android.cursor.item/channel isn't really necessary here.
- int keyCode = intent.getIntExtra(Utils.EXTRA_KEY_KEYCODE, KeyEvent.KEYCODE_UNKNOWN);
- if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
- if (DEBUG) Log.d(TAG, "Got an intent with keycode: " + keyCode);
- KeyEvent event = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
- onKeyUp(keyCode, event);
- return true;
- }
mShouldTuneToTunerChannel = intent.getBooleanExtra(Utils.EXTRA_KEY_FROM_LAUNCHER, false);
mInitChannelUri = null;
@@ -1476,9 +1359,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
}
- // TODO: remove the checkState once N API is finalized.
- SoftPreconditions.checkState(TvInputManager.ACTION_SETUP_INPUTS.equals(
- "android.media.tv.action.SETUP_INPUTS"));
if (TvInputManager.ACTION_SETUP_INPUTS.equals(intent.getAction())) {
runAfterAttachedToWindow(new Runnable() {
@Override
@@ -1488,17 +1368,12 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
});
} else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Uri uri = intent.getData();
- try {
- mSource = uri.getQueryParameter(Utils.PARAM_SOURCE);
- } catch (UnsupportedOperationException e) {
- // ignore this exception.
- }
- // When the URI points to the programs (directory, not an individual item), go to the
- // program guide. The intention here is to respond to
- // "content://android.media.tv/program", not "content://android.media.tv/program/XXX".
- // Later, we might want to add handling of individual programs too.
if (Utils.isProgramsUri(uri)) {
- // The given data is a programs URI. Open the Program Guide.
+ // When the URI points to the programs (directory, not an individual item), go to
+ // the program guide. The intention here is to respond to
+ // "content://android.media.tv/program", not
+ // "content://android.media.tv/program/XXX".
+ // Later, we might want to add handling of individual programs too.
mShowProgramGuide = true;
return true;
}
@@ -1541,17 +1416,19 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
} else if (mInitChannelUri != null) {
// Handle the URI built by TvContract.buildChannelsUriForInput().
- // TODO: Change hard-coded "input" to TvContract.PARAM_INPUT.
String inputId = mInitChannelUri.getQueryParameter("input");
long channelId = Utils.getLastWatchedChannelIdForInput(this, inputId);
if (channelId == Channel.INVALID_ID) {
String[] projection = { Channels._ID };
+ long time = System.currentTimeMillis();
try (Cursor cursor = getContentResolver().query(uri, projection,
null, null, null)) {
if (cursor != null && cursor.moveToNext()) {
channelId = cursor.getLong(0);
}
}
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity queries DB for "
+ + "last channel check (" + (System.currentTimeMillis() - time) + "ms)");
}
if (channelId == Channel.INVALID_ID) {
// Couldn't find any channel probably because the input hasn't been set up.
@@ -1567,41 +1444,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return true;
}
- private void setVolumeByAudioFocusStatus() {
- if (mPipSound == TvSettings.PIP_SOUND_MAIN) {
- setVolumeByAudioFocusStatus(mTvView);
- } else { // mPipSound == TvSettings.PIP_SOUND_PIP_WINDOW
- setVolumeByAudioFocusStatus(mPipView);
- }
- }
-
- private void setVolumeByAudioFocusStatus(TunableTvView tvView) {
- SoftPreconditions.checkState(tvView == mTvView || tvView == mPipView);
- if (tvView.isPlaying()) {
- switch (mAudioFocusStatus) {
- case AudioManager.AUDIOFOCUS_GAIN:
- tvView.setStreamVolume(AUDIO_MAX_VOLUME);
- break;
- case AudioManager.AUDIOFOCUS_LOSS:
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
- tvView.setStreamVolume(AUDIO_MIN_VOLUME);
- break;
- case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
- tvView.setStreamVolume(AUDIO_DUCKING_VOLUME);
- break;
- }
- }
- if (tvView == mTvView) {
- if (mPipView != null && mPipView.isPlaying()) {
- mPipView.setStreamVolume(AUDIO_MIN_VOLUME);
- }
- } else { // tvView == mPipView
- if (mTvView != null && mTvView.isPlaying()) {
- mTvView.setStreamVolume(AUDIO_MIN_VOLUME);
- }
- }
- }
-
private void stopTv() {
stopTv(null, false);
}
@@ -1617,10 +1459,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (!keepVisibleBehind) {
requestVisibleBehind(false);
}
- mAudioManager.abandonAudioFocus(this);
- if (mMediaSession.isActive()) {
- mMediaSession.setActive(false);
- }
+ mAudioManagerHelper.abandonAudioFocus();
+ mMediaSessionWrapper.setPlaybackState(false);
}
TvApplication.getSingletons(this).getMainActivityWrapper()
.notifyCurrentChannelChange(this, null);
@@ -1628,99 +1468,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mTunePending = false;
}
- private boolean isPlaying() {
- return mTvView.isPlaying() && mTvView.getCurrentChannel() != null;
- }
-
- private void startPip(final boolean fromUserInteraction) {
- if (mPipChannel == null) {
- Log.w(TAG, "PIP channel id is an invalid id.");
- return;
- }
- if (DEBUG) Log.d(TAG, "startPip() " + mPipChannel);
- mPipView.start(mTvInputManagerHelper);
- boolean success = mPipView.tuneTo(mPipChannel, null, new OnTuneListener() {
- @Override
- public void onUnexpectedStop(Channel channel) {
- Log.w(TAG, "The PIP is Unexpectedly stopped");
- enablePipView(false, false);
- }
-
- @Override
- public void onTuneFailed(Channel channel) {
- Log.w(TAG, "Fail to start the PIP during channel tuning");
- if (fromUserInteraction) {
- Toast.makeText(MainActivity.this, R.string.msg_no_pip_support,
- Toast.LENGTH_SHORT).show();
- enablePipView(false, false);
- }
- }
-
- @Override
- public void onStreamInfoChanged(StreamInfo info) {
- mTvViewUiManager.updatePipView();
- mHandler.removeCallbacks(mRestoreMainViewRunnable);
- restoreMainTvView();
- }
-
- @Override
- public void onChannelRetuned(Uri channel) {
- if (channel == null) {
- return;
- }
- Channel currentChannel =
- mChannelDataManager.getChannel(ContentUris.parseId(channel));
- if (currentChannel == null) {
- Log.e(TAG, "onChannelRetuned is called from PIP input but can't find a channel"
- + " with the URI " + channel);
- return;
- }
- if (isChannelChangeKeyDownReceived()) {
- // Ignore this message if the user is changing the channel.
- return;
- }
- mPipChannel = currentChannel;
- mPipView.setCurrentChannel(mPipChannel);
- }
-
- @Override
- public void onContentBlocked() {
- updateMediaSession();
- }
-
- @Override
- public void onContentAllowed() {
- updateMediaSession();
- }
- });
- if (!success) {
- Log.w(TAG, "Fail to start the PIP");
- return;
- }
- if (fromUserInteraction) {
- checkChannelLockNeeded(mPipView);
- }
- // Explicitly make the PIP view main to make the selected input an HDMI-CEC active source.
- mPipView.setMain();
- scheduleRestoreMainTvView();
- mTvViewUiManager.onPipStart();
- setVolumeByAudioFocusStatus();
- }
-
private void scheduleRestoreMainTvView() {
mHandler.removeCallbacks(mRestoreMainViewRunnable);
mHandler.postDelayed(mRestoreMainViewRunnable, TVVIEW_SET_MAIN_TIMEOUT_MS);
}
- private void stopPip() {
- if (DEBUG) Log.d(TAG, "stopPip");
- if (mPipView.isPlaying()) {
- mPipView.stop();
- mPipSwap = false;
- mTvViewUiManager.onPipStop();
- }
- }
-
/**
* Says {@code text} when accessibility is turned on.
*/
@@ -1735,7 +1487,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
}
- private void tune() {
+ private void tune(boolean updateChannelBanner) {
if (DEBUG) Log.d(TAG, "tune()");
mTuneDurationTimer.start();
@@ -1748,6 +1500,10 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
mTunePending = false;
final Channel channel = mChannelTuner.getCurrentChannel();
+ SoftPreconditions.checkState(channel != null);
+ if (channel == null) {
+ return;
+ }
if (!mChannelTuner.isCurrentChannelPassthrough()) {
if (mTvInputManagerHelper.getTunerTvInputSize() == 0) {
Toast.makeText(this, R.string.msg_no_input, Toast.LENGTH_SHORT).show();
@@ -1763,23 +1519,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
if (mChannelDataManager.getChannelCount() > 0) {
mOverlayManager.showIntroDialog();
+ } else {
+ startOnboardingActivity();
+ return;
}
}
- if (!TvCommonUtils.isRunningInTest() && mShowNewSourcesFragment
- && setupUtils.hasUnrecognizedInput(mTvInputManagerHelper)) {
- // Show new channel sources fragment.
- runAfterAttachedToWindow(new Runnable() {
- @Override
- public void run() {
- mOverlayManager.runAfterOverlaysAreClosed(new Runnable() {
- @Override
- public void run() {
- mOverlayManager.showNewSourcesFragment();
- }
- });
- }
- });
- }
mShowNewSourcesFragment = false;
if (mChannelTuner.getBrowsableChannelCount() == 0
&& mChannelDataManager.getChannelCount() > 0
@@ -1791,24 +1535,24 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mOverlayManager.getSideFragmentManager().show(
new CustomizeChannelListFragment());
} else {
- showSettingsFragment();
+ mOverlayManager.showSetupFragment();
}
return;
}
- // TODO: need to refactor the following code to put in startTv.
- if (channel == null) {
- // There is no channel to tune to.
- stopTv("tune()", false);
- if (!mChannelDataManager.isDbLoadFinished()) {
- // Wait until channel data is loaded in order to know the number of channels.
- // tune() will be retried, once the channel data is loaded.
- return;
- }
- if (mOverlayManager.getSideFragmentManager().isActive()) {
- return;
- }
- mOverlayManager.showSetupFragment();
- return;
+ if (!TvCommonUtils.isRunningInTest() && mShowNewSourcesFragment
+ && setupUtils.hasUnrecognizedInput(mTvInputManagerHelper)) {
+ // Show new channel sources fragment.
+ runAfterAttachedToWindow(new Runnable() {
+ @Override
+ public void run() {
+ mOverlayManager.runAfterOverlaysAreClosed(new Runnable() {
+ @Override
+ public void run() {
+ mOverlayManager.showNewSourcesFragment();
+ }
+ });
+ }
+ });
}
setupUtils.onTuned();
if (mTuneParams != null) {
@@ -1825,7 +1569,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (!isUnderShrunkenTvView()) {
mLastAllowedRatingForCurrentChannel = null;
}
- mHandler.removeMessages(MSG_UPDATE_CHANNEL_BANNER_BY_INFO_UPDATE);
// For every tune, we need to inform the tuned channel or input to a user,
// if Talkback is turned on.
sendAccessibilityText(!mChannelTuner.isCurrentChannelPassthrough() ?
@@ -1852,15 +1595,21 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
TvApplication.getSingletons(this).getMainActivityWrapper()
.notifyCurrentChannelChange(this, channel);
}
- checkChannelLockNeeded(mTvView);
- updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_TUNE);
+ // We have to provide channel here instead of using TvView's channel, because TvView's
+ // channel might be null when there's tuner conflict. In that case, TvView will resets
+ // its current channel onConnectionFailed().
+ checkChannelLockNeeded(mTvView, channel);
+ if (updateChannelBanner) {
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_TUNE);
+ }
if (mActivityResumed) {
// requestVisibleBehind should be called after onResume() is called. But, when
// launcher is over the TV app and the screen is turned off and on, tune() can
// be called during the pause state by mBroadcastReceiver (Intent.ACTION_SCREEN_ON).
requestVisibleBehind(true);
}
- updateMediaSession();
+ mMediaSessionWrapper.update(mTvView.isBlocked(), getCurrentChannel(), getCurrentProgram());
}
// Runs the runnable after the activity is attached to window to show the fragment transition
@@ -1895,136 +1644,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
}
- private void updateMediaSession() {
- if (getCurrentChannel() == null) {
- mMediaSession.setActive(false);
- return;
- }
-
- // If the channel is blocked, display a lock and a short text on the Now Playing Card
- if (mTvView.isScreenBlocked() || mTvView.getBlockedContentRating() != null) {
- setMediaSessionPlaybackState(false);
-
- Bitmap art = BitmapFactory.decodeResource(
- getResources(), R.drawable.ic_message_lock_preview);
- updateMediaMetadata(
- getResources().getString(R.string.channel_banner_locked_channel_title), art);
- mMediaSession.setActive(true);
- return;
- }
-
- final Program currentProgram = getCurrentProgram();
- String cardTitleText = null;
- String posterArtUri = null;
- if (currentProgram != null) {
- cardTitleText = currentProgram.getTitle();
- posterArtUri = currentProgram.getPosterArtUri();
- }
- if (TextUtils.isEmpty(cardTitleText)) {
- cardTitleText = getCurrentChannelName();
- }
- updateMediaMetadata(cardTitleText, null);
- setMediaSessionPlaybackState(true);
-
- if (posterArtUri == null) {
- posterArtUri = TvContract.buildChannelLogoUri(getCurrentChannelId()).toString();
- }
- updatePosterArt(getCurrentChannel(), currentProgram, cardTitleText, null, posterArtUri);
- mMediaSession.setActive(true);
- }
-
- private void updatePosterArt(Channel currentChannel, Program currentProgram,
- String cardTitleText, @Nullable Bitmap posterArt, @Nullable String posterArtUri) {
- if (posterArt != null) {
- updateMediaMetadata(cardTitleText, posterArt);
- } else if (posterArtUri != null) {
- ImageLoader.loadBitmap(this, posterArtUri, mNowPlayingCardWidth, mNowPlayingCardHeight,
- new ProgramPosterArtCallback(this, currentChannel,
- currentProgram, cardTitleText));
- } else {
- updateMediaMetadata(cardTitleText, R.drawable.default_now_card);
- }
- }
-
- private static class ProgramPosterArtCallback extends
- ImageLoader.ImageLoaderCallback<MainActivity> {
- private final Channel mChannel;
- private final Program mProgram;
- private final String mCardTitleText;
-
- public ProgramPosterArtCallback(MainActivity mainActivity, Channel channel, Program program,
- String cardTitleText) {
- super(mainActivity);
- mChannel = channel;
- mProgram = program;
- mCardTitleText = cardTitleText;
- }
-
- @Override
- public void onBitmapLoaded(MainActivity mainActivity, @Nullable Bitmap posterArt) {
- if (mainActivity.isNowPlayingProgram(mChannel, mProgram)) {
- mainActivity.updatePosterArt(mChannel, mProgram, mCardTitleText, posterArt, null);
- }
- }
- }
-
- private boolean isNowPlayingProgram(Channel channel, Program program) {
+ boolean isNowPlayingProgram(Channel channel, Program program) {
return program == null ? (channel != null && getCurrentProgram() == null
&& channel.equals(getCurrentChannel())) : program.equals(getCurrentProgram());
}
- private void updateMediaMetadata(final String title, final Bitmap posterArt) {
- new AsyncTask<Void, Void, Void> () {
- @Override
- protected Void doInBackground(Void... arg0) {
- MediaMetadata.Builder builder = new MediaMetadata.Builder();
- builder.putString(MediaMetadata.METADATA_KEY_TITLE, title);
- if (posterArt != null) {
- builder.putBitmap(MediaMetadata.METADATA_KEY_ART, posterArt);
- }
- mMediaSession.setMetadata(builder.build());
- return null;
- }
- }.execute();
- }
-
- private void updateMediaMetadata(final String title, final int imageResId) {
- new AsyncTask<Void, Void, Void> () {
- @Override
- protected Void doInBackground(Void... arg0) {
- MediaMetadata.Builder builder = new MediaMetadata.Builder();
- builder.putString(MediaMetadata.METADATA_KEY_TITLE, title);
- Bitmap posterArt = BitmapFactory.decodeResource(getResources(), imageResId);
- if (posterArt != null) {
- builder.putBitmap(MediaMetadata.METADATA_KEY_ART, posterArt);
- }
- mMediaSession.setMetadata(builder.build());
- return null;
- }
- }.execute();
- }
-
- private String getCurrentChannelName() {
- Channel channel = getCurrentChannel();
- if (channel == null) {
- return "";
- }
- if (channel.isPassthrough()) {
- TvInputInfo input = getTvInputManagerHelper().getTvInputInfo(channel.getInputId());
- return Utils.loadLabel(this, input);
- } else {
- return channel.getDisplayName();
- }
- }
-
- private void setMediaSessionPlaybackState(boolean isPlaying) {
- PlaybackState.Builder builder = new PlaybackState.Builder();
- builder.setState(isPlaying ? PlaybackState.STATE_PLAYING : PlaybackState.STATE_STOPPED,
- PlaybackState.PLAYBACK_POSITION_UNKNOWN,
- isPlaying ? MEDIA_SESSION_PLAYING_SPEED : MEDIA_SESSION_STOPPED_SPEED);
- mMediaSession.setPlaybackState(builder.build());
- }
-
private void addToRecentChannels(long channelId) {
if (!mRecentChannels.remove(channelId)) {
if (mRecentChannels.size() >= MAX_RECENT_CHANNELS) {
@@ -2042,106 +1666,35 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return mRecentChannels;
}
- private void checkChannelLockNeeded(TunableTvView tvView) {
- Channel channel = tvView.getCurrentChannel();
- if (tvView.isPlaying() && channel != null) {
+ private void checkChannelLockNeeded(TunableTvView tvView, Channel currentChannel) {
+ if (currentChannel == null) {
+ currentChannel = tvView.getCurrentChannel();
+ }
+ if (tvView.isPlaying() && currentChannel != null) {
if (getParentalControlSettings().isParentalControlsEnabled()
- && channel.isLocked()
+ && currentChannel.isLocked()
&& !mShowLockedChannelsTemporarily
&& !(isUnderShrunkenTvView()
- && channel.equals(mChannelBeforeShrunkenTvView)
+ && currentChannel.equals(mChannelBeforeShrunkenTvView)
&& mWasChannelUnblockedBeforeShrunkenByUser)) {
- if (DEBUG) Log.d(TAG, "Channel " + channel.getId() + " is locked");
- blockScreen(tvView);
+ if (DEBUG) Log.d(TAG, "Channel " + currentChannel.getId() + " is locked");
+ blockOrUnblockScreen(tvView, true);
} else {
- unblockScreen(tvView);
+ blockOrUnblockScreen(tvView, false);
}
}
}
- private void blockScreen(TunableTvView tvView) {
- tvView.blockScreen();
+ private void blockOrUnblockScreen(TunableTvView tvView, boolean blockOrUnblock) {
+ tvView.blockOrUnblockScreen(blockOrUnblock);
if (tvView == mTvView) {
- updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK);
- updateMediaSession();
- }
- }
-
- private void unblockScreen(TunableTvView tvView) {
- tvView.unblockScreen();
- if (tvView == mTvView) {
- updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK);
- updateMediaSession();
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK);
+ mMediaSessionWrapper.update(blockOrUnblock, getCurrentChannel(), getCurrentProgram());
}
}
/**
- * Shows the channel banner if it was hidden from the side fragment.
- *
- * <p>When the side fragment is visible, showing the channel banner should be put off until the
- * side fragment is closed even though the channel changes.
- */
- public void showChannelBannerIfHiddenBySideFragment() {
- if (mChannelBannerHiddenBySideFragment) {
- updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW);
- }
- }
-
- private void updateChannelBannerAndShowIfNeeded(@ChannelBannerUpdateReason int reason) {
- if(DEBUG) Log.d(TAG, "updateChannelBannerAndShowIfNeeded(reason=" + reason + ")");
- if (!mChannelTuner.isCurrentChannelPassthrough()) {
- int lockType = ChannelBannerView.LOCK_NONE;
- if (mTvView.isScreenBlocked()) {
- lockType = ChannelBannerView.LOCK_CHANNEL_INFO;
- } else if (mTvView.getBlockedContentRating() != null
- || (getParentalControlSettings().isParentalControlsEnabled()
- && !mTvView.isVideoAvailable())) {
- // If the parental control is enabled, do not show the program detail until the
- // video becomes available.
- lockType = ChannelBannerView.LOCK_PROGRAM_DETAIL;
- }
- if (lockType == ChannelBannerView.LOCK_NONE) {
- if (reason == UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST) {
- // Do not show detailed program information while fast-tuning.
- lockType = ChannelBannerView.LOCK_PROGRAM_DETAIL;
- } else if (reason == UPDATE_CHANNEL_BANNER_REASON_TUNE
- && getParentalControlSettings().isParentalControlsEnabled()) {
- // If parental control is turned on,
- // assumes that program is locked by default and waits for onContentAllowed.
- lockType = ChannelBannerView.LOCK_PROGRAM_DETAIL;
- }
- }
- // If lock type is not changed, we don't need to update channel banner by parental
- // control.
- if (!mChannelBannerView.setLockType(lockType)
- && reason == UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK) {
- return;
- }
-
- mChannelBannerView.updateViews(mTvView);
- }
- boolean needToShowBanner = (reason == UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW
- || reason == UPDATE_CHANNEL_BANNER_REASON_TUNE
- || reason == UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST);
- boolean noOverlayUiWhenResume =
- mInputToSetUp == null && !mShowProgramGuide && !mShowSelectInputView;
- if (needToShowBanner && noOverlayUiWhenResume
- && mOverlayManager.getCurrentDialog() == null
- && !mOverlayManager.isSetupFragmentActive()
- && !mOverlayManager.isNewSourcesFragmentActive()) {
- if (mChannelTuner.getCurrentChannel() == null) {
- mChannelBannerHiddenBySideFragment = false;
- } else if (mOverlayManager.getSideFragmentManager().isActive()) {
- mChannelBannerHiddenBySideFragment = true;
- } else {
- mChannelBannerHiddenBySideFragment = false;
- mOverlayManager.showBanner();
- }
- }
- updateAvailabilityToast();
- }
-
- /**
* Hide the overlays when tuning to a channel from the menu (e.g. Channels).
*/
public void hideOverlaysForTune() {
@@ -2197,7 +1750,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (bestTrack != null) {
String selectedTrack = getSelectedTrack(TvTrackInfo.TYPE_AUDIO);
if (!bestTrack.getId().equals(selectedTrack)) {
- selectTrack(TvTrackInfo.TYPE_AUDIO, bestTrack);
+ selectTrack(TvTrackInfo.TYPE_AUDIO, bestTrack, UNDEFINED_TRACK_INDEX);
} else {
mTvOptionsManager.onMultiAudioChanged(
Utils.getMultiAudioString(this, bestTrack, false));
@@ -2210,7 +1763,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private void applyClosedCaption() {
List<TvTrackInfo> tracks = getTracks(TvTrackInfo.TYPE_SUBTITLE);
if (tracks == null) {
- mTvOptionsManager.onClosedCaptionsChanged(null);
+ mTvOptionsManager.onClosedCaptionsChanged(null, UNDEFINED_TRACK_INDEX);
return;
}
@@ -2219,17 +1772,19 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
String selectedTrackId = getSelectedTrack(TvTrackInfo.TYPE_SUBTITLE);
TvTrackInfo alternativeTrack = null;
+ int alternativeTrackIndex = UNDEFINED_TRACK_INDEX;
if (enabled) {
String language = mCaptionSettings.getLanguage();
String trackId = mCaptionSettings.getTrackId();
- for (TvTrackInfo track : tracks) {
+ for (int i = 0; i < tracks.size(); i++) {
+ TvTrackInfo track = tracks.get(i);
if (Utils.isEqualLanguage(track.getLanguage(), language)) {
if (track.getId().equals(trackId)) {
if (!track.getId().equals(selectedTrackId)) {
- selectTrack(TvTrackInfo.TYPE_SUBTITLE, track);
+ selectTrack(TvTrackInfo.TYPE_SUBTITLE, track, i);
} else {
// Already selected. Update the option string only.
- mTvOptionsManager.onClosedCaptionsChanged(track);
+ mTvOptionsManager.onClosedCaptionsChanged(track, i);
}
if (DEBUG) {
Log.d(TAG, "Subtitle Track Selected {id=" + track.getId()
@@ -2238,14 +1793,16 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return;
} else if (alternativeTrack == null) {
alternativeTrack = track;
+ alternativeTrackIndex = i;
}
}
}
if (alternativeTrack != null) {
if (!alternativeTrack.getId().equals(selectedTrackId)) {
- selectTrack(TvTrackInfo.TYPE_SUBTITLE, alternativeTrack);
+ selectTrack(TvTrackInfo.TYPE_SUBTITLE, alternativeTrack, alternativeTrackIndex);
} else {
- mTvOptionsManager.onClosedCaptionsChanged(alternativeTrack);
+ mTvOptionsManager
+ .onClosedCaptionsChanged(alternativeTrack, alternativeTrackIndex);
}
if (DEBUG) {
Log.d(TAG, "Subtitle Track Selected {id=" + alternativeTrack.getId()
@@ -2255,29 +1812,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
}
if (selectedTrackId != null) {
- selectTrack(TvTrackInfo.TYPE_SUBTITLE, null);
+ selectTrack(TvTrackInfo.TYPE_SUBTITLE, null, UNDEFINED_TRACK_INDEX);
if (DEBUG) Log.d(TAG, "Subtitle Track Unselected");
return;
}
- mTvOptionsManager.onClosedCaptionsChanged(null);
- }
-
- /**
- * Pops up the KeypadChannelSwitchView with the given key input event.
- *
- * @param keyCode A key code of the key event.
- */
- public void showKeypadChannelSwitchView(int keyCode) {
- if (mChannelTuner.areAllChannelsLoaded()) {
- mOverlayManager.showKeypadChannelSwitch();
- mKeypadChannelSwitchView.onNumberKeyUp(keyCode - KeyEvent.KEYCODE_0);
- }
- }
-
- public void showSearchActivity() {
- // HACK: Once we moved the window layer to TYPE_APPLICATION_SUB_PANEL,
- // the voice button doesn't work. So we directly call the voice action.
- SearchManagerHelper.getInstance(this).launchAssistAction();
+ mTvOptionsManager.onClosedCaptionsChanged(null, UNDEFINED_TRACK_INDEX);
}
public void showProgramGuideSearchFragment() {
@@ -2295,13 +1834,12 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
@Override
protected void onDestroy() {
if (DEBUG) Log.d(TAG, "onDestroy()");
- SideFragment.releasePreloadedRecycledViews();
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).reset();
+ SideFragment.releaseRecycledViewPool();
+ ViewCache.getInstance().clear();
if (mTvView != null) {
mTvView.release();
}
- if (mPipView != null) {
- mPipView.release();
- }
if (mChannelTuner != null) {
mChannelTuner.removeListener(mChannelTunerListener);
mChannelTuner.stop();
@@ -2314,21 +1852,15 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mProgramDataManager.setPrefetchEnabled(false);
}
}
- if (mPipInputManager != null) {
- mPipInputManager.stop();
- }
if (mOverlayManager != null) {
mOverlayManager.release();
}
- if (mKeypadChannelSwitchView != null) {
- mKeypadChannelSwitchView.setChannels(null);
- }
mMemoryManageables.clear();
- if (mMediaSession != null) {
- mMediaSession.release();
+ if (mMediaSessionWrapper != null) {
+ mMediaSessionWrapper.release();
}
- if (mAudioCapabilitiesReceiver != null) {
- mAudioCapabilitiesReceiver.unregister();
+ if (mAudioManagerHelper != null) {
+ mAudioManagerHelper.release();
}
mHandler.removeCallbacksAndMessages(null);
application.getMainActivityWrapper().onMainActivityDestroyed(this);
@@ -2340,8 +1872,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mChannelStatusRecurringRunner.stop();
mChannelStatusRecurringRunner = null;
}
- if (mTvInputManagerHelper != null && Features.TUNER.isEnabled(this)) {
- mTvInputManagerHelper.removeCallback(mTvInputCallback);
+ if (mTvInputManagerHelper != null) {
+ mTvInputManagerHelper.clearTvInputLabels();
+ if (Features.TUNER.isEnabled(this)) {
+ mTvInputManagerHelper.removeCallback(mTvInputCallback);
+ }
}
super.onDestroy();
}
@@ -2410,7 +1945,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
* G debug: refresh cloud epg
* I KEYCODE_TV_INPUT
* O debug: show display mode option
- * P debug: togglePipView
* S KEYCODE_CAPTIONS: select subtitle
* W debug: toggle screen size
* V KEYCODE_MEDIA_RECORD debug: record the current channel for 30 sec
@@ -2422,8 +1956,9 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
finishChannelChangeIfNeeded();
if (event.getKeyCode() == KeyEvent.KEYCODE_SEARCH) {
- showSearchActivity();
- return true;
+ // Prevent MainActivity from being closed by onVisibleBehindCanceled()
+ mOtherActivityLaunched = true;
+ return false;
}
switch (mOverlayManager.onKeyUp(keyCode, event)) {
case KEY_EVENT_HANDLER_RESULT_DISPATCH_TO_OVERLAY:
@@ -2467,12 +2002,12 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
} else {
if (KeypadChannelSwitchView.isChannelNumberKey(keyCode)) {
- showKeypadChannelSwitchView(keyCode);
+ mOverlayManager.showKeypadChannelSwitch(keyCode);
return true;
}
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (!mTvView.isVideoAvailable()
+ if (!mTvView.isVideoOrAudioAvailable()
&& mTvView.getVideoUnavailableReason()
== TunableTvView.VIDEO_UNAVAILABLE_REASON_NO_RESOURCE) {
DvrUiHelper.startSchedulesActivityForTuneConflict(this,
@@ -2480,35 +2015,16 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return true;
}
if (!PermissionUtils.hasModifyParentalControls(this)) {
- // TODO: support this feature for non-system LC app. b/23939816
return true;
}
PinDialogFragment dialog = null;
if (mTvView.isScreenBlocked()) {
- dialog = new PinDialogFragment(
- PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_CHANNEL,
- new PinDialogFragment.ResultListener() {
- @Override
- public void done(boolean success) {
- if (success) {
- unblockScreen(mTvView);
- mIsCurrentChannelUnblockedByUser = true;
- }
- }
- });
- } else if (mTvView.getBlockedContentRating() != null) {
- final TvContentRating rating = mTvView.getBlockedContentRating();
- dialog = new PinDialogFragment(
- PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_PROGRAM,
- new PinDialogFragment.ResultListener() {
- @Override
- public void done(boolean success) {
- if (success) {
- mLastAllowedRatingForCurrentChannel = rating;
- mTvView.unblockContent(rating);
- }
- }
- });
+ dialog = PinDialogFragment
+ .create(PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_CHANNEL);
+ } else if (mTvView.isContentBlocked()) {
+ dialog = PinDialogFragment
+ .create(PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_PROGRAM,
+ mTvView.getBlockedContentRating().flattenToString());
}
if (dialog != null) {
mOverlayManager.showDialogFragment(PinDialogFragment.DIALOG_TAG, dialog,
@@ -2531,7 +2047,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return true;
}
if (keyCode != KeyEvent.KEYCODE_MENU) {
- updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW);
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW);
}
if (keyCode != KeyEvent.KEYCODE_E) {
mOverlayManager.showMenu(Menu.REASON_NONE);
@@ -2547,6 +2064,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (!SystemProperties.USE_DEBUG_KEYS.getValue()) {
break;
}
+ // Pass through.
case KeyEvent.KEYCODE_CAPTIONS: {
mOverlayManager.getSideFragmentManager().show(new ClosedCaptionFragment());
return true;
@@ -2555,14 +2073,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (!SystemProperties.USE_DEBUG_KEYS.getValue()) {
break;
}
+ // Pass through.
case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
mOverlayManager.getSideFragmentManager().show(new MultiAudioFragment());
return true;
}
- case KeyEvent.KEYCODE_GUIDE: {
- mOverlayManager.showProgramGuide();
- return true;
- }
case KeyEvent.KEYCODE_INFO: {
mOverlayManager.showBanner();
return true;
@@ -2578,22 +2093,17 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
Toast.makeText(this, R.string.dvr_msg_cannot_record_program,
Toast.LENGTH_SHORT).show();
} else {
- if (!DvrUiHelper.checkStorageStatusAndShowErrorMessage(this,
- currentChannel.getInputId())) {
- return true;
- }
Program program = mProgramDataManager
.getCurrentProgram(currentChannel.getId());
- if (program == null) {
- DvrUiHelper
- .showChannelRecordDurationOptions(this, currentChannel);
- } else if (DvrUiHelper.handleCreateSchedule(this, program)) {
- String msg = getString(
- R.string.dvr_msg_current_program_scheduled,
- program.getTitle(), Utils.toTimeString(
- program.getEndTimeUtcMillis(), false));
- Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
- }
+ DvrUiHelper.checkStorageStatusAndShowErrorMessage(this,
+ currentChannel.getInputId(), new Runnable() {
+ @Override
+ public void run() {
+ DvrUiHelper.requestRecordingCurrentProgram(
+ MainActivity.this,
+ currentChannel, program, false);
+ }
+ });
}
} else {
DvrUiHelper.showStopRecordingDialog(this, currentChannel.getId(),
@@ -2624,7 +2134,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
if (SystemProperties.USE_DEBUG_KEYS.getValue() || BuildConfig.ENG) {
switch (keyCode) {
- case KeyEvent.KEYCODE_W: {
+ case KeyEvent.KEYCODE_W:
mDebugNonFullSizeScreen = !mDebugNonFullSizeScreen;
if (mDebugNonFullSizeScreen) {
FrameLayout.LayoutParams params =
@@ -2632,30 +2142,23 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
params.width = 960;
params.height = 540;
params.gravity = Gravity.START;
- mTvView.setLayoutParams(params);
+ mTvView.setTvViewLayoutParams(params);
} else {
FrameLayout.LayoutParams params =
(FrameLayout.LayoutParams) mTvView.getLayoutParams();
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.CENTER;
- mTvView.setLayoutParams(params);
+ mTvView.setTvViewLayoutParams(params);
}
return true;
- }
- case KeyEvent.KEYCODE_P: {
- togglePipView();
- return true;
- }
case KeyEvent.KEYCODE_CTRL_LEFT:
- case KeyEvent.KEYCODE_CTRL_RIGHT: {
+ case KeyEvent.KEYCODE_CTRL_RIGHT:
mUseKeycodeBlacklist = !mUseKeycodeBlacklist;
return true;
- }
- case KeyEvent.KEYCODE_O: {
+ case KeyEvent.KEYCODE_O:
mOverlayManager.getSideFragmentManager().show(new DisplayModeFragment());
return true;
- }
case KeyEvent.KEYCODE_D:
mOverlayManager.getSideFragmentManager().show(new DeveloperOptionFragment());
return true;
@@ -2681,22 +2184,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
@Override
- public void onBackPressed() {
- // The activity should be returned to the caller of this activity
- // when the mSource is not null.
- if (!mOverlayManager.getSideFragmentManager().isActive() && isPlaying()
- && mSource == null) {
- // If back key would exit TV app,
- // show McLauncher instead so we can get benefit of McLauncher's shyMode.
- Intent startMain = new Intent(Intent.ACTION_MAIN);
- startMain.addCategory(Intent.CATEGORY_HOME);
- startActivity(startMain);
- } else {
- super.onBackPressed();
- }
- }
-
- @Override
public void onUserInteraction() {
super.onUserInteraction();
if (mOverlayManager != null) {
@@ -2725,66 +2212,10 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
}
- public void togglePipView() {
- enablePipView(!mPipEnabled, true);
- mOverlayManager.getMenu().update();
- }
-
- public boolean isPipEnabled() {
- return mPipEnabled;
- }
-
- public void tuneToChannelForPip(Channel channel) {
- if (!mPipEnabled) {
- throw new IllegalStateException("tuneToChannelForPip is called when PIP is off");
- }
- if (mPipChannel.equals(channel)) {
- return;
- }
- mPipChannel = channel;
- startPip(true);
- }
-
- private void enablePipView(boolean enable, boolean fromUserInteraction) {
- if (enable == mPipEnabled) {
- return;
- }
- if (enable) {
- List<PipInput> pipAvailableInputs = mPipInputManager.getPipInputList(true);
- if (pipAvailableInputs.isEmpty()) {
- Toast.makeText(this, R.string.msg_no_available_input_by_pip, Toast.LENGTH_SHORT)
- .show();
- return;
- }
- // TODO: choose the last pip input.
- Channel pipChannel = pipAvailableInputs.get(0).getChannel();
- if (pipChannel != null) {
- mPipEnabled = true;
- mPipChannel = pipChannel;
- startPip(fromUserInteraction);
- mTvViewUiManager.restorePipSize();
- mTvViewUiManager.restorePipLayout();
- mTvOptionsManager.onPipChanged(mPipEnabled);
- } else {
- Toast.makeText(this, R.string.msg_no_available_input_by_pip, Toast.LENGTH_SHORT)
- .show();
- }
- } else {
- mPipEnabled = false;
- mPipChannel = null;
- // Recover the stream volume of the main TV view, if needed.
- if (mPipSound == TvSettings.PIP_SOUND_PIP_WINDOW) {
- setVolumeByAudioFocusStatus(mTvView);
- mPipSound = TvSettings.PIP_SOUND_MAIN;
- mTvOptionsManager.onPipSoundChanged(mPipSound);
- }
- stopPip();
- mTvViewUiManager.restoreDisplayMode(false);
- mTvOptionsManager.onPipChanged(mPipEnabled);
- }
- }
-
- private boolean isChannelChangeKeyDownReceived() {
+ /**
+ * Returns {@code true} if one of the channel changing keys are pressed and not released yet.
+ */
+ public boolean isChannelChangeKeyDownReceived() {
return mHandler.hasMessages(MSG_CHANNEL_UP_PRESSED)
|| mHandler.hasMessages(MSG_CHANNEL_DOWN_PRESSED);
}
@@ -2811,10 +2242,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (SystemProperties.LOG_KEYEVENT.getValue()) {
Log.d(TAG, "dispatchKeyEventToSession(" + event + ")");
}
- if (mPipEnabled && mChannelTuner.isCurrentChannelPassthrough()) {
- // If PIP is enabled, key events will be used by UI.
- return false;
- }
boolean handled = false;
if (mTvView != null) {
handled = mTvView.dispatchKeyEvent(event);
@@ -2832,21 +2259,15 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
private boolean isKeyEventBlocked() {
- // If the current channel is passthrough channel without a PIP view,
- // we always don't handle the key events in TV activity. Instead, the key event will
- // be handled by the passthrough TV input.
- return mChannelTuner.isCurrentChannelPassthrough() && !mPipEnabled;
+ // If the current channel is a passthrough channel, we don't handle the key events in TV
+ // activity. Instead, the key event will be handled by the passthrough TV input.
+ return mChannelTuner.isCurrentChannelPassthrough();
}
private void tuneToLastWatchedChannelForTunerInput() {
if (!mChannelTuner.isCurrentChannelPassthrough()) {
return;
}
- if (mPipEnabled) {
- if (!mPipChannel.isPassthrough()) {
- enablePipView(false, true);
- }
- }
stopTv();
startTv(null);
}
@@ -2857,16 +2278,17 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mTvView.reset();
}
} else {
- if (mPipEnabled && mPipInputManager.areInSamePipInput(channel, mPipChannel)) {
- enablePipView(false, true);
- }
if (!mTvView.isPlaying()) {
startTv(channel.getUri());
} else if (channel.equals(mTvView.getCurrentChannel())) {
- updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_TUNE);
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_TUNE);
+ } else if (channel == mChannelTuner.getCurrentChannel()) {
+ // Channel banner is already updated in moveToAdjacentChannel
+ tune(false);
} else if (mChannelTuner.moveToChannel(channel)) {
// Channel banner would be updated inside of tune.
- tune();
+ tune(true);
} else {
showSettingsFragment();
}
@@ -2883,107 +2305,25 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
*/
private void moveToAdjacentChannel(boolean channelUp, boolean fastTuning) {
if (mChannelTuner.moveToAdjacentBrowsableChannel(channelUp)) {
- updateChannelBannerAndShowIfNeeded(fastTuning ? UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST
- : UPDATE_CHANNEL_BANNER_REASON_TUNE);
- }
- }
-
- public Channel getPipChannel() {
- return mPipChannel;
- }
-
- /**
- * Swap the main and the sub screens while in the PIP mode.
- */
- public void swapPip() {
- if (!mPipEnabled || mTvView == null || mPipView == null) {
- Log.e(TAG, "swapPip() - not in PIP");
- mPipSwap = false;
- return;
- }
-
- Channel channel = mTvView.getCurrentChannel();
- boolean tvViewBlocked = mTvView.isScreenBlocked();
- boolean pipViewBlocked = mPipView.isScreenBlocked();
- if (channel == null || !mTvView.isPlaying()) {
- // If the TV view is not currently playing or its current channel is null, swapping here
- // basically means disabling the PIP mode and getting back to the full screen since
- // there's no point of keeping a blank PIP screen at the bottom which is not tune-able.
- enablePipView(false, true);
- mOverlayManager.hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_DEFAULT);
- mPipSwap = false;
- return;
- }
-
- // Reset the TV view and tune the PIP view to the previous channel of the TV view.
- mTvView.reset();
- mPipView.reset();
- Channel oldPipChannel = mPipChannel;
- tuneToChannelForPip(channel);
- if (tvViewBlocked) {
- mPipView.blockScreen();
- } else {
- mPipView.unblockScreen();
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(fastTuning ?
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST
+ : TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_TUNE);
}
-
- if (oldPipChannel != null) {
- // Tune the TV view to the previous PIP channel.
- tuneToChannel(oldPipChannel);
- }
- if (pipViewBlocked) {
- mTvView.blockScreen();
- } else {
- mTvView.unblockScreen();
- }
- if (mPipSound == TvSettings.PIP_SOUND_MAIN) {
- setVolumeByAudioFocusStatus(mTvView);
- } else { // mPipSound == TvSettings.PIP_SOUND_PIP_WINDOW
- setVolumeByAudioFocusStatus(mPipView);
- }
- mPipSwap = !mPipSwap;
- mTvOptionsManager.onPipSwapChanged(mPipSwap);
- }
-
- /**
- * Toggle where the sound is coming from when the user is watching the PIP.
- */
- public void togglePipSoundMode() {
- if (!mPipEnabled || mTvView == null || mPipView == null) {
- Log.e(TAG, "togglePipSoundMode() - not in PIP");
- return;
- }
- if (mPipSound == TvSettings.PIP_SOUND_MAIN) {
- setVolumeByAudioFocusStatus(mPipView);
- mPipSound = TvSettings.PIP_SOUND_PIP_WINDOW;
- } else { // mPipSound == TvSettings.PIP_SOUND_PIP_WINDOW
- setVolumeByAudioFocusStatus(mTvView);
- mPipSound = TvSettings.PIP_SOUND_MAIN;
- }
- restoreMainTvView();
- mTvOptionsManager.onPipSoundChanged(mPipSound);
}
/**
* Set the main TV view which holds HDMI-CEC active source based on the sound mode
*/
private void restoreMainTvView() {
- if (mPipSound == TvSettings.PIP_SOUND_MAIN) {
- mTvView.setMain();
- } else { // mPipSound == TvSettings.PIP_SOUND_PIP_WINDOW
- mPipView.setMain();
- }
+ mTvView.setMain();
}
@Override
public void onVisibleBehindCanceled() {
stopTv("onVisibleBehindCanceled()", false);
mTracker.sendScreenView("");
- mAudioFocusStatus = AudioManager.AUDIOFOCUS_LOSS;
- mAudioManager.abandonAudioFocus(this);
- if (mMediaSession.isActive()) {
- mMediaSession.setActive(false);
- }
- stopPip();
+ mAudioManagerHelper.abandonAudioFocus();
+ mMediaSessionWrapper.setPlaybackState(false);
mVisibleBehind = false;
if (!mOtherActivityLaunched && Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
// Workaround: in M, onStop is not called, even though it should be called after
@@ -3012,13 +2352,13 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return mTvView.getSelectedTrack(type);
}
- private void selectTrack(int type, TvTrackInfo track) {
+ private void selectTrack(int type, TvTrackInfo track, int trackIndex) {
mTvView.selectTrack(type, track == null ? null : track.getId());
if (type == TvTrackInfo.TYPE_AUDIO) {
mTvOptionsManager.onMultiAudioChanged(track == null ? null :
Utils.getMultiAudioString(this, track, false));
} else if (type == TvTrackInfo.TYPE_SUBTITLE) {
- mTvOptionsManager.onClosedCaptionsChanged(track);
+ mTvOptionsManager.onClosedCaptionsChanged(track, trackIndex);
}
}
@@ -3073,16 +2413,12 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
private void updateAvailabilityToast() {
- updateAvailabilityToast(mTvView);
- }
-
- private void updateAvailabilityToast(StreamInfo info) {
- if (info.isVideoAvailable()) {
+ if (mTvView.isVideoAvailable()
+ || mTvView.getCurrentChannel() != mChannelTuner.getCurrentChannel()) {
return;
}
- int stringId;
- switch (info.getVideoUnavailableReason()) {
+ switch (mTvView.getVideoUnavailableReason()) {
case TunableTvView.VIDEO_UNAVAILABLE_REASON_NOT_TUNED:
case TunableTvView.VIDEO_UNAVAILABLE_REASON_NO_RESOURCE:
case TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING:
@@ -3092,13 +2428,22 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return;
case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:
default:
- stringId = R.string.msg_channel_unavailable_unknown;
+ Toast.makeText(this, R.string.msg_channel_unavailable_unknown,
+ Toast.LENGTH_SHORT).show();
break;
}
+ }
- Toast.makeText(this, stringId, Toast.LENGTH_SHORT).show();
+ /**
+ * Returns {@code true} if some overlay UI will be shown when the activity is resumed.
+ */
+ public boolean willShowOverlayUiWhenResume() {
+ return mInputToSetUp != null || mShowProgramGuide || mShowSelectInputView;
}
+ /**
+ * Returns the current parental control settings.
+ */
public ParentalControlSettings getParentalControlSettings() {
return mTvInputManagerHelper.getParentalControlSettings();
}
@@ -3110,6 +2455,9 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
return mTvInputManagerHelper.getContentRatingsManager();
}
+ /**
+ * Returns the current captioning settings.
+ */
public CaptionSettings getCaptionSettings() {
return mCaptionSettings;
}
@@ -3163,6 +2511,7 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (mActivityStarted) {
initAnimations();
initSideFragments();
+ initMenuItemViews();
}
}
}, LAZY_INITIALIZATION_DELAY);
@@ -3174,7 +2523,11 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
private void initSideFragments() {
- SideFragment.preloadRecycledViews(this);
+ SideFragment.preloadItemViews(this);
+ }
+
+ private void initMenuItemViews() {
+ mOverlayManager.getMenu().preloadItemViews();
}
@Override
@@ -3207,10 +2560,6 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
sendMessageDelayed(Message.obtain(msg), getDelay(startTime));
mainActivity.moveToAdjacentChannel(true, true);
break;
- case MSG_UPDATE_CHANNEL_BANNER_BY_INFO_UPDATE:
- mainActivity.updateChannelBannerAndShowIfNeeded(
- UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO);
- break;
}
}
@@ -3225,14 +2574,10 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
private class MyOnTuneListener implements OnTuneListener {
boolean mUnlockAllowedRatingBeforeShrunken = true;
boolean mWasUnderShrunkenTvView;
- long mStreamInfoUpdateTimeThresholdMs;
Channel mChannel;
- public MyOnTuneListener() { }
-
private void onTune(Channel channel, boolean wasUnderShrukenTvView) {
- mStreamInfoUpdateTimeThresholdMs =
- System.currentTimeMillis() + FIRST_STREAM_INFO_UPDATE_DELAY_MILLIS;
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log("MainActivity.MyOnTuneListener.onTune");
mChannel = channel;
mWasUnderShrunkenTvView = wasUnderShrukenTvView;
}
@@ -3249,7 +2594,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (mTvView.isFadedOut()) {
mTvView.removeFadeEffect();
}
- // TODO: show something to user about this error.
+ Toast.makeText(MainActivity.this, R.string.msg_channel_unavailable_unknown,
+ Toast.LENGTH_SHORT).show();
}
@Override
@@ -3258,29 +2604,21 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mTracker.sendChannelTuneTime(info.getCurrentChannel(),
mTuneDurationTimer.reset());
}
- // If updateChannelBanner() is called without delay, the stream info seems flickering
- // when the channel is quickly changed.
- if (!mHandler.hasMessages(MSG_UPDATE_CHANNEL_BANNER_BY_INFO_UPDATE)
- && info.isVideoAvailable()) {
- if (System.currentTimeMillis() > mStreamInfoUpdateTimeThresholdMs) {
- updateChannelBannerAndShowIfNeeded(
- UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO);
- } else {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(
- MSG_UPDATE_CHANNEL_BANNER_BY_INFO_UPDATE),
- mStreamInfoUpdateTimeThresholdMs - System.currentTimeMillis());
- }
+ if (info.isVideoOrAudioAvailable() && mChannel == getCurrentChannel()) {
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_UPDATE_STREAM_INFO);
}
-
applyDisplayRefreshRate(info.getVideoFrameRate());
- mTvViewUiManager.updateTvView();
+ mTvViewUiManager.updateTvAspectRatio();
applyMultiAudio();
applyClosedCaption();
- // TODO: Send command to TIS with checking the settings in TV and CaptionManager.
mOverlayManager.getMenu().onStreamInfoChanged();
if (mTvView.isVideoAvailable()) {
mTvViewUiManager.fadeInTvView();
}
+ if (!mTvView.isContentBlocked() && !mTvView.isScreenBlocked()) {
+ updateAvailabilityToast();
+ }
mHandler.removeCallbacks(mRestoreMainViewRunnable);
restoreMainTvView();
}
@@ -3303,11 +2641,15 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
}
mChannelTuner.setCurrentChannel(currentChannel);
mTvView.setCurrentChannel(currentChannel);
- updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_TUNE);
+ mOverlayManager.updateChannelBannerAndShowIfNeeded(
+ TvOverlayManager.UPDATE_CHANNEL_BANNER_REASON_TUNE);
}
@Override
public void onContentBlocked() {
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
+ "MainActivity.MyOnTuneListener.onContentBlocked removes timer");
+ Debug.removeTimer(Debug.TAG_START_UP_TIMER);
mTuneDurationTimer.reset();
TvContentRating rating = mTvView.getBlockedContentRating();
// When tuneTo was called while TV view was shrunken, if the channel id is the same
@@ -3319,9 +2661,9 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
mUnlockAllowedRatingBeforeShrunken = isUnderShrunkenTvView();
mTvView.unblockContent(rating);
}
- mChannelBannerView.setBlockingContentRating(rating);
- updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK);
+ mOverlayManager.setBlockingContentRating(rating);
mTvViewUiManager.fadeInTvView();
+ mMediaSessionWrapper.update(true, getCurrentChannel(), getCurrentProgram());
}
@Override
@@ -3329,8 +2671,8 @@ public class MainActivity extends Activity implements AudioManager.OnAudioFocusC
if (!isUnderShrunkenTvView()) {
mUnlockAllowedRatingBeforeShrunken = false;
}
- mChannelBannerView.setBlockingContentRating(null);
- updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK);
+ mOverlayManager.setBlockingContentRating(null);
+ mMediaSessionWrapper.update(false, getCurrentChannel(), getCurrentProgram());
}
}
}
diff --git a/src/com/android/tv/MainActivityWrapper.java b/src/com/android/tv/MainActivityWrapper.java
index 01733255..5af5079f 100644
--- a/src/com/android/tv/MainActivityWrapper.java
+++ b/src/com/android/tv/MainActivityWrapper.java
@@ -61,7 +61,7 @@ public final class MainActivityWrapper {
* Unsets the main activity instance.
*/
public void onMainActivityDestroyed(@NonNull MainActivity activity) {
- if (mActivity != activity) {
+ if (mActivity == activity) {
mActivity = null;
}
}
diff --git a/src/com/android/tv/MediaSessionWrapper.java b/src/com/android/tv/MediaSessionWrapper.java
new file mode 100644
index 00000000..da6ad2a4
--- /dev/null
+++ b/src/com/android/tv/MediaSessionWrapper.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2017 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.tv;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.MediaMetadata;
+import android.media.session.MediaSession;
+import android.media.session.PlaybackState;
+import android.media.tv.TvContract;
+import android.media.tv.TvInputInfo;
+import android.os.AsyncTask;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+
+import com.android.tv.data.Channel;
+import com.android.tv.data.Program;
+import com.android.tv.util.ImageLoader;
+import com.android.tv.util.Utils;
+
+/**
+ * A wrapper class for {@link MediaSession} to support common operations on media sessions for
+ * {@link MainActivity}.
+ */
+class MediaSessionWrapper {
+ private static final String MEDIA_SESSION_TAG = "com.android.tv.mediasession";
+ private static PlaybackState MEDIA_SESSION_STATE_PLAYING = new PlaybackState.Builder()
+ .setState(PlaybackState.STATE_PLAYING, PlaybackState.PLAYBACK_POSITION_UNKNOWN, 1.0f)
+ .build();
+ private static PlaybackState MEDIA_SESSION_STATE_STOPPED = new PlaybackState.Builder()
+ .setState(PlaybackState.STATE_STOPPED, PlaybackState.PLAYBACK_POSITION_UNKNOWN, 0.0f)
+ .build();
+
+ private final Context mContext;
+ private final MediaSession mMediaSession;
+ private int mNowPlayingCardWidth;
+ private int mNowPlayingCardHeight;
+
+ MediaSessionWrapper(Context context) {
+ mContext = context;
+ mMediaSession = new MediaSession(context, MEDIA_SESSION_TAG);
+ mMediaSession.setCallback(new MediaSession.Callback() {
+ @Override
+ public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
+ // Consume the media button event here. Should not send it to other apps.
+ return true;
+ }
+ });
+ mMediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
+ MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
+ mNowPlayingCardWidth = mContext.getResources().getDimensionPixelSize(
+ R.dimen.notif_card_img_max_width);
+ mNowPlayingCardHeight = mContext.getResources().getDimensionPixelSize(
+ R.dimen.notif_card_img_height);
+ }
+
+ /**
+ * Sets playback state.
+ *
+ * @param isPlaying {@code true} if TV is playing, otherwise {@code false}.
+ */
+ void setPlaybackState(boolean isPlaying) {
+ if (isPlaying) {
+ mMediaSession.setActive(true);
+ // setPlaybackState() has to be called after calling setActive(). b/31933276
+ mMediaSession.setPlaybackState(MEDIA_SESSION_STATE_PLAYING);
+ } else if (mMediaSession.isActive()) {
+ mMediaSession.setPlaybackState(MEDIA_SESSION_STATE_STOPPED);
+ mMediaSession.setActive(false);
+ }
+ }
+
+ /**
+ * Updates media session according to the current TV playback status.
+ *
+ * @param blocked {@code true} if the current channel is blocked, either by user settings or
+ * the current program's content ratings.
+ * @param currentChannel The currently playing channel.
+ * @param currentProgram The currently playing program.
+ */
+ void update(boolean blocked, Channel currentChannel, Program currentProgram) {
+ if (currentChannel == null) {
+ setPlaybackState(false);
+ return;
+ }
+
+ // If the channel is blocked, display a lock and a short text on the Now Playing Card
+ if (blocked) {
+ Bitmap art = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.ic_message_lock_preview);
+ updateMediaMetadata(mContext.getResources()
+ .getString(R.string.channel_banner_locked_channel_title), art);
+ setPlaybackState(true);
+ return;
+ }
+
+ String cardTitleText = null;
+ String posterArtUri = null;
+ if (currentProgram != null) {
+ cardTitleText = currentProgram.getTitle();
+ posterArtUri = currentProgram.getPosterArtUri();
+ }
+ if (TextUtils.isEmpty(cardTitleText)) {
+ cardTitleText = getChannelName(currentChannel);
+ }
+ updateMediaMetadata(cardTitleText, null);
+ if (posterArtUri == null) {
+ posterArtUri = TvContract.buildChannelLogoUri(currentChannel.getId()).toString();
+ }
+ updatePosterArt(currentChannel, currentProgram, cardTitleText, null, posterArtUri);
+ setPlaybackState(true);
+ }
+
+ /**
+ * Releases the media session.
+ *
+ * @see MediaSession#release()
+ */
+ void release() {
+ mMediaSession.release();
+ }
+
+ private String getChannelName(Channel channel) {
+ if (channel.isPassthrough()) {
+ TvInputInfo input = TvApplication.getSingletons(mContext).getTvInputManagerHelper()
+ .getTvInputInfo(channel.getInputId());
+ return Utils.loadLabel(mContext, input);
+ } else {
+ return channel.getDisplayName();
+ }
+ }
+
+ private void updatePosterArt(Channel currentChannel, Program currentProgram,
+ String cardTitleText, @Nullable Bitmap posterArt, @Nullable String posterArtUri) {
+ if (posterArt != null) {
+ updateMediaMetadata(cardTitleText, posterArt);
+ } else if (posterArtUri != null) {
+ ImageLoader.loadBitmap(mContext, posterArtUri, mNowPlayingCardWidth,
+ mNowPlayingCardHeight, new ProgramPosterArtCallback(this, currentChannel,
+ currentProgram, cardTitleText));
+ } else {
+ updateMediaMetadata(cardTitleText, R.drawable.default_now_card);
+ }
+ }
+
+ private void updateMediaMetadata(final String title, final Bitmap posterArt) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... arg0) {
+ MediaMetadata.Builder builder = new MediaMetadata.Builder();
+ builder.putString(MediaMetadata.METADATA_KEY_TITLE, title);
+ if (posterArt != null) {
+ builder.putBitmap(MediaMetadata.METADATA_KEY_ART, posterArt);
+ }
+ mMediaSession.setMetadata(builder.build());
+ return null;
+ }
+ }.execute();
+ }
+
+ private void updateMediaMetadata(final String title, final int imageResId) {
+ new AsyncTask<Void, Void, Void> () {
+ @Override
+ protected Void doInBackground(Void... arg0) {
+ MediaMetadata.Builder builder = new MediaMetadata.Builder();
+ builder.putString(MediaMetadata.METADATA_KEY_TITLE, title);
+ Bitmap posterArt =
+ BitmapFactory.decodeResource(mContext.getResources(), imageResId);
+ if (posterArt != null) {
+ builder.putBitmap(MediaMetadata.METADATA_KEY_ART, posterArt);
+ }
+ mMediaSession.setMetadata(builder.build());
+ return null;
+ }
+ }.execute();
+ }
+
+ private static class ProgramPosterArtCallback extends
+ ImageLoader.ImageLoaderCallback<MediaSessionWrapper> {
+ private final Channel mChannel;
+ private final Program mProgram;
+ private final String mCardTitleText;
+
+ ProgramPosterArtCallback(MediaSessionWrapper sessionWrapper, Channel channel,
+ Program program, String cardTitleText) {
+ super(sessionWrapper);
+ mChannel = channel;
+ mProgram = program;
+ mCardTitleText = cardTitleText;
+ }
+
+ @Override
+ public void onBitmapLoaded(MediaSessionWrapper sessionWrapper, @Nullable Bitmap posterArt) {
+ if (((MainActivity) sessionWrapper.mContext).isNowPlayingProgram(mChannel, mProgram)) {
+ sessionWrapper.updatePosterArt(mChannel, mProgram, mCardTitleText, posterArt, null);
+ }
+ }
+ }
+}
diff --git a/src/com/android/tv/SetupPassthroughActivity.java b/src/com/android/tv/SetupPassthroughActivity.java
index 8a263a26..f0f54413 100644
--- a/src/com/android/tv/SetupPassthroughActivity.java
+++ b/src/com/android/tv/SetupPassthroughActivity.java
@@ -18,19 +18,27 @@ package com.android.tv;
import android.app.Activity;
import android.content.ActivityNotFoundException;
+import android.content.Context;
import android.content.Intent;
import android.media.tv.TvInputInfo;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.MainThread;
import android.util.Log;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.TvCommonConstants;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.ChannelDataManager.Listener;
import com.android.tv.data.epg.EpgFetcher;
import com.android.tv.experiments.Experiments;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
+import java.util.concurrent.TimeUnit;
+
/**
* An activity to launch a TV input setup activity.
*
@@ -42,66 +50,83 @@ public class SetupPassthroughActivity extends Activity {
private static final int REQUEST_START_SETUP_ACTIVITY = 200;
+ private static ScanTimeoutMonitor sScanTimeoutMonitor;
+
private TvInputInfo mTvInputInfo;
private Intent mActivityAfterCompletion;
+ private boolean mEpgFetcherDuringScan;
@Override
public void onCreate(Bundle savedInstanceState) {
+ if (DEBUG) Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
- Intent intent = getIntent();
- SoftPreconditions.checkState(
- intent.getAction().equals(TvCommonConstants.INTENT_ACTION_INPUT_SETUP));
ApplicationSingletons appSingletons = TvApplication.getSingletons(this);
TvInputManagerHelper inputManager = appSingletons.getTvInputManagerHelper();
+ Intent intent = getIntent();
String inputId = intent.getStringExtra(TvCommonConstants.EXTRA_INPUT_ID);
mTvInputInfo = inputManager.getTvInputInfo(inputId);
- if (DEBUG) Log.d(TAG, "TvInputId " + inputId + " / TvInputInfo " + mTvInputInfo);
- if (mTvInputInfo == null) {
- Log.w(TAG, "There is no input with the ID " + inputId + ".");
- finish();
- return;
- }
- Intent setupIntent = intent.getExtras().getParcelable(TvCommonConstants.EXTRA_SETUP_INTENT);
- if (DEBUG) Log.d(TAG, "Setup activity launch intent: " + setupIntent);
- if (setupIntent == null) {
- Log.w(TAG, "The input (" + mTvInputInfo.getId() + ") doesn't have setup.");
- finish();
- return;
- }
- SetupUtils.grantEpgPermission(this, mTvInputInfo.getServiceInfo().packageName);
mActivityAfterCompletion = intent.getParcelableExtra(
TvCommonConstants.EXTRA_ACTIVITY_AFTER_COMPLETION);
- if (DEBUG) Log.d(TAG, "Activity after completion " + mActivityAfterCompletion);
- // If EXTRA_SETUP_INTENT is not removed, an infinite recursion happens during
- // setupIntent.putExtras(intent.getExtras()).
- Bundle extras = intent.getExtras();
- extras.remove(TvCommonConstants.EXTRA_SETUP_INTENT);
- setupIntent.putExtras(extras);
- try {
- startActivityForResult(setupIntent, REQUEST_START_SETUP_ACTIVITY);
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "Can't find activity: " + setupIntent.getComponent());
- finish();
- return;
- }
- if (Utils.isInternalTvInput(this, mTvInputInfo.getId()) && Experiments.CLOUD_EPG.get()) {
- EpgFetcher.getInstance(this).stop();
+ boolean needToFetchEpg = Utils.isInternalTvInput(this, mTvInputInfo.getId())
+ && Experiments.CLOUD_EPG.get();
+ if (needToFetchEpg) {
+ // In case when the activity is restored, this flag should be restored as well.
+ mEpgFetcherDuringScan = true;
}
- }
-
- @Override
- protected void onDestroy() {
- if (mTvInputInfo != null && Utils.isInternalTvInput(this, mTvInputInfo.getId())
- && Experiments.CLOUD_EPG.get()) {
- EpgFetcher.getInstance(this).start();
+ if (savedInstanceState == null) {
+ SoftPreconditions.checkState(
+ intent.getAction().equals(TvCommonConstants.INTENT_ACTION_INPUT_SETUP));
+ if (DEBUG) Log.d(TAG, "TvInputId " + inputId + " / TvInputInfo " + mTvInputInfo);
+ if (mTvInputInfo == null) {
+ Log.w(TAG, "There is no input with the ID " + inputId + ".");
+ finish();
+ return;
+ }
+ Intent setupIntent =
+ intent.getExtras().getParcelable(TvCommonConstants.EXTRA_SETUP_INTENT);
+ if (DEBUG) Log.d(TAG, "Setup activity launch intent: " + setupIntent);
+ if (setupIntent == null) {
+ Log.w(TAG, "The input (" + mTvInputInfo.getId() + ") doesn't have setup.");
+ finish();
+ return;
+ }
+ SetupUtils.grantEpgPermission(this, mTvInputInfo.getServiceInfo().packageName);
+ if (DEBUG) Log.d(TAG, "Activity after completion " + mActivityAfterCompletion);
+ // If EXTRA_SETUP_INTENT is not removed, an infinite recursion happens during
+ // setupIntent.putExtras(intent.getExtras()).
+ Bundle extras = intent.getExtras();
+ extras.remove(TvCommonConstants.EXTRA_SETUP_INTENT);
+ setupIntent.putExtras(extras);
+ try {
+ startActivityForResult(setupIntent, REQUEST_START_SETUP_ACTIVITY);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "Can't find activity: " + setupIntent.getComponent());
+ finish();
+ return;
+ }
+ if (needToFetchEpg) {
+ if (sScanTimeoutMonitor == null) {
+ sScanTimeoutMonitor = new ScanTimeoutMonitor(this);
+ }
+ sScanTimeoutMonitor.startMonitoring();
+ EpgFetcher.getInstance(this).onChannelScanStarted();
+ }
}
- super.onDestroy();
}
@Override
public void onActivityResult(int requestCode, final int resultCode, final Intent data) {
+ if (DEBUG) Log.d(TAG, "onActivityResult");
+ if (sScanTimeoutMonitor != null) {
+ sScanTimeoutMonitor.stopMonitoring();
+ }
+ // Note: It's not guaranteed that this method is always called after scanning.
boolean setupComplete = requestCode == REQUEST_START_SETUP_ACTIVITY
&& resultCode == Activity.RESULT_OK;
+ // Tells EpgFetcher that channel source setup is finished.
+ if (mEpgFetcherDuringScan) {
+ EpgFetcher.getInstance(this).onChannelScanFinished();
+ }
if (!setupComplete) {
setResult(resultCode, data);
finish();
@@ -122,4 +147,75 @@ public class SetupPassthroughActivity extends Activity {
}
});
}
+
+ /**
+ * Monitors the scan progress and notifies the timeout of the scanning.
+ * The purpose of this monitor is to call EpgFetcher.onChannelScanFinished() in case when
+ * SetupPassthroughActivity.onActivityResult() is not called properly. b/36008534
+ */
+ @MainThread
+ private static class ScanTimeoutMonitor {
+ // Set timeout long enough. The message in Sony TV says the scanning takes about 30 minutes.
+ private static final long SCAN_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(30);
+
+ private final Context mContext;
+ private final ChannelDataManager mChannelDataManager;
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+ private final Runnable mScanTimeoutRunnable = new Runnable() {
+ @Override
+ public void run() {
+ Log.w(TAG, "No channels has been added for a while." +
+ " The scan might have finished unexpectedly.");
+ onScanTimedOut();
+ }
+ };
+ private final Listener mChannelDataManagerListener = new Listener() {
+ @Override
+ public void onLoadFinished() {
+ setupTimer();
+ }
+
+ @Override
+ public void onChannelListUpdated() {
+ setupTimer();
+ }
+
+ @Override
+ public void onChannelBrowsableChanged() { }
+ };
+ private boolean mStarted;
+
+ private ScanTimeoutMonitor(Context context) {
+ mContext = context.getApplicationContext();
+ mChannelDataManager = TvApplication.getSingletons(context).getChannelDataManager();
+ }
+
+ private void startMonitoring() {
+ if (!mStarted) {
+ mStarted = true;
+ mChannelDataManager.addListener(mChannelDataManagerListener);
+ }
+ if (mChannelDataManager.isDbLoadFinished()) {
+ setupTimer();
+ }
+ }
+
+ private void stopMonitoring() {
+ if (mStarted) {
+ mStarted = false;
+ mHandler.removeCallbacks(mScanTimeoutRunnable);
+ mChannelDataManager.removeListener(mChannelDataManagerListener);
+ }
+ }
+
+ private void setupTimer() {
+ mHandler.removeCallbacks(mScanTimeoutRunnable);
+ mHandler.postDelayed(mScanTimeoutRunnable, SCAN_TIMEOUT_MS);
+ }
+
+ private void onScanTimedOut() {
+ stopMonitoring();
+ EpgFetcher.getInstance(mContext).onChannelScanFinished();
+ }
+ }
}
diff --git a/src/com/android/tv/TimeShiftManager.java b/src/com/android/tv/TimeShiftManager.java
index 2d6d45c4..70885936 100644
--- a/src/com/android/tv/TimeShiftManager.java
+++ b/src/com/android/tv/TimeShiftManager.java
@@ -161,7 +161,6 @@ public class TimeShiftManager {
@TimeShiftActionId
private int mLastActionId = 0;
- // TODO: Remove these variables once API level 23 is available.
private final Context mContext;
private Program mCurrentProgram;
@@ -618,6 +617,15 @@ public class TimeShiftManager {
+ mAvailablityChangedTimeMs);
return;
}
+ if (recordStartTimeMs > System.currentTimeMillis()) {
+ // The time reported by TvInputService might not consistent with system
+ // clock,, use system's current time instead.
+ Log.e(TAG, "The start time should not be earlier than the current time, "
+ + "reset the start time to the system's current time: {"
+ + "startTime: " + recordStartTimeMs + ", current time: "
+ + System.currentTimeMillis());
+ recordStartTimeMs = System.currentTimeMillis();
+ }
if (mRecordStartTimeMs == recordStartTimeMs) {
return;
}
@@ -887,10 +895,12 @@ public class TimeShiftManager {
}
long fetchStartTimeMs = Utils.floorTime(startTimeMs, MAX_DUMMY_PROGRAM_DURATION);
- boolean needToLoad = addDummyPrograms(fetchStartTimeMs,
- endTimeMs + PREFETCH_DURATION_FOR_NEXT);
+ long fetchEndTimeMs = Utils.ceilTime(endTimeMs + PREFETCH_DURATION_FOR_NEXT,
+ MAX_DUMMY_PROGRAM_DURATION);
+ removeOutdatedPrograms(fetchStartTimeMs);
+ boolean needToLoad = addDummyPrograms(fetchStartTimeMs, fetchEndTimeMs);
if (needToLoad) {
- Range<Long> period = Range.create(fetchStartTimeMs, endTimeMs);
+ Range<Long> period = Range.create(fetchStartTimeMs, fetchEndTimeMs);
mProgramLoadQueue.add(period);
startTaskIfNeeded();
}
@@ -996,6 +1006,12 @@ public class TimeShiftManager {
return added;
}
+ private void removeOutdatedPrograms(long startTimeMs) {
+ while (mPrograms.size() > 0 && mPrograms.get(0).getEndTimeUtcMillis() <= startTimeMs) {
+ mPrograms.remove(0);
+ }
+ }
+
private void removeDummyPrograms() {
for (Iterator<Program> it = mPrograms.listIterator(); it.hasNext(); ) {
if (!it.next().isValid()) {
@@ -1012,7 +1028,7 @@ public class TimeShiftManager {
for (int i = 0, j = 0; i < mPrograms.size() && j < loadedPrograms.size(); ++j) {
Program loadedProgram = loadedPrograms.get(j);
// Skip previous programs.
- while (program.getEndTimeUtcMillis() < loadedProgram.getStartTimeUtcMillis()) {
+ while (program.getEndTimeUtcMillis() <= loadedProgram.getStartTimeUtcMillis()) {
// Reached end of mPrograms.
if (++i == mPrograms.size()) {
return;
diff --git a/src/com/android/tv/TvApplication.java b/src/com/android/tv/TvApplication.java
index 0e18a259..0c7c0fd1 100644
--- a/src/com/android/tv/TvApplication.java
+++ b/src/com/android/tv/TvApplication.java
@@ -22,16 +22,20 @@ import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputManager.TvInputCallback;
+import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
@@ -49,19 +53,30 @@ import com.android.tv.common.ui.setup.animation.SetupAnimationHelper;
import com.android.tv.config.DefaultConfigManager;
import com.android.tv.config.RemoteConfig;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.PreviewDataManager;
import com.android.tv.data.ProgramDataManager;
+import com.android.tv.data.epg.EpgFetcher;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManagerImpl;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrRecordingService;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.DvrStorageStatusManager;
import com.android.tv.dvr.DvrWatchedPositionManager;
+import com.android.tv.dvr.recorder.RecordingScheduler;
+import com.android.tv.perf.EventNames;
+import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.perf.StubPerformanceMonitor;
+import com.android.tv.perf.TimerEvent;
+import com.android.tv.recommendation.ChannelPreviewUpdater;
+import com.android.tv.recommendation.RecordedProgramPreviewUpdater;
+import com.android.tv.tuner.TunerInputController;
import com.android.tv.tuner.TunerPreferences;
import com.android.tv.tuner.tvinput.TunerTvInputService;
import com.android.tv.tuner.util.TunerInputInfoUtils;
import com.android.tv.util.AccountHelper;
import com.android.tv.util.Clock;
+import com.android.tv.util.Debug;
+import com.android.tv.util.PermissionUtils;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.SystemProperties;
import com.android.tv.util.TvInputManagerHelper;
@@ -72,17 +87,25 @@ import java.util.List;
public class TvApplication extends Application implements ApplicationSingletons {
private static final String TAG = "TvApplication";
private static final boolean DEBUG = false;
- private RemoteConfig mRemoteConfig;
+ private static final TimerEvent sAppStartTimer = StubPerformanceMonitor.startBootstrapTimer();
+
+ /**
+ * An instance of {@link ApplicationSingletons}. Note that this can be set directly only for the
+ * test purpose.
+ */
+ @VisibleForTesting
+ public static ApplicationSingletons sAppSingletons;
/**
* Broadcast Action: The user has updated LC to a new version that supports tuner input.
- * {@link TunerInputController} will recevice this intent to check the existence of tuner
- * input when the new version is first launched.
+ * {@link com.android.tv.tuner.TunerInputController} will recevice this intent to check
+ * the existence of tuner input when the new version is first launched.
*/
public static final String ACTION_APPLICATION_FIRST_LAUNCHED =
"com.android.tv.action.APPLICATION_FIRST_LAUNCHED";
private static final String PREFERENCE_IS_FIRST_LAUNCH = "is_first_launch";
+ private RemoteConfig mRemoteConfig;
private String mVersionName = "";
private final MainActivityWrapper mMainActivityWrapper = new MainActivityWrapper();
@@ -92,21 +115,30 @@ public class TvApplication extends Application implements ApplicationSingletons
private Tracker mTracker;
private TvInputManagerHelper mTvInputManagerHelper;
private ChannelDataManager mChannelDataManager;
- private ProgramDataManager mProgramDataManager;
+ private volatile ProgramDataManager mProgramDataManager;
+ private PreviewDataManager mPreviewDataManager;
private DvrManager mDvrManager;
private DvrScheduleManager mDvrScheduleManager;
private DvrDataManager mDvrDataManager;
private DvrStorageStatusManager mDvrStorageStatusManager;
private DvrWatchedPositionManager mDvrWatchedPositionManager;
+ private RecordingScheduler mRecordingScheduler;
@Nullable
private InputSessionManager mInputSessionManager;
private AccountHelper mAccountHelper;
// When this variable is null, we don't know in which process TvApplication runs.
private Boolean mRunningInMainProcess;
+ private PerformanceMonitor mPerformanceMonitor;
@Override
public void onCreate() {
super.onCreate();
+ if (!PermissionUtils.hasInternet(this)) {
+ // When an isolated process starts, just skip all the initialization.
+ return;
+ }
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).start();
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log("Start TvApplication.onCreate");
SharedPreferencesUtils.initialize(this, new Runnable() {
@Override
public void run() {
@@ -127,18 +159,15 @@ public class TvApplication extends Application implements ApplicationSingletons
}
Log.i(TAG, "Starting Live TV " + getVersionName());
-
// Only set StrictMode for ENG builds because the build server only produces userdebug
// builds.
if (BuildConfig.ENG && SystemProperties.ALLOW_STRICT_MODE.getValue()) {
StrictMode.ThreadPolicy.Builder threadPolicyBuilder =
new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog();
StrictMode.VmPolicy.Builder vmPolicyBuilder =
- new StrictMode.VmPolicy.Builder().detectAll().penaltyLog();
+ new StrictMode.VmPolicy.Builder().detectAll().penaltyDeath();
if (!TvCommonUtils.isRunningInTest()) {
threadPolicyBuilder.penaltyDialog();
- // Turn off death penalty for tests b/23355898
- vmPolicyBuilder.penaltyDeath();
}
StrictMode.setThreadPolicy(threadPolicyBuilder.build());
StrictMode.setVmPolicy(vmPolicyBuilder.build());
@@ -149,13 +178,16 @@ public class TvApplication extends Application implements ApplicationSingletons
mAnalytics = StubAnalytics.getInstance(this);
}
mTracker = mAnalytics.getDefaultTracker();
- mTvInputManagerHelper = new TvInputManagerHelper(this);
- mTvInputManagerHelper.start();
+ getTvInputManagerHelper();
// In SetupFragment, transitions are set in the constructor. Because the fragment can be
// created in Activity.onCreate() by the framework, SetupAnimationHelper should be
// initialized here before Activity.onCreate() is called.
SetupAnimationHelper.initialize(this);
+
+
Log.i(TAG, "Started Live TV " + mVersionName);
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log("finish TvApplication.onCreate");
+ getPerformanceMonitor().stopTimer(sAppStartTimer, EventNames.APPLICATION_ONCREATE);
}
private void setCurrentRunningProcess(boolean isMainProcess) {
@@ -163,12 +195,22 @@ public class TvApplication extends Application implements ApplicationSingletons
SoftPreconditions.checkState(isMainProcess == mRunningInMainProcess);
return;
}
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
+ "start TvApplication.setCurrentRunningProcess");
mRunningInMainProcess = isMainProcess;
if (CommonFeatures.DVR.isEnabled(this)) {
mDvrStorageStatusManager = new DvrStorageStatusManager(this, mRunningInMainProcess);
}
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ // Fetch remote config
+ getRemoteConfig().fetch(null);
+ return null;
+ }
+ }.execute();
if (mRunningInMainProcess) {
- mTvInputManagerHelper.addCallback(new TvInputCallback() {
+ getTvInputManagerHelper().addCallback(new TvInputCallback() {
@Override
public void onInputAdded(String inputId) {
if (Features.TUNER.isEnabled(TvApplication.this) && TextUtils.equals(inputId,
@@ -186,15 +228,22 @@ public class TvApplication extends Application implements ApplicationSingletons
if (Features.TUNER.isEnabled(this)) {
// If the tuner input service is added before the app is started, we need to
// handle it here.
- TunerInputInfoUtils.updateTunerInputInfo(this);
+ TunerInputInfoUtils.updateTunerInputInfo(TvApplication.this);
}
if (CommonFeatures.DVR.isEnabled(this)) {
mDvrScheduleManager = new DvrScheduleManager(this);
mDvrManager = new DvrManager(this);
- //NOTE: DvrRecordingService just keeps running.
- DvrRecordingService.startService(this);
+ mRecordingScheduler = RecordingScheduler.createScheduler(this);
+ }
+ EpgFetcher.getInstance(this).startRoutineService();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ ChannelPreviewUpdater.getInstance(this).startRoutineService();
+ RecordedProgramPreviewUpdater.getInstance(this)
+ .updatePreviewDataForRecordedPrograms();
}
}
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
+ "finish TvApplication.setCurrentRunningProcess");
}
private void checkTunerServiceOnFirstLaunch() {
@@ -203,7 +252,7 @@ public class TvApplication extends Application implements ApplicationSingletons
boolean isFirstLaunch = sharedPreferences.getBoolean(PREFERENCE_IS_FIRST_LAUNCH, true);
if (isFirstLaunch) {
if (DEBUG) Log.d(TAG, "Congratulations, it's the first launch!");
- sendBroadcast(new Intent(ACTION_APPLICATION_FIRST_LAUNCHED));
+ TunerInputController.onCheckingUsbTunerStatus(this, ACTION_APPLICATION_FIRST_LAUNCHED);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(PREFERENCE_IS_FIRST_LAUNCH, false);
editor.apply();
@@ -227,6 +276,15 @@ public class TvApplication extends Application implements ApplicationSingletons
}
/**
+ * Returns the {@link RecordingScheduler}.
+ */
+ @Override
+ @Nullable
+ public RecordingScheduler getRecordingScheduler() {
+ return mRecordingScheduler;
+ }
+
+ /**
* Returns the {@link DvrWatchedPositionManager}.
*/
@Override
@@ -268,24 +326,55 @@ public class TvApplication extends Application implements ApplicationSingletons
@Override
public ChannelDataManager getChannelDataManager() {
if (mChannelDataManager == null) {
- mChannelDataManager = new ChannelDataManager(this, mTvInputManagerHelper);
+ mChannelDataManager = new ChannelDataManager(this, getTvInputManagerHelper());
mChannelDataManager.start();
}
return mChannelDataManager;
}
+ @Override
+ public boolean isChannelDataManagerLoadFinished() {
+ return mChannelDataManager != null && mChannelDataManager.isDbLoadFinished();
+ }
+
/**
* Returns {@link ProgramDataManager}.
*/
@Override
public ProgramDataManager getProgramDataManager() {
- if (mProgramDataManager == null) {
- mProgramDataManager = new ProgramDataManager(this);
- mProgramDataManager.start();
+ if (mProgramDataManager != null) {
+ return mProgramDataManager;
}
+ Utils.runInMainThreadAndWait(new Runnable() {
+ @Override
+ public void run() {
+ if (mProgramDataManager == null) {
+ mProgramDataManager = new ProgramDataManager(TvApplication.this);
+ mProgramDataManager.start();
+ }
+ }
+ });
return mProgramDataManager;
}
+ @Override
+ public boolean isProgramDataManagerCurrentProgramsLoadFinished() {
+ return mProgramDataManager != null && mProgramDataManager.isCurrentProgramsLoadFinished();
+ }
+
+ /**
+ * Returns {@link PreviewDataManager}.
+ */
+ @TargetApi(Build.VERSION_CODES.O)
+ @Override
+ public PreviewDataManager getPreviewDataManager() {
+ if (mPreviewDataManager == null) {
+ mPreviewDataManager = new PreviewDataManager(this);
+ mPreviewDataManager.start();
+ }
+ return mPreviewDataManager;
+ }
+
/**
* Returns {@link DvrDataManager}.
*/
@@ -314,6 +403,10 @@ public class TvApplication extends Application implements ApplicationSingletons
*/
@Override
public TvInputManagerHelper getTvInputManagerHelper() {
+ if (mTvInputManagerHelper == null) {
+ mTvInputManagerHelper = new TvInputManagerHelper(this);
+ mTvInputManagerHelper.start();
+ }
return mTvInputManagerHelper;
}
@@ -345,6 +438,19 @@ public class TvApplication extends Application implements ApplicationSingletons
return mRemoteConfig;
}
+ @Override
+ public boolean isRunningInMainProcess() {
+ return mRunningInMainProcess != null && mRunningInMainProcess;
+ }
+
+ @Override
+ public PerformanceMonitor getPerformanceMonitor() {
+ if (mPerformanceMonitor == null) {
+ mPerformanceMonitor = StubPerformanceMonitor.initialize(this);
+ }
+ return mPerformanceMonitor;
+ }
+
/**
* SelectInputActivity is set in {@link SelectInputActivity#onCreate} and cleared in
* {@link SelectInputActivity#onDestroy}.
@@ -353,6 +459,14 @@ public class TvApplication extends Application implements ApplicationSingletons
mSelectInputActivity = activity;
}
+ public void handleGuideKey() {
+ if (!mMainActivityWrapper.isResumed()) {
+ startActivity(new Intent(Intent.ACTION_VIEW, TvContract.Programs.CONTENT_URI));
+ } else {
+ mMainActivityWrapper.getMainActivity().getOverlayManager().toggleProgramGuide();
+ }
+ }
+
/**
* Handles the global key KEYCODE_TV.
*/
@@ -471,6 +585,7 @@ public class TvApplication extends Application implements ApplicationSingletons
if (packageManager.getComponentEnabledSetting(name) != newState) {
packageManager.setComponentEnabledSetting(name, newState,
dontKillApp ? PackageManager.DONT_KILL_APP : 0);
+ Log.i(TAG, (enable ? "Un-hide" : "Hide") + " Live TV.");
}
SetupUtils.getInstance(TvApplication.this).onInputListUpdated(inputManager);
}
@@ -479,7 +594,11 @@ public class TvApplication extends Application implements ApplicationSingletons
* Returns the @{@link ApplicationSingletons} using the application context.
*/
public static ApplicationSingletons getSingletons(Context context) {
- return (ApplicationSingletons) context.getApplicationContext();
+ // No need to be "synchronized" because this doesn't create any instance.
+ if (sAppSingletons == null) {
+ sAppSingletons = (ApplicationSingletons) context.getApplicationContext();
+ }
+ return sAppSingletons;
}
/**
@@ -491,6 +610,7 @@ public class TvApplication extends Application implements ApplicationSingletons
* specific initializations.
*/
public static void setCurrentRunningProcess(Context context, boolean isMainProcess) {
+ // TODO(b/63064354) TvApplication should not have to know if it is "the main process"
if (context.getApplicationContext() instanceof TvApplication) {
TvApplication tvApplication = (TvApplication) context.getApplicationContext();
tvApplication.setCurrentRunningProcess(isMainProcess);
diff --git a/src/com/android/tv/TvOptionsManager.java b/src/com/android/tv/TvOptionsManager.java
index 7871cbe7..493e039c 100644
--- a/src/com/android/tv/TvOptionsManager.java
+++ b/src/com/android/tv/TvOptionsManager.java
@@ -18,14 +18,13 @@ package com.android.tv;
import android.content.Context;
import android.media.tv.TvTrackInfo;
+import android.support.annotation.IntDef;
import android.util.SparseArray;
import com.android.tv.data.DisplayMode;
-import com.android.tv.util.TvSettings;
-import com.android.tv.util.TvSettings.PipLayout;
-import com.android.tv.util.TvSettings.PipSize;
-import com.android.tv.util.TvSettings.PipSound;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Locale;
/**
@@ -33,39 +32,34 @@ import java.util.Locale;
* captions and display mode. Can be also used to create MenuAction items to control such options.
*/
public class TvOptionsManager {
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({OPTION_CLOSED_CAPTIONS, OPTION_DISPLAY_MODE, OPTION_SYSTEMWIDE_PIP, OPTION_MULTI_AUDIO,
+ OPTION_MORE_CHANNELS, OPTION_DEVELOPER, OPTION_SETTINGS})
+ public @interface OptionType {}
public static final int OPTION_CLOSED_CAPTIONS = 0;
public static final int OPTION_DISPLAY_MODE = 1;
- public static final int OPTION_IN_APP_PIP = 2;
- public static final int OPTION_SYSTEMWIDE_PIP = 3;
- public static final int OPTION_MULTI_AUDIO = 4;
- public static final int OPTION_MORE_CHANNELS = 5;
- public static final int OPTION_DEVELOPER = 6;
- public static final int OPTION_SETTINGS = 7;
-
- public static final int OPTION_PIP_INPUT = 100;
- public static final int OPTION_PIP_SWAP = 101;
- public static final int OPTION_PIP_SOUND = 102;
- public static final int OPTION_PIP_LAYOUT = 103 ;
- public static final int OPTION_PIP_SIZE = 104;
+ public static final int OPTION_SYSTEMWIDE_PIP = 2;
+ public static final int OPTION_MULTI_AUDIO = 3;
+ public static final int OPTION_MORE_CHANNELS = 4;
+ public static final int OPTION_DEVELOPER = 5;
+ public static final int OPTION_SETTINGS = 6;
private final Context mContext;
private final SparseArray<OptionChangedListener> mOptionChangedListeners = new SparseArray<>();
private String mClosedCaptionsLanguage;
private int mDisplayMode;
- private boolean mPip;
private String mMultiAudio;
- private String mPipInput;
- private boolean mPipSwap;
- @PipSound private int mPipSound;
- @PipLayout private int mPipLayout;
- @PipSize private int mPipSize;
public TvOptionsManager(Context context) {
mContext = context;
}
- public String getOptionString(int option) {
+ /**
+ * Returns a suitable displayed string for the given option type under current settings.
+ * @param option the type of option, should be one of {@link OptionType}.
+ */
+ public String getOptionString(@OptionType int option) {
switch (option) {
case OPTION_CLOSED_CAPTIONS:
if (mClosedCaptionsLanguage == null) {
@@ -77,101 +71,48 @@ public class TvOptionsManager {
.isDisplayModeAvailable(mDisplayMode)
? DisplayMode.getLabel(mDisplayMode, mContext)
: DisplayMode.getLabel(DisplayMode.MODE_NORMAL, mContext);
- case OPTION_IN_APP_PIP:
- return mContext.getString(
- mPip ? R.string.options_item_pip_on : R.string.options_item_pip_off);
case OPTION_MULTI_AUDIO:
return mMultiAudio;
- case OPTION_PIP_INPUT:
- return mPipInput;
- case OPTION_PIP_SWAP:
- return mContext.getString(mPipSwap ? R.string.pip_options_item_swap_on
- : R.string.pip_options_item_swap_off);
- case OPTION_PIP_SOUND:
- if (mPipSound == TvSettings.PIP_SOUND_MAIN) {
- return mContext.getString(R.string.pip_options_item_sound_main);
- } else if (mPipSound == TvSettings.PIP_SOUND_PIP_WINDOW) {
- return mContext.getString(R.string.pip_options_item_sound_pip_window);
- }
- break;
- case OPTION_PIP_LAYOUT:
- if (mPipLayout == TvSettings.PIP_LAYOUT_BOTTOM_RIGHT) {
- return mContext.getString(R.string.pip_options_item_layout_bottom_right);
- } else if (mPipLayout == TvSettings.PIP_LAYOUT_TOP_RIGHT) {
- return mContext.getString(R.string.pip_options_item_layout_top_right);
- } else if (mPipLayout == TvSettings.PIP_LAYOUT_TOP_LEFT) {
- return mContext.getString(R.string.pip_options_item_layout_top_left);
- } else if (mPipLayout == TvSettings.PIP_LAYOUT_BOTTOM_LEFT) {
- return mContext.getString(R.string.pip_options_item_layout_bottom_left);
- } else if (mPipLayout == TvSettings.PIP_LAYOUT_SIDE_BY_SIDE) {
- return mContext.getString(R.string.pip_options_item_layout_side_by_side);
- }
- break;
- case OPTION_PIP_SIZE:
- if (mPipSize == TvSettings.PIP_SIZE_BIG) {
- return mContext.getString(R.string.pip_options_item_size_big);
- } else if (mPipSize == TvSettings.PIP_SIZE_SMALL) {
- return mContext.getString(R.string.pip_options_item_size_small);
- }
- break;
}
return "";
}
- public void onClosedCaptionsChanged(TvTrackInfo track) {
- mClosedCaptionsLanguage = (track == null) ? null
- : (track.getLanguage() != null) ? track.getLanguage()
- : mContext.getString(R.string.default_language);
+ /**
+ * Handles changing selection of closed caption.
+ */
+ public void onClosedCaptionsChanged(TvTrackInfo track, int trackIndex) {
+ mClosedCaptionsLanguage = (track == null) ?
+ null : (track.getLanguage() != null) ? track.getLanguage()
+ : mContext.getString(R.string.closed_caption_unknown_language, trackIndex + 1);
notifyOptionChanged(OPTION_CLOSED_CAPTIONS);
}
+ /**
+ * Handles changing selection of display mode.
+ */
public void onDisplayModeChanged(int displayMode) {
mDisplayMode = displayMode;
notifyOptionChanged(OPTION_DISPLAY_MODE);
}
- public void onPipChanged(boolean pip) {
- mPip = pip;
- notifyOptionChanged(OPTION_IN_APP_PIP);
- }
-
+ /**
+ * Handles changing selection of multi-audio.
+ */
public void onMultiAudioChanged(String multiAudio) {
mMultiAudio = multiAudio;
notifyOptionChanged(OPTION_MULTI_AUDIO);
}
- public void onPipInputChanged(String pipInput) {
- mPipInput = pipInput;
- notifyOptionChanged(OPTION_PIP_INPUT);
- }
-
- public void onPipSwapChanged(boolean pipSwap) {
- mPipSwap = pipSwap;
- notifyOptionChanged(OPTION_PIP_SWAP);
- }
-
- public void onPipSoundChanged(@PipSound int pipSound) {
- mPipSound = pipSound;
- notifyOptionChanged(OPTION_PIP_SOUND);
- }
-
- public void onPipLayoutChanged(@PipLayout int pipLayout) {
- mPipLayout = pipLayout;
- notifyOptionChanged(OPTION_PIP_LAYOUT);
- }
-
- public void onPipSizeChanged(@PipSize int pipSize) {
- mPipSize = pipSize;
- notifyOptionChanged(OPTION_PIP_SIZE);
- }
-
- private void notifyOptionChanged(int option) {
+ private void notifyOptionChanged(@OptionType int option) {
OptionChangedListener listener = mOptionChangedListeners.get(option);
if (listener != null) {
- listener.onOptionChanged(getOptionString(option));
+ listener.onOptionChanged(option, getOptionString(option));
}
}
+ /**
+ * Sets listeners to changes of the given option type.
+ */
public void setOptionChangedListener(int option, OptionChangedListener listener) {
mOptionChangedListeners.put(option, listener);
}
@@ -180,6 +121,6 @@ public class TvOptionsManager {
* An interface used to monitor option changes.
*/
public interface OptionChangedListener {
- void onOptionChanged(String newOption);
+ void onOptionChanged(@OptionType int optionType, String newString);
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/analytics/DurationTimer.java b/src/com/android/tv/analytics/DurationTimer.java
deleted file mode 100644
index ad2d91f8..00000000
--- a/src/com/android/tv/analytics/DurationTimer.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.analytics;
-
-import android.os.SystemClock;
-
-/**
- * Times a duration.
- */
-public final class DurationTimer {
- public static final long TIME_NOT_SET = -1;
-
- private long startTimeMs = TIME_NOT_SET;
-
- /**
- * Returns true if the timer is running.
- */
- public boolean isRunning() {
- return startTimeMs != TIME_NOT_SET;
- }
-
- /**
- * Start the timer.
- */
- public void start() {
- startTimeMs = SystemClock.elapsedRealtime();
- }
-
- /**
- * Returns the current duration in milliseconds or {@link #TIME_NOT_SET} if the timer is not
- * running.
- */
- public long getDuration() {
- return isRunning() ? SystemClock.elapsedRealtime() - startTimeMs : TIME_NOT_SET;
- }
-
- /**
- * Stops the timer and resets its value to {@link #TIME_NOT_SET}.
- *
- * @return the current duration in milliseconds or {@link #TIME_NOT_SET} if the timer is not
- * running.
- */
- public long reset() {
- long duration = getDuration();
- startTimeMs = TIME_NOT_SET;
- return duration;
- }
-}
diff --git a/src/com/android/tv/config/DefaultConfigManager.java b/src/com/android/tv/config/DefaultConfigManager.java
index f5a6e959..bbabc6d4 100644
--- a/src/com/android/tv/config/DefaultConfigManager.java
+++ b/src/com/android/tv/config/DefaultConfigManager.java
@@ -22,6 +22,7 @@ import android.content.Context;
* Stub Remote Config.
*/
public class DefaultConfigManager {
+ public static final long DEFAULT_LONG_VALUE = 0;
public static DefaultConfigManager createInstance(Context context) {
return new DefaultConfigManager();
}
@@ -47,6 +48,11 @@ public class DefaultConfigManager {
public boolean getBoolean(String key) {
return false;
}
+
+ @Override
+ public long getLong(String key) {
+ return DEFAULT_LONG_VALUE;
+ }
}
}
diff --git a/src/com/android/tv/config/RemoteConfig.java b/src/com/android/tv/config/RemoteConfig.java
index 0f7d2c53..f7ae87e7 100644
--- a/src/com/android/tv/config/RemoteConfig.java
+++ b/src/com/android/tv/config/RemoteConfig.java
@@ -45,4 +45,7 @@ public interface RemoteConfig {
* Gets value as a boolean corresponding to the specified key.
*/
boolean getBoolean(String key);
+
+ /** Gets value as a long corresponding to the specified key. */
+ long getLong(String key);
}
diff --git a/src/com/android/tv/config/RemoteConfigUtils.java b/src/com/android/tv/config/RemoteConfigUtils.java
new file mode 100644
index 00000000..09d85239
--- /dev/null
+++ b/src/com/android/tv/config/RemoteConfigUtils.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 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.tv.config;
+
+import android.content.Context;
+import android.util.Log;
+import com.android.tv.TvApplication;
+
+/** A utility class to get the remote config. */
+public class RemoteConfigUtils {
+ private static final String TAG = "RemoteConfigUtils";
+ private static final boolean DEBUG = false;
+
+ private RemoteConfigUtils() {}
+
+ public static long getRemoteConfig(Context context, String key, long defaultValue) {
+ RemoteConfig remoteConfig = TvApplication.getSingletons(context).getRemoteConfig();
+ try {
+ long remoteValue = remoteConfig.getLong(key);
+ if (DEBUG) Log.d(TAG, "Got " + key + " from remote: " + remoteValue);
+ return remoteValue;
+ } catch (Exception e) {
+ Log.w(TAG, "Cannot get " + key + " from RemoteConfig", e);
+ }
+ if (DEBUG) Log.d(TAG, "Use default value " + defaultValue);
+ return defaultValue;
+ }
+}
diff --git a/src/com/android/tv/customization/TvCustomizationManager.java b/src/com/android/tv/customization/TvCustomizationManager.java
index 22298a10..ed6b98ca 100644
--- a/src/com/android/tv/customization/TvCustomizationManager.java
+++ b/src/com/android/tv/customization/TvCustomizationManager.java
@@ -18,15 +18,18 @@ package com.android.tv.customization;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
+import android.support.annotation.IntDef;
import android.text.TextUtils;
import android.util.Log;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -37,6 +40,10 @@ public class TvCustomizationManager {
private static final String TAG = "TvCustomizationManager";
private static final boolean DEBUG = false;
+ private static final String[] CUSTOMIZE_PERMISSIONS = {
+ "com.android.tv.permission.CUSTOMIZE_TV_APP"
+ };
+
private static final String CATEGORY_TV_CUSTOMIZATION =
"com.android.tv.category";
@@ -47,6 +54,19 @@ public class TvCustomizationManager {
public static final String ID_OPTIONS_ROW = "options_row";
public static final String ID_PARTNER_ROW = "partner_row";
+ @IntDef({TRICKPLAY_MODE_ENABLED, TRICKPLAY_MODE_DISABLED, TRICKPLAY_MODE_USE_EXTERNAL_STORAGE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TRICKPLAY_MODE {}
+ public static final int TRICKPLAY_MODE_ENABLED = 0;
+ public static final int TRICKPLAY_MODE_DISABLED = 1;
+ public static final int TRICKPLAY_MODE_USE_EXTERNAL_STORAGE = 2;
+
+ private static final String[] TRICKPLAY_MODE_STRINGS = {
+ "enabled",
+ "disabled",
+ "use_external_storage_only"
+ };
+
private static final HashMap<String, String> INTENT_CATEGORY_TO_ROW_ID;
static {
INTENT_CATEGORY_TO_ROW_ID = new HashMap<>();
@@ -55,12 +75,19 @@ public class TvCustomizationManager {
}
private static final String RES_ID_PARTNER_ROW_TITLE = "partner_row_title";
+ private static final String RES_ID_HAS_LINUX_DVB_BUILT_IN_TUNER =
+ "has_linux_dvb_built_in_tuner";
+ private static final String RES_ID_TRICKPLAY_MODE = "trickplay_mode";
private static final String RES_TYPE_STRING = "string";
+ private static final String RES_TYPE_BOOLEAN = "bool";
+
+ private static String sCustomizationPackage;
+ private static Boolean sHasLinuxDvbBuiltInTuner;
+ private static @TRICKPLAY_MODE Integer sTrickplayMode;
private final Context mContext;
private boolean mInitialized;
- private String mCustomizationPackage;
private String mPartnerRowTitle;
private final Map<String, List<CustomAction>> mRowIdToCustomActionsMap = new HashMap<>();
@@ -71,6 +98,68 @@ public class TvCustomizationManager {
}
/**
+ * Returns {@code true} if there's a customization package installed and it specifies built-in
+ * tuner devices are available. The built-in tuner should support DVB API to be recognized by
+ * Live TV.
+ */
+ public static boolean hasLinuxDvbBuiltInTuner(Context context) {
+ if (sHasLinuxDvbBuiltInTuner == null) {
+ if (TextUtils.isEmpty(getCustomizationPackageName(context))) {
+ sHasLinuxDvbBuiltInTuner = false;
+ } else {
+ try {
+ Resources res = context.getPackageManager()
+ .getResourcesForApplication(sCustomizationPackage);
+ int resId = res.getIdentifier(RES_ID_HAS_LINUX_DVB_BUILT_IN_TUNER,
+ RES_TYPE_BOOLEAN, sCustomizationPackage);
+ sHasLinuxDvbBuiltInTuner = resId != 0 && res.getBoolean(resId);
+ } catch (NameNotFoundException e) {
+ sHasLinuxDvbBuiltInTuner = false;
+ }
+ }
+ }
+ return sHasLinuxDvbBuiltInTuner;
+ }
+
+ public static @TRICKPLAY_MODE int getTrickplayMode(Context context) {
+ if (sTrickplayMode == null) {
+ if (TextUtils.isEmpty(getCustomizationPackageName(context))) {
+ sTrickplayMode = TRICKPLAY_MODE_ENABLED;
+ } else {
+ try {
+ String customization = null;
+ Resources res = context.getPackageManager()
+ .getResourcesForApplication(sCustomizationPackage);
+ int resId = res.getIdentifier(RES_ID_TRICKPLAY_MODE,
+ RES_TYPE_STRING, sCustomizationPackage);
+ customization = resId == 0 ? null : res.getString(resId);
+ sTrickplayMode = TRICKPLAY_MODE_ENABLED;
+ if (customization != null) {
+ for (int i = 0; i < TRICKPLAY_MODE_STRINGS.length; ++i) {
+ if (TRICKPLAY_MODE_STRINGS[i].equalsIgnoreCase(customization)) {
+ sTrickplayMode = i;
+ break;
+ }
+ }
+ }
+ } catch (NameNotFoundException e) {
+ sTrickplayMode = TRICKPLAY_MODE_ENABLED;
+ }
+ }
+ }
+ return sTrickplayMode;
+ }
+
+ private static String getCustomizationPackageName(Context context) {
+ if (sCustomizationPackage == null) {
+ List<PackageInfo> packageInfos = context.getPackageManager()
+ .getPackagesHoldingPermissions(CUSTOMIZE_PERMISSIONS, 0);
+ sCustomizationPackage = packageInfos.size() == 0 ? "" : packageInfos.get(0).packageName;
+ }
+ return sCustomizationPackage;
+ }
+
+ /**
* Initialize TV customization options.
* Run this API only on the main thread.
*/
@@ -79,14 +168,13 @@ public class TvCustomizationManager {
return;
}
mInitialized = true;
- buildCustomActions();
- if (!TextUtils.isEmpty(mCustomizationPackage)) {
+ if (!TextUtils.isEmpty(getCustomizationPackageName(mContext))) {
+ buildCustomActions();
buildPartnerRow();
}
}
private void buildCustomActions() {
- mCustomizationPackage = null;
mRowIdToCustomActionsMap.clear();
PackageManager pm = mContext.getPackageManager();
for (String intentCategory : INTENT_CATEGORY_TO_ROW_ID.keySet()) {
@@ -98,16 +186,8 @@ public class TvCustomizationManager {
| PackageManager.GET_META_DATA);
for (ResolveInfo info : activities) {
String packageName = info.activityInfo.packageName;
- if (TextUtils.isEmpty(mCustomizationPackage)) {
- if (DEBUG) Log.d(TAG, "Found TV customization package " + packageName);
- if ((info.activityInfo.applicationInfo.flags
- & ApplicationInfo.FLAG_SYSTEM) == 0) {
- Log.w(TAG, "Only system app can customize TV. Ignoring " + packageName);
- continue;
- }
- mCustomizationPackage = packageName;
- } else if (!packageName.equals(mCustomizationPackage)) {
- Log.w(TAG, "A customization package " + mCustomizationPackage
+ if (!TextUtils.equals(packageName, sCustomizationPackage)) {
+ Log.w(TAG, "A customization package " + sCustomizationPackage
+ " already exist. Ignoring " + packageName);
continue;
}
@@ -117,7 +197,7 @@ public class TvCustomizationManager {
Drawable drawable = info.loadIcon(pm);
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(intentCategory);
- intent.setClassName(mCustomizationPackage, info.activityInfo.name);
+ intent.setClassName(sCustomizationPackage, info.activityInfo.name);
String rowId = INTENT_CATEGORY_TO_ROW_ID.get(intentCategory);
List<CustomAction> actions = mRowIdToCustomActionsMap.get(rowId);
@@ -159,13 +239,13 @@ public class TvCustomizationManager {
Resources res;
try {
res = mContext.getPackageManager()
- .getResourcesForApplication(mCustomizationPackage);
+ .getResourcesForApplication(sCustomizationPackage);
} catch (NameNotFoundException e) {
- Log.w(TAG, "Could not get resources for package " + mCustomizationPackage);
+ Log.w(TAG, "Could not get resources for package " + sCustomizationPackage);
return;
}
int resId = res.getIdentifier(
- RES_ID_PARTNER_ROW_TITLE, RES_TYPE_STRING, mCustomizationPackage);
+ RES_ID_PARTNER_ROW_TITLE, RES_TYPE_STRING, sCustomizationPackage);
if (resId != 0) {
mPartnerRowTitle = res.getString(resId);
}
diff --git a/src/com/android/tv/data/BaseProgram.java b/src/com/android/tv/data/BaseProgram.java
index f420de02..4e36c80a 100644
--- a/src/com/android/tv/data/BaseProgram.java
+++ b/src/com/android/tv/data/BaseProgram.java
@@ -17,12 +17,17 @@
package com.android.tv.data;
import android.content.Context;
+import android.media.tv.TvContentRating;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+
+import com.android.tv.R;
import java.util.Comparator;
/**
* Base class for {@link com.android.tv.data.Program} and
- * {@link com.android.tv.dvr.RecordedProgram}.
+ * {@link com.android.tv.dvr.data.RecordedProgram}.
*/
public abstract class BaseProgram {
/**
@@ -94,14 +99,29 @@ public abstract class BaseProgram {
abstract public String getTitle();
/**
- * Returns the program's title withe its season and episode number.
+ * Returns the episode title.
*/
- abstract public String getTitleWithEpisodeNumber(Context context);
+ abstract public String getEpisodeTitle();
/**
* Returns the displayed title of the program episode.
*/
- abstract public String getEpisodeDisplayTitle(Context context);
+ public String getEpisodeDisplayTitle(Context context) {
+ if (!TextUtils.isEmpty(getEpisodeNumber())) {
+ String episodeTitle = getEpisodeTitle() == null ? "" : getEpisodeTitle();
+ if (TextUtils.equals(getSeasonNumber(), "0")) {
+ // Do not show "S0: ".
+ return String.format(context.getResources().getString(
+ R.string.display_episode_title_format_no_season_number),
+ getEpisodeNumber(), episodeTitle);
+ } else {
+ return String.format(context.getResources().getString(
+ R.string.display_episode_title_format),
+ getSeasonNumber(), getEpisodeNumber(), episodeTitle);
+ }
+ }
+ return getEpisodeTitle();
+ }
/**
* Returns the description of the program.
@@ -158,6 +178,10 @@ public abstract class BaseProgram {
*/
abstract public int[] getCanonicalGenreIds();
+ /** Returns the array of content ratings. */
+ @Nullable
+ abstract public TvContentRating[] getContentRatings();
+
/**
* Returns channel's ID of the program.
*/
@@ -169,6 +193,13 @@ public abstract class BaseProgram {
abstract public boolean isValid();
/**
+ * Checks whether the program is episodic or not.
+ */
+ public boolean isEpisodic() {
+ return getSeriesId() != null;
+ }
+
+ /**
* Generates the series ID for the other inputs than the tuner TV input.
*/
public static String generateSeriesId(String packageName, String title) {
diff --git a/src/com/android/tv/data/Channel.java b/src/com/android/tv/data/Channel.java
index 30f84236..4a391ae7 100644
--- a/src/com/android/tv/data/Channel.java
+++ b/src/com/android/tv/data/Channel.java
@@ -52,6 +52,16 @@ public final class Channel {
public static final int LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART = 3;
/**
+ * Compares the channel numbers of channels which belong to the same input.
+ */
+ public static final Comparator<Channel> CHANNEL_NUMBER_COMPARATOR = new Comparator<Channel>() {
+ @Override
+ public int compare(Channel lhs, Channel rhs) {
+ return ChannelNumber.compare(lhs.getDisplayNumber(), rhs.getDisplayNumber());
+ }
+ };
+
+ /**
* When a TIS doesn't provide any information about app link, and it doesn't have a leanback
* launch intent, there will be no app link card for the TIS.
*/
@@ -81,15 +91,22 @@ public final class Channel {
TvContract.Channels.COLUMN_DESCRIPTION,
TvContract.Channels.COLUMN_VIDEO_FORMAT,
TvContract.Channels.COLUMN_BROWSABLE,
+ TvContract.Channels.COLUMN_SEARCHABLE,
TvContract.Channels.COLUMN_LOCKED,
TvContract.Channels.COLUMN_APP_LINK_TEXT,
TvContract.Channels.COLUMN_APP_LINK_COLOR,
TvContract.Channels.COLUMN_APP_LINK_ICON_URI,
TvContract.Channels.COLUMN_APP_LINK_POSTER_ART_URI,
TvContract.Channels.COLUMN_APP_LINK_INTENT_URI,
+ TvContract.Channels.COLUMN_INTERNAL_PROVIDER_FLAG2, // Only used in bundled input
};
/**
+ * Channel number delimiter between major and minor parts.
+ */
+ public static final char CHANNEL_NUMBER_DELIMITER = '-';
+
+ /**
* Creates {@code Channel} object from cursor.
*
* <p>The query that created the cursor MUST use {@link #PROJECTION}
@@ -103,28 +120,41 @@ public final class Channel {
channel.mPackageName = Utils.intern(cursor.getString(index++));
channel.mInputId = Utils.intern(cursor.getString(index++));
channel.mType = Utils.intern(cursor.getString(index++));
- channel.mDisplayNumber = cursor.getString(index++);
+ channel.mDisplayNumber = normalizeDisplayNumber(cursor.getString(index++));
channel.mDisplayName = cursor.getString(index++);
channel.mDescription = cursor.getString(index++);
channel.mVideoFormat = Utils.intern(cursor.getString(index++));
channel.mBrowsable = cursor.getInt(index++) == 1;
+ channel.mSearchable = cursor.getInt(index++) == 1;
channel.mLocked = cursor.getInt(index++) == 1;
channel.mAppLinkText = cursor.getString(index++);
channel.mAppLinkColor = cursor.getInt(index++);
channel.mAppLinkIconUri = cursor.getString(index++);
channel.mAppLinkPosterArtUri = cursor.getString(index++);
channel.mAppLinkIntentUri = cursor.getString(index++);
+ if (Utils.isBundledInput(channel.mInputId)) {
+ channel.mRecordingProhibited = cursor.getInt(index++) != 0;
+ }
return channel;
}
/**
- * Creates a {@link Channel} object from the DVR database.
+ * Replaces the channel number separator with dash('-').
*/
- public static Channel fromDvrCursor(Cursor c) {
- Channel channel = new Channel();
- int index = -1;
- channel.mDvrId = c.getLong(++index);
- return channel;
+ public static String normalizeDisplayNumber(String string) {
+ if (!TextUtils.isEmpty(string)) {
+ int length = string.length();
+ for (int i = 0; i < length; i++) {
+ char c = string.charAt(i);
+ if (c == '.' || Character.isWhitespace(c)
+ || Character.getType(c) == Character.DASH_PUNCTUATION) {
+ StringBuilder sb = new StringBuilder(string);
+ sb.setCharAt(i, CHANNEL_NUMBER_DELIMITER);
+ return sb.toString();
+ }
+ }
+ }
+ return string;
}
/** ID of this channel. Matches to BaseColumns._ID. */
@@ -138,6 +168,7 @@ public final class Channel {
private String mDescription;
private String mVideoFormat;
private boolean mBrowsable;
+ private boolean mSearchable;
private boolean mLocked;
private boolean mIsPassthrough;
private String mAppLinkText;
@@ -147,8 +178,10 @@ public final class Channel {
private String mAppLinkIntentUri;
private Intent mAppLinkIntent;
private int mAppLinkType;
+ private String mLogoUri;
+ private boolean mRecordingProhibited;
- private long mDvrId;
+ private boolean mChannelLogoExist;
private Channel() {
// Do nothing.
@@ -187,7 +220,6 @@ public final class Channel {
return mDisplayName;
}
- @VisibleForTesting
public String getDescription() {
return mDescription;
}
@@ -230,10 +262,14 @@ public final class Channel {
}
/**
- * Returns an ID in DVR database.
+ * Returns channel logo uri which is got from cloud, it's used only for ChannelLogoFetcher.
*/
- public long getDvrId() {
- return mDvrId;
+ public String getLogoUri() {
+ return mLogoUri;
+ }
+
+ public boolean isRecordingProhibited() {
+ return mRecordingProhibited;
}
/**
@@ -266,6 +302,11 @@ public final class Channel {
return mBrowsable;
}
+ /** Checks whether this channel is searchable or not. */
+ public boolean isSearchable() {
+ return mSearchable;
+ }
+
public boolean isLocked() {
return mLocked;
}
@@ -279,6 +320,13 @@ public final class Channel {
}
/**
+ * Sets channel logo uri which is got from cloud.
+ */
+ public void setLogoUri(String logoUri) {
+ mLogoUri = logoUri;
+ }
+
+ /**
* Check whether {@code other} has same read-only channel info as this. But, it cannot check two
* channels have same logos. It also excludes browsable and locked, because two fields are
* changed by TV app.
@@ -298,7 +346,8 @@ public final class Channel {
&& mAppLinkColor == other.mAppLinkColor
&& Objects.equals(mAppLinkIconUri, other.mAppLinkIconUri)
&& Objects.equals(mAppLinkPosterArtUri, other.mAppLinkPosterArtUri)
- && Objects.equals(mAppLinkIntentUri, other.mAppLinkIntentUri);
+ && Objects.equals(mAppLinkIntentUri, other.mAppLinkIntentUri)
+ && Objects.equals(mRecordingProhibited, other.mRecordingProhibited);
}
@Override
@@ -314,8 +363,10 @@ public final class Channel {
+ ", videoFormat=" + mVideoFormat
+ ", isPassthrough=" + mIsPassthrough
+ ", browsable=" + mBrowsable
+ + ", searchable=" + mSearchable
+ ", locked=" + mLocked
- + ", appLinkText=" + mAppLinkText + "}";
+ + ", appLinkText=" + mAppLinkText
+ + ", recordingProhibited=" + mRecordingProhibited + "}";
}
void copyFrom(Channel other) {
@@ -332,6 +383,7 @@ public final class Channel {
mVideoFormat = other.mVideoFormat;
mIsPassthrough = other.mIsPassthrough;
mBrowsable = other.mBrowsable;
+ mSearchable = other.mSearchable;
mLocked = other.mLocked;
mAppLinkText = other.mAppLinkText;
mAppLinkColor = other.mAppLinkColor;
@@ -340,6 +392,8 @@ public final class Channel {
mAppLinkIntentUri = other.mAppLinkIntentUri;
mAppLinkIntent = other.mAppLinkIntent;
mAppLinkType = other.mAppLinkType;
+ mRecordingProhibited = other.mRecordingProhibited;
+ mChannelLogoExist = other.mChannelLogoExist;
}
/**
@@ -389,8 +443,7 @@ public final class Channel {
mChannel.mDisplayName = "name";
mChannel.mDescription = "description";
mChannel.mBrowsable = true;
- mChannel.mLocked = false;
- mChannel.mIsPassthrough = false;
+ mChannel.mSearchable = true;
}
public Builder(Channel other) {
@@ -422,7 +475,7 @@ public final class Channel {
@VisibleForTesting
public Builder setDisplayNumber(String displayNumber) {
- mChannel.mDisplayNumber = displayNumber;
+ mChannel.mDisplayNumber = normalizeDisplayNumber(displayNumber);
return this;
}
@@ -448,6 +501,11 @@ public final class Channel {
return this;
}
+ public Builder setSearchable(boolean searchable) {
+ mChannel.mSearchable = searchable;
+ return this;
+ }
+
public Builder setLocked(boolean locked) {
mChannel.mLocked = locked;
return this;
@@ -485,6 +543,11 @@ public final class Channel {
return this;
}
+ public Builder setRecordingProhibited(boolean recordingProhibited) {
+ mChannel.mRecordingProhibited = recordingProhibited;
+ return this;
+ }
+
public Channel build() {
Channel channel = new Channel();
channel.copyFrom(mChannel);
@@ -524,6 +587,21 @@ public final class Channel {
}
/**
+ * Sets if the channel logo exists. This method should be only called from
+ * {@link ChannelDataManager}.
+ */
+ void setChannelLogoExist(boolean exist) {
+ mChannelLogoExist = exist;
+ }
+
+ /**
+ * Returns if channel logo exists.
+ */
+ public boolean channelLogoExists() {
+ return mChannelLogoExist;
+ }
+
+ /**
* Returns the type of app link for this channel.
* It returns {@link #APP_LINK_TYPE_CHANNEL} if the channel has a non null app link text and
* a valid app link intent, it returns {@link #APP_LINK_TYPE_APP} if the input service which
@@ -655,4 +733,4 @@ public final class Channel {
return label;
}
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/data/ChannelDataManager.java b/src/com/android/tv/data/ChannelDataManager.java
index 6f9ea6d7..6f93fbd1 100644
--- a/src/com/android/tv/data/ChannelDataManager.java
+++ b/src/com/android/tv/data/ChannelDataManager.java
@@ -21,13 +21,17 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
+import android.content.res.AssetFileDescriptor;
import android.database.ContentObserver;
+import android.database.sqlite.SQLiteException;
import android.media.tv.TvContract;
import android.media.tv.TvContract.Channels;
import android.media.tv.TvInputManager.TvInputCallback;
+import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.support.annotation.AnyThread;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
@@ -43,6 +47,7 @@ import com.android.tv.util.PermissionUtils;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -59,7 +64,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
* This class is not thread-safe and under an assumption that its public methods are called in
* only the main thread.
*/
-@MainThread
+@AnyThread
public class ChannelDataManager {
private static final String TAG = "ChannelDataManager";
private static final boolean DEBUG = false;
@@ -74,10 +79,10 @@ public class ChannelDataManager {
private final List<Runnable> mPostRunnablesAfterChannelUpdate = new ArrayList<>();
private final Set<Listener> mListeners = new CopyOnWriteArraySet<>();
- private final Map<Long, ChannelWrapper> mChannelWrapperMap = new HashMap<>();
- private final Map<String, MutableInt> mChannelCountMap = new HashMap<>();
+ // Use container class to support multi-thread safety. This value can be set only on the main
+ // thread.
+ volatile private UnmodifiableChannelData mData = new UnmodifiableChannelData();
private final Channel.DefaultComparator mChannelComparator;
- private final List<Channel> mChannels = new ArrayList<>();
private final Handler mHandler;
private final Set<Long> mBrowsableUpdateChannelIds = new HashSet<>();
@@ -92,15 +97,17 @@ public class ChannelDataManager {
@Override
public void onInputAdded(String inputId) {
boolean channelAdded = false;
- for (ChannelWrapper channel : mChannelWrapperMap.values()) {
+ ChannelData data = new ChannelData(mData);
+ for (ChannelWrapper channel : mData.channelWrapperMap.values()) {
if (channel.mChannel.getInputId().equals(inputId)) {
channel.mInputRemoved = false;
- addChannel(channel.mChannel);
+ addChannel(data, channel.mChannel);
channelAdded = true;
}
}
if (channelAdded) {
- Collections.sort(mChannels, mChannelComparator);
+ Collections.sort(data.channels, mChannelComparator);
+ mData = new UnmodifiableChannelData(data);
notifyChannelListUpdated();
}
}
@@ -109,7 +116,7 @@ public class ChannelDataManager {
public void onInputRemoved(String inputId) {
boolean channelRemoved = false;
ArrayList<ChannelWrapper> removedChannels = new ArrayList<>();
- for (ChannelWrapper channel : mChannelWrapperMap.values()) {
+ for (ChannelWrapper channel : mData.channelWrapperMap.values()) {
if (channel.mChannel.getInputId().equals(inputId)) {
channel.mInputRemoved = true;
channelRemoved = true;
@@ -117,13 +124,15 @@ public class ChannelDataManager {
}
}
if (channelRemoved) {
- clearChannels();
- for (ChannelWrapper channelWrapper : mChannelWrapperMap.values()) {
+ ChannelData data = new ChannelData();
+ data.channelWrapperMap.putAll(mData.channelWrapperMap);
+ for (ChannelWrapper channelWrapper : data.channelWrapperMap.values()) {
if (!channelWrapper.mInputRemoved) {
- addChannel(channelWrapper.mChannel);
+ addChannel(data, channelWrapper.mChannel);
}
}
- Collections.sort(mChannels, mChannelComparator);
+ Collections.sort(data.channels, mChannelComparator);
+ mData = new UnmodifiableChannelData(data);
notifyChannelListUpdated();
for (ChannelWrapper channel : removedChannels) {
channel.notifyChannelRemoved();
@@ -132,10 +141,12 @@ public class ChannelDataManager {
}
};
+ @MainThread
public ChannelDataManager(Context context, TvInputManagerHelper inputManager) {
this(context, inputManager, context.getContentResolver());
}
+ @MainThread
@VisibleForTesting
ChannelDataManager(Context context, TvInputManagerHelper inputManager,
ContentResolver contentResolver) {
@@ -167,6 +178,7 @@ public class ChannelDataManager {
/**
* Starts the manager. If data is ready, {@link Listener#onLoadFinished()} will be called.
*/
+ @MainThread
public void start() {
if (mStarted) {
return;
@@ -184,6 +196,7 @@ public class ChannelDataManager {
* Stops the manager. It clears manager states and runs pending DB operations. Added listeners
* aren't automatically removed by this method.
*/
+ @MainThread
@VisibleForTesting
public void stop() {
if (!mStarted) {
@@ -192,12 +205,10 @@ public class ChannelDataManager {
mStarted = false;
mDbLoadFinished = false;
- ChannelLogoFetcher.stopFetchingChannelLogos();
mInputManager.removeCallback(mTvInputCallback);
mContentResolver.unregisterContentObserver(mChannelObserver);
mHandler.removeCallbacksAndMessages(null);
- mChannelWrapperMap.clear();
clearChannels();
mPostRunnablesAfterChannelUpdate.clear();
if (mChannelsUpdateTask != null) {
@@ -233,7 +244,7 @@ public class ChannelDataManager {
* Adds a {@link ChannelListener} for a specific channel with the channel ID {@code channelId}.
*/
public void addChannelListener(Long channelId, ChannelListener listener) {
- ChannelWrapper channelWrapper = mChannelWrapperMap.get(channelId);
+ ChannelWrapper channelWrapper = mData.channelWrapperMap.get(channelId);
if (channelWrapper == null) {
return;
}
@@ -245,7 +256,7 @@ public class ChannelDataManager {
* {@code channelId}.
*/
public void removeChannelListener(Long channelId, ChannelListener listener) {
- ChannelWrapper channelWrapper = mChannelWrapperMap.get(channelId);
+ ChannelWrapper channelWrapper = mData.channelWrapperMap.get(channelId);
if (channelWrapper == null) {
return;
}
@@ -263,14 +274,14 @@ public class ChannelDataManager {
* Returns the number of channels.
*/
public int getChannelCount() {
- return mChannels.size();
+ return mData.channels.size();
}
/**
* Returns a list of channels.
*/
public List<Channel> getChannelList() {
- return Collections.unmodifiableList(mChannels);
+ return new ArrayList<>(mData.channels);
}
/**
@@ -278,7 +289,7 @@ public class ChannelDataManager {
*/
public List<Channel> getBrowsableChannelList() {
List<Channel> channels = new ArrayList<>();
- for (Channel channel : mChannels) {
+ for (Channel channel : mData.channels) {
if (channel.isBrowsable()) {
channels.add(channel);
}
@@ -292,7 +303,7 @@ public class ChannelDataManager {
* @param inputId The ID of the input.
*/
public int getChannelCountForInput(String inputId) {
- MutableInt count = mChannelCountMap.get(inputId);
+ MutableInt count = mData.channelCountMap.get(inputId);
return count == null ? 0 : count.value;
}
@@ -303,17 +314,14 @@ public class ChannelDataManager {
* In that case this method is used to check if the channel exists in the DB.
*/
public boolean doesChannelExistInDb(long channelId) {
- return mChannelWrapperMap.get(channelId) != null;
+ return mData.channelWrapperMap.get(channelId) != null;
}
/**
* Returns true if and only if there exists at least one channel and all channels are hidden.
*/
public boolean areAllChannelsHidden() {
- if (mChannels.isEmpty()) {
- return false;
- }
- for (Channel channel : mChannels) {
+ for (Channel channel : mData.channels) {
if (channel.isBrowsable()) {
return false;
}
@@ -325,7 +333,7 @@ public class ChannelDataManager {
* Gets the channel with the channel ID {@code channelId}.
*/
public Channel getChannel(Long channelId) {
- ChannelWrapper channelWrapper = mChannelWrapperMap.get(channelId);
+ ChannelWrapper channelWrapper = mData.channelWrapperMap.get(channelId);
if (channelWrapper == null || channelWrapper.mInputRemoved) {
return null;
}
@@ -349,7 +357,7 @@ public class ChannelDataManager {
*/
public void updateBrowsable(Long channelId, boolean browsable,
boolean skipNotifyChannelBrowsableChanged) {
- ChannelWrapper channelWrapper = mChannelWrapperMap.get(channelId);
+ ChannelWrapper channelWrapper = mData.channelWrapperMap.get(channelId);
if (channelWrapper == null) {
return;
}
@@ -407,7 +415,7 @@ public class ChannelDataManager {
* The value change will be applied to DB when applyPendingDbOperation is called.
*/
public void updateLocked(Long channelId, boolean locked) {
- ChannelWrapper channelWrapper = mChannelWrapperMap.get(channelId);
+ ChannelWrapper channelWrapper = mData.channelWrapperMap.get(channelId);
if (channelWrapper == null) {
return;
}
@@ -427,10 +435,11 @@ public class ChannelDataManager {
* to DB.
*/
public void applyUpdatedValuesToDb() {
+ ChannelData data = mData;
ArrayList<Long> browsableIds = new ArrayList<>();
ArrayList<Long> unbrowsableIds = new ArrayList<>();
for (Long id : mBrowsableUpdateChannelIds) {
- ChannelWrapper channelWrapper = mChannelWrapperMap.get(id);
+ ChannelWrapper channelWrapper = data.channelWrapperMap.get(id);
if (channelWrapper == null) {
continue;
}
@@ -452,10 +461,10 @@ public class ChannelDataManager {
}
editor.apply();
} else {
- if (browsableIds.size() != 0) {
+ if (!browsableIds.isEmpty()) {
updateOneColumnValue(column, 1, browsableIds);
}
- if (unbrowsableIds.size() != 0) {
+ if (!unbrowsableIds.isEmpty()) {
updateOneColumnValue(column, 0, unbrowsableIds);
}
}
@@ -464,7 +473,7 @@ public class ChannelDataManager {
ArrayList<Long> lockedIds = new ArrayList<>();
ArrayList<Long> unlockedIds = new ArrayList<>();
for (Long id : mLockedUpdateChannelIds) {
- ChannelWrapper channelWrapper = mChannelWrapperMap.get(id);
+ ChannelWrapper channelWrapper = data.channelWrapperMap.get(id);
if (channelWrapper == null) {
continue;
}
@@ -476,10 +485,10 @@ public class ChannelDataManager {
channelWrapper.mLockedInDb = channelWrapper.mChannel.isLocked();
}
column = TvContract.Channels.COLUMN_LOCKED;
- if (lockedIds.size() != 0) {
+ if (!lockedIds.isEmpty()) {
updateOneColumnValue(column, 1, lockedIds);
}
- if (unlockedIds.size() != 0) {
+ if (!unlockedIds.isEmpty()) {
updateOneColumnValue(column, 0, unlockedIds);
}
mLockedUpdateChannelIds.clear();
@@ -492,22 +501,24 @@ public class ChannelDataManager {
}
}
- private void addChannel(Channel channel) {
- mChannels.add(channel);
+ @MainThread
+ private void addChannel(ChannelData data, Channel channel) {
+ data.channels.add(channel);
String inputId = channel.getInputId();
- MutableInt count = mChannelCountMap.get(inputId);
+ MutableInt count = data.channelCountMap.get(inputId);
if (count == null) {
- mChannelCountMap.put(inputId, new MutableInt(1));
+ data.channelCountMap.put(inputId, new MutableInt(1));
} else {
count.value++;
}
}
+ @MainThread
private void clearChannels() {
- mChannels.clear();
- mChannelCountMap.clear();
+ mData = new UnmodifiableChannelData();
}
+ @MainThread
private void handleUpdateChannels() {
if (mChannelsUpdateTask != null) {
mChannelsUpdateTask.cancel(true);
@@ -525,6 +536,9 @@ public class ChannelDataManager {
}
}
+ /**
+ * A listener for ChannelDataManager. The callbacks are called on the main thread.
+ */
public interface Listener {
/**
* Called when data load is finished.
@@ -543,6 +557,9 @@ public class ChannelDataManager {
void onChannelBrowsableChanged();
}
+ /**
+ * A listener for individual channel change. The callbacks are called on the main thread.
+ */
public interface ChannelListener {
/**
* Called when the channel has been removed in DB.
@@ -590,9 +607,36 @@ public class ChannelDataManager {
}
}
+ private class CheckChannelLogoExistTask extends AsyncTask<Void, Void, Boolean> {
+ private final Channel mChannel;
+
+ CheckChannelLogoExistTask(Channel channel) {
+ mChannel = channel;
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ try (AssetFileDescriptor f = mContext.getContentResolver().openAssetFileDescriptor(
+ TvContract.buildChannelLogoUri(mChannel.getId()), "r")) {
+ return true;
+ } catch (SQLiteException | IOException | NullPointerException e) {
+ // File not found or asset file not found.
+ }
+ return false;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ ChannelWrapper wrapper = mData.channelWrapperMap.get(mChannel.getId());
+ if (wrapper != null) {
+ wrapper.mChannel.setChannelLogoExist(result);
+ }
+ }
+ }
+
private final class QueryAllChannelsTask extends AsyncDbTask.AsyncChannelQueryTask {
- public QueryAllChannelsTask(ContentResolver contentResolver) {
+ QueryAllChannelsTask(ContentResolver contentResolver) {
super(contentResolver);
}
@@ -603,7 +647,9 @@ public class ChannelDataManager {
if (DEBUG) Log.e(TAG, "onPostExecute with null channels");
return;
}
- Set<Long> removedChannelIds = new HashSet<>(mChannelWrapperMap.keySet());
+ ChannelData data = new ChannelData();
+ data.channelWrapperMap.putAll(mData.channelWrapperMap);
+ Set<Long> removedChannelIds = new HashSet<>(data.channelWrapperMap.keySet());
List<ChannelWrapper> removedChannelWrappers = new ArrayList<>();
List<ChannelWrapper> updatedChannelWrappers = new ArrayList<>();
@@ -625,13 +671,15 @@ public class ChannelDataManager {
boolean newlyAdded = !removedChannelIds.remove(channelId);
ChannelWrapper channelWrapper;
if (newlyAdded) {
+ new CheckChannelLogoExistTask(channel)
+ .executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
channelWrapper = new ChannelWrapper(channel);
- mChannelWrapperMap.put(channel.getId(), channelWrapper);
+ data.channelWrapperMap.put(channel.getId(), channelWrapper);
if (!channelWrapper.mInputRemoved) {
channelAdded = true;
}
} else {
- channelWrapper = mChannelWrapperMap.get(channelId);
+ channelWrapper = data.channelWrapperMap.get(channelId);
if (!channelWrapper.mChannel.hasSameReadOnlyInfo(channel)) {
// Channel data updated
Channel oldChannel = channelWrapper.mChannel;
@@ -640,9 +688,9 @@ public class ChannelDataManager {
// {@link #applyUpdatedValuesToDb} is called. Therefore, the value
// between DB and ChannelDataManager could be different for a while.
// Therefore, we'll keep the values in ChannelDataManager.
- channelWrapper.mChannel.copyFrom(channel);
channel.setBrowsable(oldChannel.isBrowsable());
channel.setLocked(oldChannel.isLocked());
+ channelWrapper.mChannel.copyFrom(channel);
if (!channelWrapper.mInputRemoved) {
channelUpdated = true;
updatedChannelWrappers.add(channelWrapper);
@@ -663,19 +711,19 @@ public class ChannelDataManager {
}
for (long id : removedChannelIds) {
- ChannelWrapper channelWrapper = mChannelWrapperMap.remove(id);
+ ChannelWrapper channelWrapper = data.channelWrapperMap.remove(id);
if (!channelWrapper.mInputRemoved) {
channelRemoved = true;
removedChannelWrappers.add(channelWrapper);
}
}
- clearChannels();
- for (ChannelWrapper channelWrapper : mChannelWrapperMap.values()) {
+ for (ChannelWrapper channelWrapper : data.channelWrapperMap.values()) {
if (!channelWrapper.mInputRemoved) {
- addChannel(channelWrapper.mChannel);
+ addChannel(data, channelWrapper.mChannel);
}
}
- Collections.sort(mChannels, mChannelComparator);
+ Collections.sort(data.channels, mChannelComparator);
+ mData = new UnmodifiableChannelData(data);
if (!mDbLoadFinished) {
mDbLoadFinished = true;
@@ -693,7 +741,6 @@ public class ChannelDataManager {
r.run();
}
mPostRunnablesAfterChannelUpdate.clear();
- ChannelLogoFetcher.startFetchingChannelLogos(mContext);
}
}
@@ -705,10 +752,9 @@ public class ChannelDataManager {
private void updateOneColumnValue(
final String columnName, final int columnValue, final List<Long> ids) {
if (!PermissionUtils.hasAccessAllEpg(mContext)) {
- // TODO: support this feature for non-system LC app. b/23939816
return;
}
- AsyncDbTask.execute(new Runnable() {
+ AsyncDbTask.executeOnDbThread(new Runnable() {
@Override
public void run() {
String selection = Utils.buildSelectionForIds(Channels._ID, ids);
@@ -723,6 +769,7 @@ public class ChannelDataManager {
return channel.getInputId() + "|" + channel.getId();
}
+ @MainThread
private static class ChannelDataManagerHandler extends WeakHandler<ChannelDataManager> {
public ChannelDataManagerHandler(ChannelDataManager channelDataManager) {
super(Looper.getMainLooper(), channelDataManager);
@@ -735,4 +782,51 @@ public class ChannelDataManager {
}
}
}
+
+ /**
+ * Container class which includes channel data that needs to be synced. This class is
+ * modifiable and used for changing channel data.
+ * e.g. TvInputCallback, or AsyncDbTask.onPostExecute.
+ */
+ @MainThread
+ private static class ChannelData {
+ final Map<Long, ChannelWrapper> channelWrapperMap;
+ final Map<String, MutableInt> channelCountMap;
+ final List<Channel> channels;
+
+ ChannelData() {
+ channelWrapperMap = new HashMap<>();
+ channelCountMap = new HashMap<>();
+ channels = new ArrayList<>();
+ }
+
+ ChannelData(ChannelData data) {
+ channelWrapperMap = new HashMap<>(data.channelWrapperMap);
+ channelCountMap = new HashMap<>(data.channelCountMap);
+ channels = new ArrayList<>(data.channels);
+ }
+
+ ChannelData(Map<Long, ChannelWrapper> channelWrapperMap,
+ Map<String, MutableInt> channelCountMap, List<Channel> channels) {
+ this.channelWrapperMap = channelWrapperMap;
+ this.channelCountMap = channelCountMap;
+ this.channels = channels;
+ }
+ }
+
+ /** Unmodifiable channel data. */
+ @MainThread
+ private static class UnmodifiableChannelData extends ChannelData {
+ UnmodifiableChannelData() {
+ super(Collections.unmodifiableMap(new HashMap<>()),
+ Collections.unmodifiableMap(new HashMap<>()),
+ Collections.unmodifiableList(new ArrayList<>()));
+ }
+
+ UnmodifiableChannelData(ChannelData data) {
+ super(Collections.unmodifiableMap(data.channelWrapperMap),
+ Collections.unmodifiableMap(data.channelCountMap),
+ Collections.unmodifiableList(data.channels));
+ }
+ }
}
diff --git a/src/com/android/tv/data/ChannelLogoFetcher.java b/src/com/android/tv/data/ChannelLogoFetcher.java
index 5a549f83..132cab7a 100644
--- a/src/com/android/tv/data/ChannelLogoFetcher.java
+++ b/src/com/android/tv/data/ChannelLogoFetcher.java
@@ -16,160 +16,74 @@
package com.android.tv.data;
+import android.content.ContentProviderOperation;
import android.content.Context;
-import android.database.Cursor;
+import android.content.OperationApplicationException;
+import android.content.SharedPreferences;
import android.graphics.Bitmap.CompressFormat;
import android.media.tv.TvContract;
-import android.media.tv.TvContract.Channels;
import android.net.Uri;
import android.os.AsyncTask;
-import android.support.annotation.WorkerThread;
+import android.os.RemoteException;
+import android.support.annotation.MainThread;
import android.text.TextUtils;
import android.util.Log;
-import com.android.tv.util.AsyncDbTask;
+import com.android.tv.common.SharedPreferencesUtils;
import com.android.tv.util.BitmapUtils;
import com.android.tv.util.BitmapUtils.ScaledBitmapInfo;
import com.android.tv.util.PermissionUtils;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
import java.util.Map;
-import java.util.Set;
+import java.util.List;
/**
- * Utility class for TMS data.
- * This class is thread safe.
+ * Fetches channel logos from the cloud into the database. It's for the channels which have no logos
+ * or need update logos. This class is thread safe.
*/
public class ChannelLogoFetcher {
private static final String TAG = "ChannelLogoFetcher";
private static final boolean DEBUG = false;
- /**
- * The name of the file which contains the TMS data.
- * The file has multiple records and each of them is a string separated by '|' like
- * STATION_NAME|SHORT_NAME|CALL_SIGN|LOGO_URI.
- */
- private static final String TMS_US_TABLE_FILE = "tms_us.table";
- private static final String TMS_KR_TABLE_FILE = "tms_kr.table";
- private static final String FIELD_SEPARATOR = "\\|";
- private static final String NAME_SEPARATOR_FOR_TMS = "\\(|\\)|\\{|\\}|\\[|\\]";
- private static final String NAME_SEPARATOR_FOR_DB = "\\W";
- private static final int INDEX_NAME = 0;
- private static final int INDEX_SHORT_NAME = 1;
- private static final int INDEX_CALL_SIGN = 2;
- private static final int INDEX_LOGO_URI = 3;
-
- private static final String COLUMN_CHANNEL_LOGO = "logo";
+ private static final String PREF_KEY_IS_FIRST_TIME_FETCH_CHANNEL_LOGO =
+ "is_first_time_fetch_channel_logo";
- private static final Object sLock = new Object();
- private static final Set<Long> sChannelIdBlackListSet = new HashSet<>();
- private static LoadChannelTask sQueryTask;
private static FetchLogoTask sFetchTask;
/**
- * Fetch the channel logos from TMS data and insert them into TvProvider.
+ * Fetches the channel logos from the cloud data and insert them into TvProvider.
* The previous task is canceled and a new task starts.
*/
- public static void startFetchingChannelLogos(Context context) {
+ @MainThread
+ public static void startFetchingChannelLogos(
+ Context context, List<Channel> channels) {
if (!PermissionUtils.hasAccessAllEpg(context)) {
// TODO: support this feature for non-system LC app. b/23939816
return;
}
- synchronized (sLock) {
- stopFetchingChannelLogos();
- if (DEBUG) Log.d(TAG, "Request to start fetching logos.");
- sQueryTask = new LoadChannelTask(context);
- sQueryTask.executeOnDbThread();
+ if (sFetchTask != null) {
+ sFetchTask.cancel(true);
+ sFetchTask = null;
}
- }
-
- /**
- * Stops the current fetching tasks. This can be called when the Activity pauses.
- */
- public static void stopFetchingChannelLogos() {
- synchronized (sLock) {
- if (DEBUG) Log.d(TAG, "Request to stop fetching logos.");
- if (sQueryTask != null) {
- sQueryTask.cancel(true);
- sQueryTask = null;
- }
- if (sFetchTask != null) {
- sFetchTask.cancel(true);
- sFetchTask = null;
- }
+ if (DEBUG) Log.d(TAG, "Request to start fetching logos.");
+ if (channels == null || channels.isEmpty()) {
+ return;
}
+ sFetchTask = new FetchLogoTask(context.getApplicationContext(), channels);
+ sFetchTask.execute();
}
private ChannelLogoFetcher() {
}
- private static final class LoadChannelTask extends AsyncDbTask<Void, Void, List<Channel>> {
- private final Context mContext;
-
- public LoadChannelTask(Context context) {
- mContext = context;
- }
-
- @Override
- protected List<Channel> doInBackground(Void... arg) {
- // Load channels which doesn't have channel logos.
- if (DEBUG) Log.d(TAG, "Starts loading the channels from DB");
- String[] projection =
- new String[] { Channels._ID, Channels.COLUMN_DISPLAY_NAME };
- String selection = COLUMN_CHANNEL_LOGO + " IS NULL AND "
- + Channels.COLUMN_PACKAGE_NAME + "=?";
- String[] selectionArgs = new String[] { mContext.getPackageName() };
- try (Cursor c = mContext.getContentResolver().query(Channels.CONTENT_URI,
- projection, selection, selectionArgs, null)) {
- if (c == null) {
- Log.e(TAG, "Query returns null cursor", new RuntimeException());
- return null;
- }
- List<Channel> channels = new ArrayList<>();
- while (!isCancelled() && c.moveToNext()) {
- long channelId = c.getLong(0);
- if (sChannelIdBlackListSet.contains(channelId)) {
- continue;
- }
- channels.add(new Channel.Builder().setId(c.getLong(0))
- .setDisplayName(c.getString(1).toUpperCase(Locale.getDefault()))
- .build());
- }
- return channels;
- }
- }
-
- @Override
- protected void onPostExecute(List<Channel> channels) {
- synchronized (sLock) {
- if (DEBUG) {
- int count = channels == null ? 0 : channels.size();
- Log.d(TAG, count + " channels are loaded");
- }
- if (sQueryTask == this) {
- sQueryTask = null;
- if (channels != null && !channels.isEmpty()) {
- sFetchTask = new FetchLogoTask(mContext, channels);
- sFetchTask.execute();
- }
- }
- }
- }
- }
-
private static final class FetchLogoTask extends AsyncTask<Void, Void, Void> {
private final Context mContext;
private final List<Channel> mChannels;
- public FetchLogoTask(Context context, List<Channel> channels) {
+ private FetchLogoTask(Context context, List<Channel> channels) {
mContext = context;
mChannels = channels;
}
@@ -180,83 +94,53 @@ public class ChannelLogoFetcher {
if (DEBUG) Log.d(TAG, "Fetching the channel logos has been canceled");
return null;
}
- // Load the TMS table data.
- if (DEBUG) Log.d(TAG, "Loads TMS data");
- Map<String, String> channelNameLogoUriMap = new HashMap<>();
- try {
- channelNameLogoUriMap.putAll(readTmsFile(mContext, TMS_US_TABLE_FILE));
- if (isCancelled()) {
- if (DEBUG) Log.d(TAG, "Fetching the channel logos has been canceled");
- return null;
+ List<Channel> channelsToUpdate = new ArrayList<>();
+ List<Channel> channelsToRemove = new ArrayList<>();
+ // Updates or removes the logo by comparing the logo uri which is got from the cloud
+ // and the stored one. And we assume that the data got form the cloud is 100%
+ // correct and completed.
+ SharedPreferences sharedPreferences =
+ mContext.getSharedPreferences(
+ SharedPreferencesUtils.SHARED_PREF_CHANNEL_LOGO_URIS,
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit();
+ Map<String, ?> uncheckedChannels = sharedPreferences.getAll();
+ boolean isFirstTimeFetchChannelLogo = sharedPreferences.getBoolean(
+ PREF_KEY_IS_FIRST_TIME_FETCH_CHANNEL_LOGO, true);
+ // Iterating channels.
+ for (Channel channel : mChannels) {
+ String channelIdString = Long.toString(channel.getId());
+ String storedChannelLogoUri = (String) uncheckedChannels.remove(channelIdString);
+ if (!TextUtils.isEmpty(channel.getLogoUri())
+ && !TextUtils.equals(storedChannelLogoUri, channel.getLogoUri())) {
+ channelsToUpdate.add(channel);
+ sharedPreferencesEditor.putString(channelIdString, channel.getLogoUri());
+ } else if (TextUtils.isEmpty(channel.getLogoUri())
+ && (!TextUtils.isEmpty(storedChannelLogoUri)
+ || isFirstTimeFetchChannelLogo)) {
+ channelsToRemove.add(channel);
+ sharedPreferencesEditor.remove(channelIdString);
}
- channelNameLogoUriMap.putAll(readTmsFile(mContext, TMS_KR_TABLE_FILE));
- } catch (IOException e) {
- Log.e(TAG, "Loading TMS data failed.", e);
- return null;
}
- if (isCancelled()) {
- if (DEBUG) Log.d(TAG, "Fetching the channel logos has been canceled");
- return null;
+
+ // Removes non existing channels from SharedPreferences.
+ for (String channelId : uncheckedChannels.keySet()) {
+ sharedPreferencesEditor.remove(channelId);
}
- // Iterating channels.
- for (Channel channel : mChannels) {
+ // Updates channel logos.
+ for (Channel channel : channelsToUpdate) {
if (isCancelled()) {
if (DEBUG) Log.d(TAG, "Fetching the channel logos has been canceled");
return null;
}
- // Download the channel logo.
- if (TextUtils.isEmpty(channel.getDisplayName())) {
- if (DEBUG) {
- Log.d(TAG, "The channel with ID (" + channel.getId()
- + ") doesn't have the display name.");
- }
- sChannelIdBlackListSet.add(channel.getId());
- continue;
- }
- String channelName = channel.getDisplayName().trim();
- String logoUri = channelNameLogoUriMap.get(channelName);
- if (TextUtils.isEmpty(logoUri)) {
- if (DEBUG) {
- Log.d(TAG, "Can't find a logo URI for channel '" + channelName + "'");
- }
- // Find the candidate names. If the channel name is CNN-HD, then find CNNHD
- // and CNN. Or if the channel name is KQED+, then find KQED.
- String[] splitNames = channelName.split(NAME_SEPARATOR_FOR_DB);
- if (splitNames.length > 1) {
- StringBuilder sb = new StringBuilder();
- for (String splitName : splitNames) {
- sb.append(splitName);
- }
- logoUri = channelNameLogoUriMap.get(sb.toString());
- if (DEBUG) {
- if (TextUtils.isEmpty(logoUri)) {
- Log.d(TAG, "Can't find a logo URI for channel '" + sb.toString()
- + "'");
- }
- }
- }
- if (TextUtils.isEmpty(logoUri)
- && splitNames[0].length() != channelName.length()) {
- logoUri = channelNameLogoUriMap.get(splitNames[0]);
- if (DEBUG) {
- if (TextUtils.isEmpty(logoUri)) {
- Log.d(TAG, "Can't find a logo URI for channel '" + splitNames[0]
- + "'");
- }
- }
- }
- }
- if (TextUtils.isEmpty(logoUri)) {
- sChannelIdBlackListSet.add(channel.getId());
- continue;
- }
+ // Downloads the channel logo.
+ String logoUri = channel.getLogoUri();
ScaledBitmapInfo bitmapInfo = BitmapUtils.decodeSampledBitmapFromUriString(
mContext, logoUri, Integer.MAX_VALUE, Integer.MAX_VALUE);
if (bitmapInfo == null) {
Log.e(TAG, "Failed to load bitmap. {channelName=" + channel.getDisplayName()
+ ", " + "logoUri=" + logoUri + "}");
- sChannelIdBlackListSet.add(channel.getId());
continue;
}
if (isCancelled()) {
@@ -264,12 +148,15 @@ public class ChannelLogoFetcher {
return null;
}
- // Insert the logo to DB.
+ // Inserts the logo to DB.
Uri dstLogoUri = TvContract.buildChannelLogoUri(channel.getId());
try (OutputStream os = mContext.getContentResolver().openOutputStream(dstLogoUri)) {
bitmapInfo.bitmap.compress(CompressFormat.PNG, 100, os);
} catch (IOException e) {
Log.e(TAG, "Failed to write " + logoUri + " to " + dstLogoUri, e);
+ // Removes it from the shared preference for the failed channels to make it
+ // retry next time.
+ sharedPreferencesEditor.remove(Long.toString(channel.getId()));
continue;
}
if (DEBUG) {
@@ -277,63 +164,35 @@ public class ChannelLogoFetcher {
+ dstLogoUri + "}");
}
}
- if (DEBUG) Log.d(TAG, "Fetching logos has been finished successfully.");
- return null;
- }
- @WorkerThread
- private Map<String, String> readTmsFile(Context context, String fileName)
- throws IOException {
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(
- context.getAssets().open(fileName)))) {
- Map<String, String> channelNameLogoUriMap = new HashMap<>();
- String line;
- while ((line = reader.readLine()) != null && !isCancelled()) {
- String[] data = line.split(FIELD_SEPARATOR);
- if (data.length != INDEX_LOGO_URI + 1) {
- if (DEBUG) Log.d(TAG, "Invalid or comment row: " + line);
- continue;
- }
- addChannelNames(channelNameLogoUriMap,
- data[INDEX_NAME].toUpperCase(Locale.getDefault()),
- data[INDEX_LOGO_URI]);
- addChannelNames(channelNameLogoUriMap,
- data[INDEX_SHORT_NAME].toUpperCase(Locale.getDefault()),
- data[INDEX_LOGO_URI]);
- addChannelNames(channelNameLogoUriMap,
- data[INDEX_CALL_SIGN].toUpperCase(Locale.getDefault()),
- data[INDEX_LOGO_URI]);
+ // Removes the logos for the channels that have logos before but now
+ // their logo uris are null.
+ boolean deleteChannelLogoFailed = false;
+ if (!channelsToRemove.isEmpty()) {
+ ArrayList<ContentProviderOperation> ops = new ArrayList<>();
+ for (Channel channel : channelsToRemove) {
+ ops.add(ContentProviderOperation.newDelete(
+ TvContract.buildChannelLogoUri(channel.getId())).build());
+ }
+ try {
+ mContext.getContentResolver().applyBatch(TvContract.AUTHORITY, ops);
+ } catch (RemoteException | OperationApplicationException e) {
+ deleteChannelLogoFailed = true;
+ Log.e(TAG, "Error deleting obsolete channels", e);
}
- return channelNameLogoUriMap;
}
- }
-
- private void addChannelNames(Map<String, String> channelNameLogoUriMap, String channelName,
- String logoUri) {
- if (!TextUtils.isEmpty(channelName)) {
- channelNameLogoUriMap.put(channelName, logoUri);
- // Find the candidate names.
- // If the name is like "W05AAD (W05AA-D)", then split the names into "W05AAD" and
- // "W05AA-D"
- String[] splitNames = channelName.split(NAME_SEPARATOR_FOR_TMS);
- if (splitNames.length > 1) {
- for (String name : splitNames) {
- name = name.trim();
- if (channelNameLogoUriMap.get(name) == null) {
- channelNameLogoUriMap.put(name, logoUri);
- }
- }
- }
+ if (isFirstTimeFetchChannelLogo && !deleteChannelLogoFailed) {
+ sharedPreferencesEditor.putBoolean(
+ PREF_KEY_IS_FIRST_TIME_FETCH_CHANNEL_LOGO, false);
}
+ sharedPreferencesEditor.commit();
+ if (DEBUG) Log.d(TAG, "Fetching logos has been finished successfully.");
+ return null;
}
@Override
protected void onPostExecute(Void result) {
- synchronized (sLock) {
- if (sFetchTask == this) {
- sFetchTask = null;
- }
- }
+ sFetchTask = null;
}
}
}
diff --git a/src/com/android/tv/data/ChannelNumber.java b/src/com/android/tv/data/ChannelNumber.java
index 59021609..29054aa5 100644
--- a/src/com/android/tv/data/ChannelNumber.java
+++ b/src/com/android/tv/data/ChannelNumber.java
@@ -17,37 +17,38 @@
package com.android.tv.data;
import android.support.annotation.NonNull;
+import android.text.TextUtils;
import android.view.KeyEvent;
+import com.android.tv.util.StringUtils;
+
+import java.util.Objects;
+
/**
* A convenience class to handle channel number.
*/
public final class ChannelNumber implements Comparable<ChannelNumber> {
- public static final String PRIMARY_CHANNEL_DELIMITER = "-";
- public static final String[] CHANNEL_DELIMITERS = {"-", ".", " "};
-
private static final int[] CHANNEL_DELIMITER_KEYCODES = {
KeyEvent.KEYCODE_MINUS, KeyEvent.KEYCODE_NUMPAD_SUBTRACT, KeyEvent.KEYCODE_PERIOD,
KeyEvent.KEYCODE_NUMPAD_DOT, KeyEvent.KEYCODE_SPACE
};
+ /** The major part of the channel number. */
public String majorNumber;
+ /** The flag which indicates whether it has a delimiter or not. */
public boolean hasDelimiter;
+ /** The major part of the channel number. */
public String minorNumber;
public ChannelNumber() {
reset();
}
- public ChannelNumber(String major, boolean hasDelimiter, String minor) {
- setChannelNumber(major, hasDelimiter, minor);
- }
-
public void reset() {
setChannelNumber("", false, "");
}
- public void setChannelNumber(String majorNumber, boolean hasDelimiter, String minorNumber) {
+ private void setChannelNumber(String majorNumber, boolean hasDelimiter, String minorNumber) {
this.majorNumber = majorNumber;
this.hasDelimiter = hasDelimiter;
this.minorNumber = minorNumber;
@@ -56,7 +57,7 @@ public final class ChannelNumber implements Comparable<ChannelNumber> {
@Override
public String toString() {
if (hasDelimiter) {
- return majorNumber + PRIMARY_CHANNEL_DELIMITER + minorNumber;
+ return majorNumber + Channel.CHANNEL_NUMBER_DELIMITER + minorNumber;
}
return majorNumber;
}
@@ -75,6 +76,22 @@ public final class ChannelNumber implements Comparable<ChannelNumber> {
return major - opponentMajor;
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ChannelNumber) {
+ ChannelNumber channelNumber = (ChannelNumber) obj;
+ return TextUtils.equals(majorNumber, channelNumber.majorNumber)
+ && TextUtils.equals(minorNumber, channelNumber.minorNumber)
+ && hasDelimiter == channelNumber.hasDelimiter;
+ }
+ return super.equals(obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(majorNumber, hasDelimiter, minorNumber);
+ }
+
public static boolean isChannelNumberDelimiterKey(int keyCode) {
for (int delimiterKeyCode : CHANNEL_DELIMITER_KEYCODES) {
if (delimiterKeyCode == keyCode) {
@@ -84,22 +101,22 @@ public final class ChannelNumber implements Comparable<ChannelNumber> {
return false;
}
+ /**
+ * Returns the ChannelNumber instance.
+ * <p>
+ * Note that all the channel number argument should be normalized by
+ * {@link Channel#normalizeDisplayNumber}. The channels retrieved from
+ * {@link ChannelDataManager} are already normalized.
+ */
public static ChannelNumber parseChannelNumber(String number) {
if (number == null) {
return null;
}
ChannelNumber ret = new ChannelNumber();
- int indexOfDelimiter = -1;
- for (String delimiter : CHANNEL_DELIMITERS) {
- indexOfDelimiter = number.indexOf(delimiter);
- if (indexOfDelimiter >= 0) {
- break;
- }
- }
+ int indexOfDelimiter = number.indexOf(Channel.CHANNEL_NUMBER_DELIMITER);
if (indexOfDelimiter == 0 || indexOfDelimiter == number.length() - 1) {
return null;
- }
- if (indexOfDelimiter < 0) {
+ } else if (indexOfDelimiter < 0) {
ret.majorNumber = number;
if (!isInteger(ret.majorNumber)) {
return null;
@@ -115,25 +132,31 @@ public final class ChannelNumber implements Comparable<ChannelNumber> {
return ret;
}
+ /**
+ * Compares the channel numbers.
+ * <p>
+ * Note that all the channel number arguments should be normalized by
+ * {@link Channel#normalizeDisplayNumber}. The channels retrieved from
+ * {@link ChannelDataManager} are already normalized.
+ */
public static int compare(String lhs, String rhs) {
ChannelNumber lhsNumber = parseChannelNumber(lhs);
ChannelNumber rhsNumber = parseChannelNumber(rhs);
+ // Null first
if (lhsNumber == null && rhsNumber == null) {
- return 0;
+ return StringUtils.compare(lhs, rhs);
} else if (lhsNumber == null /* && rhsNumber != null */) {
return -1;
- } else if (lhsNumber != null && rhsNumber == null) {
+ } else if (rhsNumber == null) {
return 1;
}
return lhsNumber.compareTo(rhsNumber);
}
- public static boolean isInteger(String string) {
+ private static boolean isInteger(String string) {
try {
Integer.parseInt(string);
- } catch(NumberFormatException e) {
- return false;
- } catch(NullPointerException e) {
+ } catch(NumberFormatException | NullPointerException e) {
return false;
}
return true;
diff --git a/src/com/android/tv/data/InternalDataUtils.java b/src/com/android/tv/data/InternalDataUtils.java
index 6054f089..e33ca18f 100644
--- a/src/com/android/tv/data/InternalDataUtils.java
+++ b/src/com/android/tv/data/InternalDataUtils.java
@@ -21,7 +21,7 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.tv.data.Program.CriticScore;
-import com.android.tv.dvr.RecordedProgram;
+import com.android.tv.dvr.data.RecordedProgram;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
diff --git a/src/com/android/tv/data/PreviewDataManager.java b/src/com/android/tv/data/PreviewDataManager.java
new file mode 100644
index 00000000..01a58520
--- /dev/null
+++ b/src/com/android/tv/data/PreviewDataManager.java
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) 2017 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.tv.data;
+
+import android.annotation.TargetApi;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.media.tv.TvContract;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.support.annotation.IntDef;
+import android.support.annotation.MainThread;
+import android.support.media.tv.ChannelLogoUtils;
+import android.support.media.tv.PreviewProgram;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.tv.R;
+import com.android.tv.util.PermissionUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+/**
+ * Class to manage the preview data.
+ */
+@TargetApi(Build.VERSION_CODES.O)
+@MainThread
+public class PreviewDataManager {
+ private static final String TAG = "PreviewDataManager";
+ // STOPSHIP: set it to false.
+ private static final boolean DEBUG = true;
+
+ /**
+ * Invalid preview channel ID.
+ */
+ public static final long INVALID_PREVIEW_CHANNEL_ID = -1;
+ @IntDef({TYPE_DEFAULT_PREVIEW_CHANNEL, TYPE_RECORDED_PROGRAM_PREVIEW_CHANNEL})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PreviewChannelType{}
+
+ /**
+ * Type of default preview channel
+ */
+ public static final long TYPE_DEFAULT_PREVIEW_CHANNEL = 1;
+ /**
+ * Type of recorded program channel
+ */
+ public static final long TYPE_RECORDED_PROGRAM_PREVIEW_CHANNEL = 2;
+
+ private final Context mContext;
+ private final ContentResolver mContentResolver;
+ private boolean mLoadFinished;
+ private PreviewData mPreviewData = new PreviewData();
+ private final Set<PreviewDataListener> mPreviewDataListeners = new CopyOnWriteArraySet<>();
+
+ private QueryPreviewDataTask mQueryPreviewTask;
+ private final Map<Long, CreatePreviewChannelTask> mCreatePreviewChannelTasks =
+ new HashMap<>();
+ private final Map<Long, UpdatePreviewProgramTask> mUpdatePreviewProgramTasks = new HashMap<>();
+
+ private final int mPreviewChannelLogoWidth;
+ private final int mPreviewChannelLogoHeight;
+
+ public PreviewDataManager(Context context) {
+ mContext = context.getApplicationContext();
+ mContentResolver = context.getContentResolver();
+ mPreviewChannelLogoWidth = mContext.getResources().getDimensionPixelSize(
+ R.dimen.preview_channel_logo_width);
+ mPreviewChannelLogoHeight = mContext.getResources().getDimensionPixelSize(
+ R.dimen.preview_channel_logo_height);
+ }
+
+ /**
+ * Starts the preview data manager.
+ */
+ public void start() {
+ if (mQueryPreviewTask == null) {
+ mQueryPreviewTask = new QueryPreviewDataTask();
+ mQueryPreviewTask.execute();
+ }
+ }
+
+ /**
+ * Stops the preview data manager.
+ */
+ public void stop() {
+ if (mQueryPreviewTask != null) {
+ mQueryPreviewTask.cancel(true);
+ }
+ for (CreatePreviewChannelTask createPreviewChannelTask
+ : mCreatePreviewChannelTasks.values()) {
+ createPreviewChannelTask.cancel(true);
+ }
+ for (UpdatePreviewProgramTask updatePreviewProgramTask
+ : mUpdatePreviewProgramTasks.values()) {
+ updatePreviewProgramTask.cancel(true);
+ }
+
+ mQueryPreviewTask = null;
+ mCreatePreviewChannelTasks.clear();
+ mUpdatePreviewProgramTasks.clear();
+ }
+
+ /**
+ * Gets preview channel ID from the preview channel type.
+ */
+ public @PreviewChannelType long getPreviewChannelId(long previewChannelType) {
+ return mPreviewData.getPreviewChannelId(previewChannelType);
+ }
+
+ /**
+ * Creates default preview channel.
+ */
+ public void createDefaultPreviewChannel(
+ OnPreviewChannelCreationResultListener onPreviewChannelCreationResultListener) {
+ createPreviewChannel(TYPE_DEFAULT_PREVIEW_CHANNEL, onPreviewChannelCreationResultListener);
+ }
+
+ /**
+ * Creates a preview channel for specific channel type.
+ */
+ public void createPreviewChannel(@PreviewChannelType long previewChannelType,
+ OnPreviewChannelCreationResultListener onPreviewChannelCreationResultListener) {
+ CreatePreviewChannelTask currentRunningCreateTask =
+ mCreatePreviewChannelTasks.get(previewChannelType);
+ if (currentRunningCreateTask == null) {
+ CreatePreviewChannelTask createPreviewChannelTask = new CreatePreviewChannelTask(
+ previewChannelType);
+ createPreviewChannelTask.addOnPreviewChannelCreationResultListener(
+ onPreviewChannelCreationResultListener);
+ createPreviewChannelTask.execute();
+ mCreatePreviewChannelTasks.put(previewChannelType, createPreviewChannelTask);
+ } else {
+ currentRunningCreateTask.addOnPreviewChannelCreationResultListener(
+ onPreviewChannelCreationResultListener);
+ }
+ }
+
+ /**
+ * Returns {@code true} if the preview data is loaded.
+ */
+ public boolean isLoadFinished() {
+ return mLoadFinished;
+ }
+
+ /**
+ * Adds listener.
+ */
+ public void addListener(PreviewDataListener previewDataListener) {
+ mPreviewDataListeners.add(previewDataListener);
+ }
+
+ /**
+ * Removes listener.
+ */
+ public void removeListener(PreviewDataListener previewDataListener) {
+ mPreviewDataListeners.remove(previewDataListener);
+ }
+
+ /**
+ * Updates the preview programs table for a specific preview channel.
+ */
+ public void updatePreviewProgramsForChannel(long previewChannelId,
+ Set<PreviewProgramContent> programs, PreviewDataListener previewDataListener) {
+ UpdatePreviewProgramTask currentRunningUpdateTask =
+ mUpdatePreviewProgramTasks.get(previewChannelId);
+ if (currentRunningUpdateTask != null
+ && currentRunningUpdateTask.getPrograms().equals(programs)) {
+ currentRunningUpdateTask.addPreviewDataListener(previewDataListener);
+ return;
+ }
+ UpdatePreviewProgramTask updatePreviewProgramTask =
+ new UpdatePreviewProgramTask(previewChannelId, programs);
+ updatePreviewProgramTask.addPreviewDataListener(previewDataListener);
+ if (currentRunningUpdateTask != null) {
+ currentRunningUpdateTask.cancel(true);
+ currentRunningUpdateTask.saveStatus();
+ updatePreviewProgramTask.addPreviewDataListeners(
+ currentRunningUpdateTask.getPreviewDataListeners());
+ }
+ updatePreviewProgramTask.execute();
+ mUpdatePreviewProgramTasks.put(previewChannelId, updatePreviewProgramTask);
+ }
+
+ private void notifyPreviewDataLoadFinished() {
+ for (PreviewDataListener l : mPreviewDataListeners) {
+ l.onPreviewDataLoadFinished();
+ }
+ }
+
+ public interface PreviewDataListener {
+ /**
+ * Called when the preview data is loaded.
+ */
+ void onPreviewDataLoadFinished();
+
+ /**
+ * Called when the preview data is updated.
+ */
+ void onPreviewDataUpdateFinished();
+ }
+
+ public interface OnPreviewChannelCreationResultListener {
+ /**
+ * Called when the creation of preview channel is finished.
+ * @param createdPreviewChannelId The preview channel ID if created successfully,
+ * otherwise it's {@value #INVALID_PREVIEW_CHANNEL_ID}.
+ */
+ void onPreviewChannelCreationResult(long createdPreviewChannelId);
+ }
+
+ private final class QueryPreviewDataTask extends AsyncTask<Void, Void, PreviewData> {
+ private final String PARAM_PREVIEW = "preview";
+ private final String mChannelSelection = TvContract.Channels.COLUMN_PACKAGE_NAME + "=?";
+
+ @Override
+ protected PreviewData doInBackground(Void... voids) {
+ // Query preview channels and programs.
+ if (DEBUG) Log.d(TAG, "QueryPreviewDataTask.doInBackground");
+ PreviewData previewData = new PreviewData();
+ try {
+ Uri previewChannelsUri =
+ PreviewDataUtils.addQueryParamToUri(
+ TvContract.Channels.CONTENT_URI,
+ new Pair<>(PARAM_PREVIEW, String.valueOf(true)));
+ String packageName = mContext.getPackageName();
+ if (PermissionUtils.hasAccessAllEpg(mContext)) {
+ try (Cursor cursor =
+ mContentResolver.query(
+ previewChannelsUri,
+ android.support.media.tv.Channel.PROJECTION,
+ mChannelSelection,
+ new String[] {packageName},
+ null)) {
+ if (cursor != null) {
+ while (cursor.moveToNext()) {
+ android.support.media.tv.Channel previewChannel =
+ android.support.media.tv.Channel.fromCursor(cursor);
+ Long previewChannelType = previewChannel.getInternalProviderFlag1();
+ if (previewChannelType != null) {
+ previewData.addPreviewChannelId(
+ previewChannelType, previewChannel.getId());
+ }
+ }
+ }
+ }
+ } else {
+ try (Cursor cursor =
+ mContentResolver.query(
+ previewChannelsUri,
+ android.support.media.tv.Channel.PROJECTION,
+ null,
+ null,
+ null)) {
+ if (cursor != null) {
+ while (cursor.moveToNext()) {
+ android.support.media.tv.Channel previewChannel =
+ android.support.media.tv.Channel.fromCursor(cursor);
+ Long previewChannelType = previewChannel.getInternalProviderFlag1();
+ if (previewChannel.getPackageName() == packageName
+ && previewChannelType != null) {
+ previewData.addPreviewChannelId(
+ previewChannelType, previewChannel.getId());
+ }
+ }
+ }
+ }
+ }
+
+ for (long previewChannelId : previewData.getAllPreviewChannelIds().values()) {
+ Uri previewProgramsUriForPreviewChannel =
+ TvContract.buildPreviewProgramsUriForChannel(previewChannelId);
+ try (Cursor previewProgramCursor =
+ mContentResolver.query(
+ previewProgramsUriForPreviewChannel,
+ PreviewProgram.PROJECTION,
+ null,
+ null,
+ null)) {
+ if (previewProgramCursor != null) {
+ while (previewProgramCursor.moveToNext()) {
+ PreviewProgram previewProgram =
+ PreviewProgram.fromCursor(previewProgramCursor);
+ previewData.addPreviewProgram(previewProgram);
+ }
+ }
+ }
+ }
+ } catch (SQLException e) {
+ Log.w(TAG, "Unable to get preview data", e);
+ }
+ return previewData;
+ }
+
+ @Override
+ protected void onPostExecute(PreviewData result) {
+ super.onPostExecute(result);
+ if (mQueryPreviewTask == this) {
+ mQueryPreviewTask = null;
+ mPreviewData = new PreviewData(result);
+ mLoadFinished = true;
+ notifyPreviewDataLoadFinished();
+ }
+ }
+ }
+
+ private final class CreatePreviewChannelTask extends AsyncTask<Void, Void, Long> {
+ private final long mPreviewChannelType;
+ private Set<OnPreviewChannelCreationResultListener>
+ mOnPreviewChannelCreationResultListeners = new CopyOnWriteArraySet<>();
+
+ public CreatePreviewChannelTask(long previewChannelType) {
+ mPreviewChannelType = previewChannelType;
+ }
+
+ public void addOnPreviewChannelCreationResultListener(
+ OnPreviewChannelCreationResultListener onPreviewChannelCreationResultListener) {
+ if (onPreviewChannelCreationResultListener != null) {
+ mOnPreviewChannelCreationResultListeners.add(
+ onPreviewChannelCreationResultListener);
+ }
+ }
+
+ @Override
+ protected Long doInBackground(Void... params) {
+ if (DEBUG) Log.d(TAG, "CreatePreviewChannelTask.doInBackground");
+ long previewChannelId;
+ try {
+ Uri channelUri = mContentResolver.insert(TvContract.Channels.CONTENT_URI,
+ PreviewDataUtils.createPreviewChannel(mContext, mPreviewChannelType)
+ .toContentValues());
+ if (channelUri != null) {
+ previewChannelId = ContentUris.parseId(channelUri);
+ } else {
+ Log.e(TAG, "Fail to insert preview channel");
+ return INVALID_PREVIEW_CHANNEL_ID;
+ }
+ } catch (UnsupportedOperationException | NumberFormatException e) {
+ Log.e(TAG, "Fail to get channel ID");
+ return INVALID_PREVIEW_CHANNEL_ID;
+ }
+ Drawable appIcon = mContext.getApplicationInfo().loadIcon(mContext.getPackageManager());
+ if (appIcon != null && appIcon instanceof BitmapDrawable) {
+ ChannelLogoUtils.storeChannelLogo(mContext, previewChannelId,
+ Bitmap.createScaledBitmap(((BitmapDrawable) appIcon).getBitmap(),
+ mPreviewChannelLogoWidth, mPreviewChannelLogoHeight, false));
+ }
+ return previewChannelId;
+ }
+
+ @Override
+ protected void onPostExecute(Long result) {
+ super.onPostExecute(result);
+ if (result != INVALID_PREVIEW_CHANNEL_ID) {
+ mPreviewData.addPreviewChannelId(mPreviewChannelType, result);
+ }
+ for (OnPreviewChannelCreationResultListener onPreviewChannelCreationResultListener
+ : mOnPreviewChannelCreationResultListeners) {
+ onPreviewChannelCreationResultListener.onPreviewChannelCreationResult(result);
+ }
+ mCreatePreviewChannelTasks.remove(mPreviewChannelType);
+ }
+ }
+
+ /**
+ * Updates the whole data which belongs to the package in preview programs table for a
+ * specific preview channel with a set of {@link PreviewProgramContent}.
+ */
+ private final class UpdatePreviewProgramTask extends AsyncTask<Void, Void, Void> {
+ private long mPreviewChannelId;
+ private Set<PreviewProgramContent> mPrograms;
+ private Map<Long, Long> mCurrentProgramId2PreviewProgramId;
+ private Set<PreviewDataListener> mPreviewDataListeners = new CopyOnWriteArraySet<>();
+
+ public UpdatePreviewProgramTask(long previewChannelId,
+ Set<PreviewProgramContent> programs) {
+ mPreviewChannelId = previewChannelId;
+ mPrograms = programs;
+ if (mPreviewData.getPreviewProgramIds(previewChannelId) == null) {
+ mCurrentProgramId2PreviewProgramId = new HashMap<>();
+ } else {
+ mCurrentProgramId2PreviewProgramId = new HashMap<>(
+ mPreviewData.getPreviewProgramIds(previewChannelId));
+ }
+ }
+
+ public void addPreviewDataListener(PreviewDataListener previewDataListener) {
+ if (previewDataListener != null) {
+ mPreviewDataListeners.add(previewDataListener);
+ }
+ }
+
+ public void addPreviewDataListeners(Set<PreviewDataListener> previewDataListeners) {
+ if (previewDataListeners != null) {
+ mPreviewDataListeners.addAll(previewDataListeners);
+ }
+ }
+
+ public Set<PreviewProgramContent> getPrograms() {
+ return mPrograms;
+ }
+
+ public Set<PreviewDataListener> getPreviewDataListeners() {
+ return mPreviewDataListeners;
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ if (DEBUG) Log.d(TAG, "UpdatePreviewProgamTask.doInBackground");
+ Map<Long, Long> uncheckedPrograms = new HashMap<>(mCurrentProgramId2PreviewProgramId);
+ for (PreviewProgramContent program : mPrograms) {
+ if (isCancelled()) {
+ return null;
+ }
+ Long existingPreviewProgramId = uncheckedPrograms.remove(program.getId());
+ if (existingPreviewProgramId != null) {
+ if (DEBUG) Log.d(TAG, "Preview program " + existingPreviewProgramId + " " +
+ "already exists for program " + program.getId());
+ continue;
+ }
+ try {
+ Uri programUri = mContentResolver.insert(TvContract.PreviewPrograms.CONTENT_URI,
+ PreviewDataUtils.createPreviewProgramFromContent(program)
+ .toContentValues());
+ if (programUri != null) {
+ long previewProgramId = ContentUris.parseId(programUri);
+ mCurrentProgramId2PreviewProgramId.put(program.getId(), previewProgramId);
+ if (DEBUG) Log.d(TAG, "Add new preview program " + previewProgramId);
+ } else {
+ Log.e(TAG, "Fail to insert preview program");
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Fail to get preview program ID");
+ }
+ }
+
+ for (Long key : uncheckedPrograms.keySet()) {
+ if (isCancelled()) {
+ return null;
+ }
+ try {
+ if (DEBUG) Log.d(TAG, "Remove preview program " + uncheckedPrograms.get(key));
+ mContentResolver.delete(TvContract.buildPreviewProgramUri(
+ uncheckedPrograms.get(key)), null, null);
+ mCurrentProgramId2PreviewProgramId.remove(key);
+ } catch (Exception e) {
+ Log.e(TAG, "Fail to remove preview program " + uncheckedPrograms.get(key));
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void result) {
+ super.onPostExecute(result);
+ mPreviewData.setPreviewProgramIds(
+ mPreviewChannelId, mCurrentProgramId2PreviewProgramId);
+ mUpdatePreviewProgramTasks.remove(mPreviewChannelId);
+ for (PreviewDataListener previewDataListener : mPreviewDataListeners) {
+ previewDataListener.onPreviewDataUpdateFinished();
+ }
+ }
+
+ public void saveStatus() {
+ mPreviewData.setPreviewProgramIds(
+ mPreviewChannelId, mCurrentProgramId2PreviewProgramId);
+ }
+ }
+
+ /**
+ * Class to store the query result of preview data.
+ */
+ private static final class PreviewData {
+ private Map<Long, Long> mPreviewChannelType2Id = new HashMap<>();
+ private Map<Long, Map<Long, Long>> mProgramId2PreviewProgramId = new HashMap<>();
+
+ PreviewData() {
+ mPreviewChannelType2Id = new HashMap<>();
+ mProgramId2PreviewProgramId = new HashMap<>();
+ }
+
+ PreviewData(PreviewData previewData) {
+ mPreviewChannelType2Id = new HashMap<>(previewData.mPreviewChannelType2Id);
+ mProgramId2PreviewProgramId = new HashMap<>(previewData.mProgramId2PreviewProgramId);
+ }
+
+ public void addPreviewProgram(PreviewProgram previewProgram) {
+ long previewChannelId = previewProgram.getChannelId();
+ Map<Long, Long> programId2PreviewProgram =
+ mProgramId2PreviewProgramId.get(previewChannelId);
+ if (programId2PreviewProgram == null) {
+ programId2PreviewProgram = new HashMap<>();
+ }
+ mProgramId2PreviewProgramId.put(previewChannelId, programId2PreviewProgram);
+ if (previewProgram.getInternalProviderId() != null) {
+ programId2PreviewProgram.put(
+ Long.parseLong(previewProgram.getInternalProviderId()),
+ previewProgram.getId());
+ }
+ }
+
+ public @PreviewChannelType long getPreviewChannelId(long previewChannelType) {
+ Long result = mPreviewChannelType2Id.get(previewChannelType);
+ return result == null ? INVALID_PREVIEW_CHANNEL_ID : result;
+ }
+
+ public Map<Long, Long> getAllPreviewChannelIds() {
+ return mPreviewChannelType2Id;
+ }
+
+ public void addPreviewChannelId(long previewChannelType, long previewChannelId) {
+ mPreviewChannelType2Id.put(previewChannelType, previewChannelId);
+ }
+
+ public void removePreviewChannelId(long previewChannelType) {
+ mPreviewChannelType2Id.remove(previewChannelType);
+ }
+
+ public void removePreviewChannel(long previewChannelId) {
+ removePreviewChannelId(previewChannelId);
+ removePreviewProgramIds(previewChannelId);
+ }
+
+ public Map<Long, Long> getPreviewProgramIds(long previewChannelId) {
+ return mProgramId2PreviewProgramId.get(previewChannelId);
+ }
+
+ public Map<Long, Map<Long, Long>> getAllPreviewProgramIds() {
+ return mProgramId2PreviewProgramId;
+ }
+
+ public void setPreviewProgramIds(
+ long previewChannelId, Map<Long, Long> programId2PreviewProgramId) {
+ mProgramId2PreviewProgramId.put(previewChannelId, programId2PreviewProgramId);
+ }
+
+ public void removePreviewProgramIds(long previewChannelId) {
+ mProgramId2PreviewProgramId.remove(previewChannelId);
+ }
+ }
+
+ /**
+ * A utils class for preview data.
+ */
+ public final static class PreviewDataUtils {
+ /**
+ * Creates a preview channel.
+ */
+ public static android.support.media.tv.Channel createPreviewChannel(
+ Context context, @PreviewChannelType long previewChannelType) {
+ if (previewChannelType == TYPE_RECORDED_PROGRAM_PREVIEW_CHANNEL) {
+ return createRecordedProgramPreviewChannel(context, previewChannelType);
+ }
+ return createDefaultPreviewChannel(context, previewChannelType);
+ }
+
+ private static android.support.media.tv.Channel createDefaultPreviewChannel(
+ Context context, @PreviewChannelType long previewChannelType) {
+ android.support.media.tv.Channel.Builder builder =
+ new android.support.media.tv.Channel.Builder();
+ CharSequence appLabel =
+ context.getApplicationInfo().loadLabel(context.getPackageManager());
+ CharSequence appDescription =
+ context.getApplicationInfo().loadDescription(context.getPackageManager());
+ builder.setType(TvContract.Channels.TYPE_PREVIEW)
+ .setDisplayName(appLabel == null ? null : appLabel.toString())
+ .setDescription(appDescription == null ? null : appDescription.toString())
+ .setAppLinkIntentUri(TvContract.Channels.CONTENT_URI)
+ .setInternalProviderFlag1(previewChannelType);
+ return builder.build();
+ }
+
+ private static android.support.media.tv.Channel createRecordedProgramPreviewChannel(
+ Context context, @PreviewChannelType long previewChannelType) {
+ android.support.media.tv.Channel.Builder builder =
+ new android.support.media.tv.Channel.Builder();
+ builder.setType(TvContract.Channels.TYPE_PREVIEW)
+ .setDisplayName(context.getResources().getString(
+ R.string.recorded_programs_preview_channel))
+ .setAppLinkIntentUri(TvContract.Channels.CONTENT_URI)
+ .setInternalProviderFlag1(previewChannelType);
+ return builder.build();
+ }
+
+ /**
+ * Creates a preview program.
+ */
+ public static PreviewProgram createPreviewProgramFromContent(
+ PreviewProgramContent program) {
+ PreviewProgram.Builder builder = new PreviewProgram.Builder();
+ builder.setChannelId(program.getPreviewChannelId())
+ .setType(program.getType())
+ .setLive(program.getLive())
+ .setTitle(program.getTitle())
+ .setDescription(program.getDescription())
+ .setPosterArtUri(program.getPosterArtUri())
+ .setIntentUri(program.getIntentUri())
+ .setPreviewVideoUri(program.getPreviewVideoUri())
+ .setInternalProviderId(Long.toString(program.getId()));
+ return builder.build();
+ }
+
+ /**
+ * Appends query parameters to a Uri.
+ */
+ public static Uri addQueryParamToUri(Uri uri, Pair<String, String> param) {
+ return uri.buildUpon().appendQueryParameter(param.first, param.second).build();
+ }
+ }
+}
diff --git a/src/com/android/tv/data/PreviewProgramContent.java b/src/com/android/tv/data/PreviewProgramContent.java
new file mode 100644
index 00000000..39f5051d
--- /dev/null
+++ b/src/com/android/tv/data/PreviewProgramContent.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2017 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.tv.data;
+
+import android.content.Context;
+import android.media.tv.TvContract;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.data.RecordedProgram;
+
+import java.util.Objects;
+
+/**
+ * A class to store the content of preview programs.
+ */
+public class PreviewProgramContent {
+ private final static String PARAM_INPUT = "input";
+
+ private long mId;
+ private long mPreviewChannelId;
+ private int mType;
+ private boolean mLive;
+ private String mTitle;
+ private String mDescription;
+ private Uri mPosterArtUri;
+ private Uri mIntentUri;
+ private Uri mPreviewVideoUri;
+
+ /**
+ * Create preview program content from {@link Program}
+ */
+ public static PreviewProgramContent createFromProgram(Context context,
+ long previewChannelId, Program program) {
+ Channel channel = TvApplication.getSingletons(context).getChannelDataManager()
+ .getChannel(program.getChannelId());
+ if (channel == null) {
+ return null;
+ }
+ String channelDisplayName = channel.getDisplayName();
+ return new PreviewProgramContent.Builder()
+ .setId(program.getId())
+ .setPreviewChannelId(previewChannelId)
+ .setType(TvContract.PreviewPrograms.TYPE_CHANNEL)
+ .setLive(true)
+ .setTitle(program.getTitle())
+ .setDescription(!TextUtils.isEmpty(channelDisplayName)
+ ? channelDisplayName : channel.getDisplayNumber())
+ .setPosterArtUri(Uri.parse(program.getPosterArtUri()))
+ .setIntentUri(channel.getUri())
+ .setPreviewVideoUri(PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
+ channel.getUri(), new Pair<>(PARAM_INPUT, channel.getInputId())))
+ .build();
+ }
+
+ /**
+ * Create preview program content from {@link RecordedProgram}
+ */
+ public static PreviewProgramContent createFromRecordedProgram(
+ Context context, long previewChannelId, RecordedProgram recordedProgram) {
+ Channel channel = TvApplication.getSingletons(context).getChannelDataManager()
+ .getChannel(recordedProgram.getChannelId());
+ String channelDisplayName = null;
+ if (channel != null) {
+ channelDisplayName = channel.getDisplayName();
+ }
+ Uri recordedProgramUri = TvContract.buildRecordedProgramUri(recordedProgram.getId());
+ return new PreviewProgramContent.Builder()
+ .setId(recordedProgram.getId())
+ .setPreviewChannelId(previewChannelId)
+ .setType(TvContract.PreviewPrograms.TYPE_CLIP)
+ .setTitle(recordedProgram.getTitle())
+ .setDescription(channelDisplayName != null ? channelDisplayName : "")
+ .setPosterArtUri(Uri.parse(recordedProgram.getPosterArtUri()))
+ .setIntentUri(recordedProgramUri)
+ .setPreviewVideoUri(PreviewDataManager.PreviewDataUtils.addQueryParamToUri(
+ recordedProgramUri, new Pair<>(PARAM_INPUT, recordedProgram.getInputId())))
+ .build();
+ }
+
+ private PreviewProgramContent() { }
+
+ public void copyFrom(PreviewProgramContent other) {
+ if (this == other) {
+ return;
+ }
+ mId = other.mId;
+ mPreviewChannelId = other.mPreviewChannelId;
+ mType = other.mType;
+ mLive = other.mLive;
+ mTitle = other.mTitle;
+ mDescription = other.mDescription;
+ mPosterArtUri = other.mPosterArtUri;
+ mIntentUri = other.mIntentUri;
+ mPreviewVideoUri = other.mPreviewVideoUri;
+ }
+
+ /**
+ * Returns the id, which is an identification. It usually comes from the original data which
+ * create the {@PreviewProgramContent}.
+ */
+ public long getId() {
+ return mId;
+ }
+
+ /**
+ * Returns the preview channel id which the preview program belongs to.
+ */
+ public long getPreviewChannelId() {
+ return mPreviewChannelId;
+ }
+
+ /**
+ * Returns the type of the preview program.
+ */
+ public int getType() {
+ return mType;
+ }
+
+ /**
+ * Returns whether the preview program is live or not.
+ */
+ public boolean getLive() {
+ return mLive;
+ }
+
+ /**
+ * Returns the title of the preview program.
+ */
+ public String getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Returns the description of the preview program.
+ */
+ public String getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Returns the poster art uri of the preview program.
+ */
+ public Uri getPosterArtUri() {
+ return mPosterArtUri;
+ }
+
+ /**
+ * Returns the intent uri of the preview program.
+ */
+ public Uri getIntentUri() {
+ return mIntentUri;
+ }
+
+ /**
+ * Returns the preview video uri of the preview program.
+ */
+ public Uri getPreviewVideoUri() {
+ return mPreviewVideoUri;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof PreviewProgramContent)) {
+ return false;
+ }
+ PreviewProgramContent previewProgramContent = (PreviewProgramContent) other;
+ return previewProgramContent.mId == mId
+ && previewProgramContent.mPreviewChannelId == mPreviewChannelId
+ && previewProgramContent.mType == mType
+ && previewProgramContent.mLive == mLive
+ && Objects.equals(previewProgramContent.mTitle, mTitle)
+ && Objects.equals(previewProgramContent.mDescription, mDescription)
+ && Objects.equals(previewProgramContent.mPosterArtUri, mPosterArtUri)
+ && Objects.equals(previewProgramContent.mIntentUri, mIntentUri)
+ && Objects.equals(previewProgramContent.mPreviewVideoUri, mPreviewVideoUri);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId, mPreviewChannelId, mType, mLive, mTitle, mDescription,
+ mPosterArtUri, mIntentUri, mPreviewVideoUri);
+ }
+
+ public static final class Builder {
+ private final PreviewProgramContent mPreviewProgramContent;
+
+ public Builder() {
+ mPreviewProgramContent = new PreviewProgramContent();
+ }
+
+ public Builder setId(long id) {
+ mPreviewProgramContent.mId = id;
+ return this;
+ }
+
+ public Builder setPreviewChannelId(long previewChannelId) {
+ mPreviewProgramContent.mPreviewChannelId = previewChannelId;
+ return this;
+ }
+
+ public Builder setType(int type) {
+ mPreviewProgramContent.mType = type;
+ return this;
+ }
+
+ public Builder setLive(boolean live) {
+ mPreviewProgramContent.mLive = live;
+ return this;
+ }
+
+ public Builder setTitle(String title) {
+ mPreviewProgramContent.mTitle = title;
+ return this;
+ }
+
+ public Builder setDescription(String description) {
+ mPreviewProgramContent.mDescription = description;
+ return this;
+ }
+
+ public Builder setPosterArtUri(Uri posterArtUri) {
+ mPreviewProgramContent.mPosterArtUri = posterArtUri;
+ return this;
+ }
+
+ public Builder setIntentUri(Uri intentUri) {
+ mPreviewProgramContent.mIntentUri = intentUri;
+ return this;
+ }
+
+ public Builder setPreviewVideoUri(Uri previewVideoUri) {
+ mPreviewProgramContent.mPreviewVideoUri = previewVideoUri;
+ return this;
+ }
+
+ public PreviewProgramContent build() {
+ PreviewProgramContent previewProgramContent = new PreviewProgramContent();
+ previewProgramContent.copyFrom(mPreviewProgramContent);
+ return previewProgramContent;
+ }
+ }
+}
diff --git a/src/com/android/tv/data/Program.java b/src/com/android/tv/data/Program.java
index b9cd3d8d..071c7024 100644
--- a/src/com/android/tv/data/Program.java
+++ b/src/com/android/tv/data/Program.java
@@ -16,21 +16,23 @@
package com.android.tv.data;
+import android.annotation.SuppressLint;
+import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.media.tv.TvContentRating;
import android.media.tv.TvContract;
+import android.media.tv.TvContract.Programs;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.support.annotation.VisibleForTesting;
-import android.support.v4.os.BuildCompat;
import android.text.TextUtils;
import android.util.Log;
-import com.android.tv.R;
import com.android.tv.common.BuildConfig;
import com.android.tv.common.CollectionUtils;
import com.android.tv.common.TvContentRatingCache;
@@ -88,9 +90,11 @@ public final class Program extends BaseProgram implements Comparable<Program>, P
public static final String[] PROJECTION = createProjection();
private static String[] createProjection() {
- return CollectionUtils
- .concatAll(PROJECTION_BASE, BuildCompat.isAtLeastN() ? PROJECTION_ADDED_IN_NYC
- : PROJECTION_DEPRECATED_IN_NYC);
+ return CollectionUtils.concatAll(
+ PROJECTION_BASE,
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
+ ? PROJECTION_ADDED_IN_NYC
+ : PROJECTION_DEPRECATED_IN_NYC);
}
/**
@@ -135,7 +139,7 @@ public final class Program extends BaseProgram implements Comparable<Program>, P
InternalDataUtils.deserializeInternalProviderData(cursor.getBlob(index), builder);
}
index++;
- if (BuildCompat.isAtLeastN()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
builder.setSeasonNumber(cursor.getString(index++));
builder.setSeasonTitle(cursor.getString(index++));
builder.setEpisodeNumber(cursor.getString(index++));
@@ -213,11 +217,6 @@ public final class Program extends BaseProgram implements Comparable<Program>, P
private TvContentRating[] mContentRatings;
private boolean mRecordingProhibited;
- /**
- * TODO(DVR): Need to fill the following data.
- */
- private boolean mRecordingScheduled;
-
private Program() {
// Do nothing.
}
@@ -268,46 +267,12 @@ public final class Program extends BaseProgram implements Comparable<Program>, P
/**
* Returns the episode title.
*/
- public String getEpisodeTitle() {
- return mEpisodeTitle;
- }
-
- /**
- * Returns season number, episode number and episode title for display.
- */
@Override
- public String getEpisodeDisplayTitle(Context context) {
- if (!TextUtils.isEmpty(mEpisodeNumber)) {
- String episodeTitle = mEpisodeTitle == null ? "" : mEpisodeTitle;
- if (TextUtils.equals(mSeasonNumber, "0")) {
- // Do not show "S0: ".
- return String.format(context.getResources().getString(
- R.string.display_episode_title_format_no_season_number),
- mEpisodeNumber, episodeTitle);
- } else {
- return String.format(context.getResources().getString(
- R.string.display_episode_title_format),
- mSeasonNumber, mEpisodeNumber, episodeTitle);
- }
- }
+ public String getEpisodeTitle() {
return mEpisodeTitle;
}
@Override
- public String getTitleWithEpisodeNumber(Context context) {
- if (TextUtils.isEmpty(mTitle)) {
- return mTitle;
- }
- if (TextUtils.isEmpty(mSeasonNumber) || mSeasonNumber.equals("0")) {
- return TextUtils.isEmpty(mEpisodeNumber) ? mTitle : context.getString(
- R.string.program_title_with_episode_number_no_season, mTitle, mEpisodeNumber);
- } else {
- return context.getString(R.string.program_title_with_episode_number, mTitle,
- mSeasonNumber, mEpisodeNumber);
- }
- }
-
- @Override
public String getSeasonNumber() {
return mSeasonNumber;
}
@@ -361,6 +326,8 @@ public final class Program extends BaseProgram implements Comparable<Program>, P
return mCriticScores;
}
+ @Nullable
+ @Override
public TvContentRating[] getContentRatings() {
return mContentRatings;
}
@@ -495,6 +462,63 @@ public final class Program extends BaseProgram implements Comparable<Program>, P
return builder.append("}").toString();
}
+ /**
+ * Translates a {@link Program} to {@link ContentValues} that are ready to be written into
+ * Database.
+ */
+ @SuppressLint("InlinedApi")
+ @SuppressWarnings("deprecation")
+ public static ContentValues toContentValues(Program program) {
+ ContentValues values = new ContentValues();
+ values.put(TvContract.Programs.COLUMN_CHANNEL_ID, program.getChannelId());
+ putValue(values, TvContract.Programs.COLUMN_TITLE, program.getTitle());
+ putValue(values, TvContract.Programs.COLUMN_EPISODE_TITLE, program.getEpisodeTitle());
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ putValue(values, TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER,
+ program.getSeasonNumber());
+ putValue(values, TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER,
+ program.getEpisodeNumber());
+ } else {
+ putValue(values, TvContract.Programs.COLUMN_SEASON_NUMBER, program.getSeasonNumber());
+ putValue(values, TvContract.Programs.COLUMN_EPISODE_NUMBER, program.getEpisodeNumber());
+ }
+ putValue(values, TvContract.Programs.COLUMN_SHORT_DESCRIPTION, program.getDescription());
+ putValue(values, TvContract.Programs.COLUMN_LONG_DESCRIPTION, program.getLongDescription());
+ putValue(values, TvContract.Programs.COLUMN_POSTER_ART_URI, program.getPosterArtUri());
+ putValue(values, TvContract.Programs.COLUMN_THUMBNAIL_URI, program.getThumbnailUri());
+ String[] canonicalGenres = program.getCanonicalGenres();
+ if (canonicalGenres != null && canonicalGenres.length > 0) {
+ putValue(values, TvContract.Programs.COLUMN_CANONICAL_GENRE,
+ TvContract.Programs.Genres.encode(canonicalGenres));
+ } else {
+ putValue(values, TvContract.Programs.COLUMN_CANONICAL_GENRE, "");
+ }
+ putValue(values, Programs.COLUMN_CONTENT_RATING,
+ TvContentRatingCache.contentRatingsToString(program.getContentRatings()));
+ values.put(TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS,
+ program.getStartTimeUtcMillis());
+ values.put(TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS, program.getEndTimeUtcMillis());
+ putValue(values, TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA,
+ InternalDataUtils.serializeInternalProviderData(program));
+ return values;
+ }
+
+ private static void putValue(ContentValues contentValues, String key, String value) {
+ if (TextUtils.isEmpty(value)) {
+ contentValues.putNull(key);
+ } else {
+ contentValues.put(key, value);
+ }
+ }
+
+ private static void putValue(ContentValues contentValues, String key, byte[] value) {
+ if (value == null || value.length == 0) {
+ contentValues.putNull(key);
+ } else {
+ contentValues.put(key, value);
+ }
+ }
+
public void copyFrom(Program other) {
if (this == other) {
return;
@@ -524,13 +548,6 @@ public final class Program extends BaseProgram implements Comparable<Program>, P
}
/**
- * Checks whether the program is episodic or not.
- */
- public boolean isEpisodic() {
- return mSeriesId != null;
- }
-
- /**
* A Builder for the Program class
*/
public static final class Builder {
@@ -799,8 +816,12 @@ public final class Program extends BaseProgram implements Comparable<Program>, P
*/
public Program build() {
// Generate the series ID for the episodic program of other TV input.
- if (TextUtils.isEmpty(mProgram.mSeriesId)
+ if (TextUtils.isEmpty(mProgram.mTitle)) {
+ // If title is null, series cannot be generated for this program.
+ setSeriesId(null);
+ } else if (TextUtils.isEmpty(mProgram.mSeriesId)
&& !TextUtils.isEmpty(mProgram.mEpisodeNumber)) {
+ // If series ID is not set, generate it for the episodic program of other TV input.
setSeriesId(BaseProgram.generateSeriesId(mProgram.mPackageName, mProgram.mTitle));
}
Program program = new Program();
@@ -820,17 +841,20 @@ public final class Program extends BaseProgram implements Comparable<Program>, P
}
/**
- * Loads the program poster art and returns it via {@code callback}.<p>
+ * Loads the program poster art and returns it via {@code callback}.
* <p>
* Note that it may directly call {@code callback} if the program poster art already is loaded.
+ *
+ * @return {@code true} if the load is complete and the callback is executed.
*/
@UiThread
- public void loadPosterArt(Context context, int posterArtWidth, int posterArtHeight,
+ public boolean loadPosterArt(Context context, int posterArtWidth, int posterArtHeight,
ImageLoader.ImageLoaderCallback callback) {
if (mPosterArtUri == null) {
- return;
+ return false;
}
- ImageLoader.loadBitmap(context, mPosterArtUri, posterArtWidth, posterArtHeight, callback);
+ return ImageLoader.loadBitmap(
+ context, mPosterArtUri, posterArtWidth, posterArtHeight, callback);
}
public static boolean isDuplicate(Program p1, Program p2) {
diff --git a/src/com/android/tv/data/ProgramDataManager.java b/src/com/android/tv/data/ProgramDataManager.java
index d2af33a7..8cb5e74a 100644
--- a/src/com/android/tv/data/ProgramDataManager.java
+++ b/src/com/android/tv/data/ProgramDataManager.java
@@ -26,6 +26,7 @@ import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.support.annotation.AnyThread;
import android.support.annotation.MainThread;
import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
@@ -35,8 +36,6 @@ import android.util.LruCache;
import com.android.tv.common.MemoryManageable;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.epg.EpgFetcher;
-import com.android.tv.experiments.Experiments;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.Clock;
import com.android.tv.util.MultiLongSparseArray;
@@ -51,6 +50,7 @@ import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@MainThread
@@ -85,10 +85,12 @@ public class ProgramDataManager implements MemoryManageable {
private final Clock mClock;
private final ContentResolver mContentResolver;
private boolean mStarted;
+ // Updated only on the main thread.
+ private volatile boolean mCurrentProgramsLoadFinished;
private ProgramsUpdateTask mProgramsUpdateTask;
private final LongSparseArray<UpdateCurrentProgramForChannelTask> mProgramUpdateTaskMap =
new LongSparseArray<>();
- private final Map<Long, Program> mChannelIdCurrentProgramMap = new HashMap<>();
+ private final Map<Long, Program> mChannelIdCurrentProgramMap = new ConcurrentHashMap<>();
private final MultiLongSparseArray<OnCurrentProgramUpdatedListener>
mChannelId2ProgramUpdatedListeners = new MultiLongSparseArray<>();
private final Handler mHandler;
@@ -109,17 +111,14 @@ public class ProgramDataManager implements MemoryManageable {
private boolean mPauseProgramUpdate = false;
private final LruCache<Long, Program> mZeroLengthProgramCache = new LruCache<>(10);
- private final EpgFetcher mEpgFetcher;
+ @MainThread
public ProgramDataManager(Context context) {
- this(context.getContentResolver(), Clock.SYSTEM, Looper.myLooper(),
- EpgFetcher.getInstance(context));
+ this(context.getContentResolver(), Clock.SYSTEM, Looper.myLooper());
}
@VisibleForTesting
- ProgramDataManager(ContentResolver contentResolver, Clock time, Looper looper,
- EpgFetcher epgFetcher) {
- mEpgFetcher = epgFetcher;
+ ProgramDataManager(ContentResolver contentResolver, Clock time, Looper looper) {
mClock = time;
mContentResolver = contentResolver;
mHandler = new MyHandler(looper);
@@ -175,9 +174,6 @@ public class ProgramDataManager implements MemoryManageable {
}
mContentResolver.registerContentObserver(Programs.CONTENT_URI,
true, mProgramObserver);
- if (mEpgFetcher != null && Experiments.CLOUD_EPG.get()) {
- mEpgFetcher.start();
- }
}
/**
@@ -190,10 +186,6 @@ public class ProgramDataManager implements MemoryManageable {
return;
}
mStarted = false;
-
- if (mEpgFetcher != null) {
- mEpgFetcher.stop();
- }
mContentResolver.unregisterContentObserver(mProgramObserver);
mHandler.removeCallbacksAndMessages(null);
@@ -205,13 +197,23 @@ public class ProgramDataManager implements MemoryManageable {
}
}
- /**
- * Returns the current program at the specified channel.
- */
+ @AnyThread
+ public boolean isCurrentProgramsLoadFinished() {
+ return mCurrentProgramsLoadFinished;
+ }
+
+ /** Returns the current program at the specified channel. */
+ @AnyThread
public Program getCurrentProgram(long channelId) {
return mChannelIdCurrentProgramMap.get(channelId);
}
+ /** Returns all the current programs. */
+ @AnyThread
+ public List<Program> getCurrentPrograms() {
+ return new ArrayList<>(mChannelIdCurrentProgramMap.values());
+ }
+
/**
* Reloads program data.
*/
@@ -338,19 +340,19 @@ public class ProgramDataManager implements MemoryManageable {
}
private void notifyCurrentProgramUpdate(long channelId, Program program) {
-
for (OnCurrentProgramUpdatedListener listener : mChannelId2ProgramUpdatedListeners
.get(channelId)) {
listener.onCurrentProgramUpdated(channelId, program);
- }
+ }
for (OnCurrentProgramUpdatedListener listener : mChannelId2ProgramUpdatedListeners
.get(Channel.INVALID_ID)) {
listener.onCurrentProgramUpdated(channelId, program);
- }
+ }
}
private void updateCurrentProgram(long channelId, Program program) {
- Program previousProgram = mChannelIdCurrentProgramMap.put(channelId, program);
+ Program previousProgram = program == null ? mChannelIdCurrentProgramMap.remove(channelId)
+ : mChannelIdCurrentProgramMap.put(channelId, program);
if (!Objects.equals(program, previousProgram)) {
if (mPrefetchEnabled) {
removePreviousProgramsAndUpdateCurrentProgramInCache(channelId, program);
@@ -581,22 +583,22 @@ public class ProgramDataManager implements MemoryManageable {
protected void onPostExecute(List<Program> programs) {
if (DEBUG) Log.d(TAG, "ProgramsUpdateTask done");
mProgramsUpdateTask = null;
- if (programs == null) {
- return;
- }
- Set<Long> removedChannelIds = new HashSet<>(mChannelIdCurrentProgramMap.keySet());
- for (Program program : programs) {
- long channelId = program.getChannelId();
- updateCurrentProgram(channelId, program);
- removedChannelIds.remove(channelId);
- }
- for (Long channelId : removedChannelIds) {
- if (mPrefetchEnabled) {
- mChannelIdProgramCache.remove(channelId);
+ if (programs != null) {
+ Set<Long> removedChannelIds = new HashSet<>(mChannelIdCurrentProgramMap.keySet());
+ for (Program program : programs) {
+ long channelId = program.getChannelId();
+ updateCurrentProgram(channelId, program);
+ removedChannelIds.remove(channelId);
+ }
+ for (Long channelId : removedChannelIds) {
+ if (mPrefetchEnabled) {
+ mChannelIdProgramCache.remove(channelId);
+ }
+ mChannelIdCurrentProgramMap.remove(channelId);
+ notifyCurrentProgramUpdate(channelId, null);
}
- mChannelIdCurrentProgramMap.remove(channelId);
- notifyCurrentProgramUpdate(channelId, null);
}
+ mCurrentProgramsLoadFinished = true;
}
}
diff --git a/src/com/android/tv/data/StreamInfo.java b/src/com/android/tv/data/StreamInfo.java
index fe461f14..709863cf 100644
--- a/src/com/android/tv/data/StreamInfo.java
+++ b/src/com/android/tv/data/StreamInfo.java
@@ -38,5 +38,9 @@ public interface StreamInfo {
int getAudioChannelCount();
boolean hasClosedCaption();
boolean isVideoAvailable();
+ /**
+ * Returns true, if video or audio is available.
+ */
+ boolean isVideoOrAudioAvailable();
int getVideoUnavailableReason();
}
diff --git a/src/com/android/tv/data/WatchedHistoryManager.java b/src/com/android/tv/data/WatchedHistoryManager.java
index 59319338..3edd7b1a 100644
--- a/src/com/android/tv/data/WatchedHistoryManager.java
+++ b/src/com/android/tv/data/WatchedHistoryManager.java
@@ -10,15 +10,14 @@ import android.os.Looper;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
+import android.support.annotation.WorkerThread;
import android.util.Log;
import com.android.tv.common.SharedPreferencesUtils;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
@@ -28,15 +27,15 @@ import java.util.concurrent.TimeUnit;
*
* <p>When there is no access to watched table of TvProvider,
* this class is used to build up watched history and to compute recent channels.
+ * <p>Note that this class is not thread safe. Please use this on one thread.
*/
public class WatchedHistoryManager {
private final static String TAG = "WatchedHistoryManager";
- private final boolean DEBUG = false;
+ private final static boolean DEBUG = false;
private static final int MAX_HISTORY_SIZE = 10000;
private static final String PREF_KEY_LAST_INDEX = "last_index";
private static final long MIN_DURATION_MS = TimeUnit.SECONDS.toMillis(10);
- private static final long RECENT_CHANNEL_THRESHOLD_MS = TimeUnit.MINUTES.toMillis(5);
private final List<WatchedRecord> mWatchedHistory = new ArrayList<>();
private final List<WatchedRecord> mPendingRecords = new ArrayList<>();
@@ -92,11 +91,7 @@ public class WatchedHistoryManager {
WatchedHistoryManager(Context context, int maxHistorySize) {
mContext = context.getApplicationContext();
mMaxHistorySize = maxHistorySize;
- if (Looper.myLooper() == null) {
- mHandler = new Handler(Looper.getMainLooper());
- } else {
- mHandler = new Handler();
- }
+ mHandler = new Handler();
}
/**
@@ -107,56 +102,70 @@ public class WatchedHistoryManager {
return;
}
mStarted = true;
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- mSharedPreferences = mContext.getSharedPreferences(
- SharedPreferencesUtils.SHARED_PREF_WATCHED_HISTORY, Context.MODE_PRIVATE);
- mLastIndex = mSharedPreferences.getLong(PREF_KEY_LAST_INDEX, -1);
- if (mLastIndex >= 0 && mLastIndex < mMaxHistorySize) {
- for (int i = 0; i <= mLastIndex; ++i) {
- WatchedRecord record =
- decode(mSharedPreferences.getString(getSharedPreferencesKey(i),
- null));
- if (record != null) {
- mWatchedHistory.add(record);
- }
- }
- } else if (mLastIndex >= mMaxHistorySize) {
- for (long i = mLastIndex - mMaxHistorySize + 1; i <= mLastIndex; ++i) {
- WatchedRecord record = decode(mSharedPreferences.getString(
- getSharedPreferencesKey(i), null));
- if (record != null) {
- mWatchedHistory.add(record);
- }
- }
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ loadWatchedHistory();
+ return null;
}
- return null;
- }
- @Override
- protected void onPostExecute(Void params) {
- mLoaded = true;
- if (DEBUG) {
- Log.d(TAG, "Loaded: size=" + mWatchedHistory.size() + " index=" + mLastIndex);
+ @Override
+ protected void onPostExecute(Void params) {
+ onLoadFinished();
}
- if (!mPendingRecords.isEmpty()) {
- Editor editor = mSharedPreferences.edit();
- for (WatchedRecord record : mPendingRecords) {
- mWatchedHistory.add(record);
- ++mLastIndex;
- editor.putString(getSharedPreferencesKey(mLastIndex), encode(record));
- }
- editor.putLong(PREF_KEY_LAST_INDEX, mLastIndex).apply();
- mPendingRecords.clear();
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ } else {
+ loadWatchedHistory();
+ onLoadFinished();
+ }
+ }
+
+ @WorkerThread
+ private void loadWatchedHistory() {
+ mSharedPreferences = mContext.getSharedPreferences(
+ SharedPreferencesUtils.SHARED_PREF_WATCHED_HISTORY, Context.MODE_PRIVATE);
+ mLastIndex = mSharedPreferences.getLong(PREF_KEY_LAST_INDEX, -1);
+ if (mLastIndex >= 0 && mLastIndex < mMaxHistorySize) {
+ for (int i = 0; i <= mLastIndex; ++i) {
+ WatchedRecord record =
+ decode(mSharedPreferences.getString(getSharedPreferencesKey(i),
+ null));
+ if (record != null) {
+ mWatchedHistory.add(record);
}
- if (mListener != null) {
- mListener.onLoadFinished();
+ }
+ } else if (mLastIndex >= mMaxHistorySize) {
+ for (long i = mLastIndex - mMaxHistorySize + 1; i <= mLastIndex; ++i) {
+ WatchedRecord record = decode(mSharedPreferences.getString(
+ getSharedPreferencesKey(i), null));
+ if (record != null) {
+ mWatchedHistory.add(record);
}
- mSharedPreferences.registerOnSharedPreferenceChangeListener(
- mOnSharedPreferenceChangeListener);
}
- }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ }
+
+ private void onLoadFinished() {
+ mLoaded = true;
+ if (DEBUG) {
+ Log.d(TAG, "Loaded: size=" + mWatchedHistory.size() + " index=" + mLastIndex);
+ }
+ if (!mPendingRecords.isEmpty()) {
+ Editor editor = mSharedPreferences.edit();
+ for (WatchedRecord record : mPendingRecords) {
+ mWatchedHistory.add(record);
+ ++mLastIndex;
+ editor.putString(getSharedPreferencesKey(mLastIndex), encode(record));
+ }
+ editor.putLong(PREF_KEY_LAST_INDEX, mLastIndex).apply();
+ mPendingRecords.clear();
+ }
+ if (mListener != null) {
+ mListener.onLoadFinished();
+ }
+ mSharedPreferences.registerOnSharedPreferenceChangeListener(
+ mOnSharedPreferenceChangeListener);
}
@VisibleForTesting
@@ -204,52 +213,6 @@ public class WatchedHistoryManager {
return Collections.unmodifiableList(mWatchedHistory);
}
- /**
- * Returns the list of recently watched channels.
- */
- public List<Channel> buildRecentChannel(ChannelDataManager channelDataManager, int maxCount) {
- List<Channel> list = new ArrayList<>();
- Map<Long, Long> durationMap = new HashMap<>();
- for (int i = mWatchedHistory.size() - 1; i >= 0; --i) {
- WatchedRecord record = mWatchedHistory.get(i);
- long channelId = record.channelId;
- Channel channel = channelDataManager.getChannel(channelId);
- if (channel == null || !channel.isBrowsable()) {
- continue;
- }
- Long duration = durationMap.get(channelId);
- if (duration == null) {
- duration = 0L;
- }
- if (duration >= RECENT_CHANNEL_THRESHOLD_MS) {
- continue;
- }
- if (list.isEmpty()) {
- // We put the first recent channel regardless of RECENT_CHANNEL_THREASHOLD.
- // It has the similar functionality as the previous channel in a usual remote
- // controller.
- list.add(channel);
- durationMap.put(channelId, RECENT_CHANNEL_THRESHOLD_MS);
- } else {
- duration += record.duration;
- durationMap.put(channelId, duration);
- if (duration >= RECENT_CHANNEL_THRESHOLD_MS) {
- list.add(channel);
- }
- }
- if (list.size() >= maxCount) {
- break;
- }
- }
- if (DEBUG) {
- Log.d(TAG, "Build recent channel");
- for (Channel channel : list) {
- Log.d(TAG, "recent channel: " + channel);
- }
- }
- return list;
- }
-
@VisibleForTesting
WatchedRecord getRecord(int reverseIndex) {
return mWatchedHistory.get(mWatchedHistory.size() - 1 - reverseIndex);
diff --git a/src/com/android/tv/data/epg/EpgFetchHelper.java b/src/com/android/tv/data/epg/EpgFetchHelper.java
new file mode 100644
index 00000000..5693c877
--- /dev/null
+++ b/src/com/android/tv/data/epg/EpgFetchHelper.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2017 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.tv.data.epg;
+
+import android.content.ContentProviderOperation;
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
+import android.media.tv.TvContract;
+import android.media.tv.TvContract.Programs;
+import android.os.RemoteException;
+import android.preference.PreferenceManager;
+import android.support.annotation.WorkerThread;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.tv.data.Program;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/** The helper class for {@link com.android.tv.data.epg.EpgFetcher} */
+class EpgFetchHelper {
+ private static final String TAG = "EpgFetchHelper";
+ private static final boolean DEBUG = false;
+
+ private static final long PROGRAM_QUERY_DURATION_MS = TimeUnit.DAYS.toMillis(30);
+ private static final int BATCH_OPERATION_COUNT = 100;
+
+ // Value: Long
+ private static final String KEY_LAST_UPDATED_EPG_TIMESTAMP =
+ "com.android.tv.data.epg.EpgFetcher.LastUpdatedEpgTimestamp";
+ // Value: String
+ private static final String KEY_LAST_LINEUP_ID =
+ "com.android.tv.data.epg.EpgFetcher.LastLineupId";
+
+ private static long sLastEpgUpdatedTimestamp = -1;
+ private static String sLastLineupId;
+
+ private EpgFetchHelper() { }
+
+ /**
+ * Updates newly fetched EPG data for the given channel to local providers. The method will
+ * compare the broadcasting time and try to match each newly fetched program with old programs
+ * of that channel in the database one by one. It will update the matched old program, or insert
+ * the new program if there is no matching program can be found in the database and at the same
+ * time remove those old programs which conflicts with the inserted one.
+
+ * @param channelId the target channel ID.
+ * @param fetchedPrograms the newly fetched program data.
+ * @return {@code true} if new program data are successfully updated. Otherwise {@code false}.
+ */
+ static boolean updateEpgData(Context context, long channelId, List<Program> fetchedPrograms) {
+ final int fetchedProgramsCount = fetchedPrograms.size();
+ if (fetchedProgramsCount == 0) {
+ return false;
+ }
+ boolean updated = false;
+ long startTimeMs = System.currentTimeMillis();
+ long endTimeMs = startTimeMs + PROGRAM_QUERY_DURATION_MS;
+ List<Program> oldPrograms = queryPrograms(context, channelId, startTimeMs, endTimeMs);
+ int oldProgramsIndex = 0;
+ int newProgramsIndex = 0;
+
+ // Compare the new programs with old programs one by one and update/delete the old one
+ // or insert new program if there is no matching program in the database.
+ ArrayList<ContentProviderOperation> ops = new ArrayList<>();
+ while (newProgramsIndex < fetchedProgramsCount) {
+ Program oldProgram = oldProgramsIndex < oldPrograms.size()
+ ? oldPrograms.get(oldProgramsIndex) : null;
+ Program newProgram = fetchedPrograms.get(newProgramsIndex);
+ boolean addNewProgram = false;
+ if (oldProgram != null) {
+ if (oldProgram.equals(newProgram)) {
+ // Exact match. No need to update. Move on to the next programs.
+ oldProgramsIndex++;
+ newProgramsIndex++;
+ } else if (hasSameTitleAndOverlap(oldProgram, newProgram)) {
+ // Partial match. Update the old program with the new one.
+ // NOTE: Use 'update' in this case instead of 'insert' and 'delete'. There
+ // could be application specific settings which belong to the old program.
+ ops.add(ContentProviderOperation.newUpdate(
+ TvContract.buildProgramUri(oldProgram.getId()))
+ .withValues(Program.toContentValues(newProgram))
+ .build());
+ oldProgramsIndex++;
+ newProgramsIndex++;
+ } else if (oldProgram.getEndTimeUtcMillis() < newProgram.getEndTimeUtcMillis()) {
+ // No match. Remove the old program first to see if the next program in
+ // {@code oldPrograms} partially matches the new program.
+ ops.add(ContentProviderOperation.newDelete(
+ TvContract.buildProgramUri(oldProgram.getId()))
+ .build());
+ oldProgramsIndex++;
+ } else {
+ // No match. The new program does not match any of the old programs. Insert
+ // it as a new program.
+ addNewProgram = true;
+ newProgramsIndex++;
+ }
+ } else {
+ // No old programs. Just insert new programs.
+ addNewProgram = true;
+ newProgramsIndex++;
+ }
+ if (addNewProgram) {
+ ops.add(ContentProviderOperation
+ .newInsert(Programs.CONTENT_URI)
+ .withValues(Program.toContentValues(newProgram))
+ .build());
+ }
+ // Throttle the batch operation not to cause TransactionTooLargeException.
+ if (ops.size() > BATCH_OPERATION_COUNT || newProgramsIndex >= fetchedProgramsCount) {
+ try {
+ if (DEBUG) {
+ int size = ops.size();
+ Log.d(TAG, "Running " + size + " operations for channel " + channelId);
+ for (int i = 0; i < size; ++i) {
+ Log.d(TAG, "Operation(" + i + "): " + ops.get(i));
+ }
+ }
+ context.getContentResolver().applyBatch(TvContract.AUTHORITY, ops);
+ updated = true;
+ } catch (RemoteException | OperationApplicationException e) {
+ Log.e(TAG, "Failed to insert programs.", e);
+ return updated;
+ }
+ ops.clear();
+ }
+ }
+ if (DEBUG) {
+ Log.d(TAG, "Updated " + fetchedProgramsCount + " programs for channel " + channelId);
+ }
+ return updated;
+ }
+
+ private static List<Program> queryPrograms(Context context, long channelId,
+ long startTimeMs, long endTimeMs) {
+ try (Cursor c = context.getContentResolver().query(
+ TvContract.buildProgramsUriForChannel(channelId, startTimeMs, endTimeMs),
+ Program.PROJECTION, null, null, Programs.COLUMN_START_TIME_UTC_MILLIS)) {
+ if (c == null) {
+ return Collections.emptyList();
+ }
+ ArrayList<Program> programs = new ArrayList<>();
+ while (c.moveToNext()) {
+ programs.add(Program.fromCursor(c));
+ }
+ return programs;
+ }
+ }
+
+ /**
+ * Returns {@code true} if the {@code oldProgram} needs to be updated with the
+ * {@code newProgram}.
+ */
+ private static boolean hasSameTitleAndOverlap(Program oldProgram, Program newProgram) {
+ // NOTE: Here, we update the old program if it has the same title and overlaps with the
+ // new program. The test logic is just an example and you can modify this. E.g. check
+ // whether the both programs have the same program ID if your EPG supports any ID for
+ // the programs.
+ return TextUtils.equals(oldProgram.getTitle(), newProgram.getTitle())
+ && oldProgram.getStartTimeUtcMillis() <= newProgram.getEndTimeUtcMillis()
+ && newProgram.getStartTimeUtcMillis() <= oldProgram.getEndTimeUtcMillis();
+ }
+
+ /**
+ * Sets the last known lineup ID into shared preferences for future usage. If channels are not
+ * re-scanned, EPG fetcher can directly use this value instead of checking the correct lineup ID
+ * every time when it needs to fetch EPG data.
+ */
+ @WorkerThread
+ synchronized static void setLastLineupId(Context context, String lineupId) {
+ if (DEBUG) {
+ if (lineupId == null) {
+ Log.d(TAG, "Clear stored lineup id: " + sLastLineupId);
+ }
+ }
+ sLastLineupId = lineupId;
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .putString(KEY_LAST_LINEUP_ID, lineupId).apply();
+ }
+
+ /**
+ * Gets the last known lineup ID from shared preferences.
+ */
+ synchronized static String getLastLineupId(Context context) {
+ if (sLastLineupId == null) {
+ sLastLineupId = PreferenceManager.getDefaultSharedPreferences(context)
+ .getString(KEY_LAST_LINEUP_ID, null);
+ }
+ if (DEBUG) Log.d(TAG, "Last lineup is " + sLastLineupId);
+ return sLastLineupId;
+ }
+
+ /**
+ * Sets the last updated timestamp of EPG data into shared preferences. If the EPG data is not
+ * out-dated, it's not necessary for EPG fetcher to fetch EPG again.
+ */
+ @WorkerThread
+ synchronized static void setLastEpgUpdatedTimestamp(Context context, long timestamp) {
+ sLastEpgUpdatedTimestamp = timestamp;
+ PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(
+ KEY_LAST_UPDATED_EPG_TIMESTAMP, timestamp).apply();
+ }
+
+ /**
+ * Gets the last updated timestamp of EPG data.
+ */
+ synchronized static long getLastEpgUpdatedTimestamp(Context context) {
+ if (sLastEpgUpdatedTimestamp < 0) {
+ sLastEpgUpdatedTimestamp = PreferenceManager.getDefaultSharedPreferences(context)
+ .getLong(KEY_LAST_UPDATED_EPG_TIMESTAMP, 0);
+ }
+ return sLastEpgUpdatedTimestamp;
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/data/epg/EpgFetcher.java b/src/com/android/tv/data/epg/EpgFetcher.java
index 3b093b6a..24f8b826 100644
--- a/src/com/android/tv/data/epg/EpgFetcher.java
+++ b/src/com/android/tv/data/epg/EpgFetcher.java
@@ -16,570 +16,720 @@
package com.android.tv.data.epg;
-import android.Manifest;
-import android.annotation.SuppressLint;
-import android.content.ContentProviderOperation;
-import android.content.ContentValues;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
import android.content.Context;
-import android.content.OperationApplicationException;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.location.Address;
-import android.media.tv.TvContentRating;
-import android.media.tv.TvContract;
-import android.media.tv.TvContract.Programs;
-import android.media.tv.TvContract.Programs.Genres;
import android.media.tv.TvInputInfo;
+import android.net.TrafficStats;
+import android.os.AsyncTask;
+import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
-import android.os.RemoteException;
-import android.preference.PreferenceManager;
+import android.support.annotation.AnyThread;
import android.support.annotation.MainThread;
-import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.v4.os.BuildCompat;
+import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.Features;
import com.android.tv.TvApplication;
-import com.android.tv.common.WeakHandler;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.common.TvCommonUtils;
+import com.android.tv.config.RemoteConfigUtils;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.InternalDataUtils;
+import com.android.tv.data.ChannelLogoFetcher;
import com.android.tv.data.Lineup;
import com.android.tv.data.Program;
+import com.android.tv.perf.EventNames;
+import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.perf.TimerEvent;
+import com.android.tv.tuner.util.PostalCodeUtils;
import com.android.tv.util.LocationUtils;
-import com.android.tv.util.RecurringRunner;
+import com.android.tv.util.NetworkTrafficTags;
import com.android.tv.util.Utils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
- * An utility class to fetch the EPG. This class isn't thread-safe.
+ * The service class to fetch EPG routinely or on-demand during channel scanning
+ *
+ * <p>Since the default executor of {@link AsyncTask} is {@link AsyncTask#SERIAL_EXECUTOR}, only one
+ * task can run at a time. Because fetching EPG takes long time, the fetching task shouldn't run on
+ * the serial executor. Instead, it should run on the {@link AsyncTask#THREAD_POOL_EXECUTOR}.
*/
public class EpgFetcher {
private static final String TAG = "EpgFetcher";
private static final boolean DEBUG = false;
- private static final int MSG_FETCH_EPG = 1;
+ private static final int EPG_ROUTINELY_FETCHING_JOB_ID = 101;
+
+ private static final long INITIAL_BACKOFF_MS = TimeUnit.SECONDS.toMillis(10);
+
+ private static final int REASON_EPG_READER_NOT_READY = 1;
+ private static final int REASON_LOCATION_INFO_UNAVAILABLE = 2;
+ private static final int REASON_LOCATION_PERMISSION_NOT_GRANTED = 3;
+ private static final int REASON_NO_EPG_DATA_RETURNED = 4;
+ private static final int REASON_NO_NEW_EPG = 5;
- private static final long EPG_PREFETCH_RECURRING_PERIOD_MS = TimeUnit.HOURS.toMillis(4);
- private static final long EPG_READER_INIT_WAIT_MS = TimeUnit.MINUTES.toMillis(1);
- private static final long LOCATION_INIT_WAIT_MS = TimeUnit.SECONDS.toMillis(10);
- private static final long LOCATION_ERROR_WAIT_MS = TimeUnit.HOURS.toMillis(1);
- private static final long PROGRAM_QUERY_DURATION = TimeUnit.DAYS.toMillis(30);
+ private static final long FETCH_DURING_SCAN_WAIT_TIME_MS = TimeUnit.SECONDS.toMillis(10);
- private static final int BATCH_OPERATION_COUNT = 100;
+ private static final long FETCH_DURING_SCAN_DURATION_SEC = TimeUnit.HOURS.toSeconds(3);
+ private static final long FAST_FETCH_DURATION_SEC = TimeUnit.DAYS.toSeconds(2);
- private static final String SUPPORTED_COUNTRY_CODE = Locale.US.getCountry();
- private static final String CONTENT_RATING_SEPARATOR = ",";
+ private static final int DEFAULT_ROUTINE_INTERVAL_HOUR = 4;
+ private static final String KEY_ROUTINE_INTERVAL = "live_channels_epg_fetcher_interval_hour";
- // Value: Long
- private static final String KEY_LAST_UPDATED_EPG_TIMESTAMP =
- "com.android.tv.data.epg.EpgFetcher.LastUpdatedEpgTimestamp";
- // Value: String
- private static final String KEY_LAST_LINEUP_ID =
- "com.android.tv.data.epg.EpgFetcher.LastLineupId";
+ private static final int MSG_PREPARE_FETCH_DURING_SCAN = 1;
+ private static final int MSG_CHANNEL_UPDATED_DURING_SCAN = 2;
+ private static final int MSG_FINISH_FETCH_DURING_SCAN = 3;
+ private static final int MSG_RETRY_PREPARE_FETCH_DURING_SCAN = 4;
+
+ private static final int QUERY_CHANNEL_COUNT = 50;
+ private static final int MINIMUM_CHANNELS_TO_DECIDE_LINEUP = 3;
private static EpgFetcher sInstance;
private final Context mContext;
private final ChannelDataManager mChannelDataManager;
private final EpgReader mEpgReader;
- private EpgFetcherHandler mHandler;
- private RecurringRunner mRecurringRunner;
- private boolean mStarted;
-
- private long mLastEpgTimestamp = -1;
- private String mLineupId;
-
- public static synchronized EpgFetcher getInstance(Context context) {
+ private final PerformanceMonitor mPerformanceMonitor;
+ private FetchAsyncTask mFetchTask;
+ private FetchDuringScanHandler mFetchDuringScanHandler;
+ private long mEpgTimeStamp;
+ private List<Lineup> mPossibleLineups;
+ private final Object mPossibleLineupsLock = new Object();
+ private final Object mFetchDuringScanHandlerLock = new Object();
+ // A flag to block the re-entrance of onChannelScanStarted and onChannelScanFinished.
+ private boolean mScanStarted;
+
+ private final long mRoutineIntervalMs;
+ private final long mEpgDataExpiredTimeLimitMs;
+ private final long mFastFetchDurationSec;
+
+ public static EpgFetcher getInstance(Context context) {
if (sInstance == null) {
- sInstance = new EpgFetcher(context.getApplicationContext());
+ sInstance = new EpgFetcher(context);
}
return sInstance;
}
- /**
- * Creates and returns {@link EpgReader}.
- */
- public static EpgReader createEpgReader(Context context) {
+ /** Creates and returns {@link EpgReader}. */
+ public static EpgReader createEpgReader(Context context, String region) {
return new StubEpgReader(context);
}
private EpgFetcher(Context context) {
- mContext = context;
- mEpgReader = new StubEpgReader(mContext);
- mChannelDataManager = TvApplication.getSingletons(context).getChannelDataManager();
- mChannelDataManager.addListener(new ChannelDataManager.Listener() {
- @Override
- public void onLoadFinished() {
- if (DEBUG) Log.d(TAG, "ChannelDataManager.onLoadFinished()");
- handleChannelChanged();
+ mContext = context.getApplicationContext();
+ ApplicationSingletons applicationSingletons = TvApplication.getSingletons(mContext);
+ mChannelDataManager = applicationSingletons.getChannelDataManager();
+ mPerformanceMonitor = applicationSingletons.getPerformanceMonitor();
+ mEpgReader = createEpgReader(mContext, LocationUtils.getCurrentCountry(mContext));
+
+ int remoteInteval =
+ (int) RemoteConfigUtils.getRemoteConfig(
+ context, KEY_ROUTINE_INTERVAL, DEFAULT_ROUTINE_INTERVAL_HOUR);
+ mRoutineIntervalMs =
+ remoteInteval < 0
+ ? TimeUnit.HOURS.toMillis(DEFAULT_ROUTINE_INTERVAL_HOUR)
+ : TimeUnit.HOURS.toMillis(remoteInteval);
+ mEpgDataExpiredTimeLimitMs = mRoutineIntervalMs * 2;
+ mFastFetchDurationSec = FAST_FETCH_DURATION_SEC + mRoutineIntervalMs / 1000;
+ }
+
+ /**
+ * Starts the routine service of EPG fetching. It use {@link JobScheduler} to schedule the EPG
+ * fetching routine. The EPG fetching routine will be started roughly every 4 hours, unless
+ * the channel scanning of tuner input is started.
+ */
+ @MainThread
+ public void startRoutineService() {
+ JobScheduler jobScheduler =
+ (JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+ for (JobInfo job : jobScheduler.getAllPendingJobs()) {
+ if (job.getId() == EPG_ROUTINELY_FETCHING_JOB_ID) {
+ return;
}
+ }
+ JobInfo job =
+ new JobInfo.Builder(
+ EPG_ROUTINELY_FETCHING_JOB_ID,
+ new ComponentName(mContext, EpgFetchService.class))
+ .setPeriodic(mRoutineIntervalMs)
+ .setBackoffCriteria(INITIAL_BACKOFF_MS, JobInfo.BACKOFF_POLICY_EXPONENTIAL)
+ .setPersisted(true)
+ .build();
+ jobScheduler.schedule(job);
+ Log.i(TAG, "EPG fetching routine service started.");
+ }
+ /**
+ * Fetches EPG immediately if current EPG data are out-dated, i.e., not successfully updated
+ * by routine fetching service due to various reasons.
+ */
+ @MainThread
+ public void fetchImmediatelyIfNeeded() {
+ if (TvCommonUtils.isRunningInTest()) {
+ // Do not run EpgFetcher in test.
+ return;
+ }
+ new AsyncTask<Void, Void, Long>() {
@Override
- public void onChannelListUpdated() {
- if (DEBUG) Log.d(TAG, "ChannelDataManager.onChannelListUpdated()");
- handleChannelChanged();
+ protected Long doInBackground(Void... args) {
+ return EpgFetchHelper.getLastEpgUpdatedTimestamp(mContext);
}
@Override
- public void onChannelBrowsableChanged() {
- if (DEBUG) Log.d(TAG, "ChannelDataManager.onChannelBrowsableChanged()");
- handleChannelChanged();
+ protected void onPostExecute(Long result) {
+ if (System.currentTimeMillis() - EpgFetchHelper.getLastEpgUpdatedTimestamp(mContext)
+ > mEpgDataExpiredTimeLimitMs) {
+ Log.i(TAG, "EPG data expired. Start fetching immediately.");
+ fetchImmediately();
+ }
}
- });
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
- private void handleChannelChanged() {
- if (mStarted) {
- if (needToStop()) {
- stop();
- }
- } else {
- start();
- }
- }
+ /**
+ * Fetches EPG immediately.
+ */
+ @MainThread
+ public void fetchImmediately() {
+ if (!mChannelDataManager.isDbLoadFinished()) {
+ mChannelDataManager.addListener(new ChannelDataManager.Listener() {
+ @Override
+ public void onLoadFinished() {
+ mChannelDataManager.removeListener(this);
+ executeFetchTaskIfPossible(null, null);
+ }
- private boolean needToStop() {
- return !canStart();
- }
+ @Override
+ public void onChannelListUpdated() { }
- private boolean canStart() {
- if (DEBUG) Log.d(TAG, "canStart()");
- boolean hasInternalTunerChannel = false;
- for (TvInputInfo input : TvApplication.getSingletons(mContext).getTvInputManagerHelper()
- .getTvInputInfos(true, true)) {
- String inputId = input.getId();
- if (Utils.isInternalTvInput(mContext, inputId)
- && mChannelDataManager.getChannelCountForInput(inputId) > 0) {
- hasInternalTunerChannel = true;
- break;
- }
- }
- if (!hasInternalTunerChannel) {
- if (DEBUG) Log.d(TAG, "No internal tuner channels.");
- return false;
+ @Override
+ public void onChannelBrowsableChanged() { }
+ });
+ } else {
+ executeFetchTaskIfPossible(null, null);
}
+ }
- if (!TextUtils.isEmpty(getLastLineupId())) {
- return true;
- }
- if (mContext.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
- != PackageManager.PERMISSION_GRANTED) {
- if (DEBUG) Log.d(TAG, "No permission to check the current location.");
- return false;
+ /**
+ * Notifies EPG fetch service that channel scanning is started.
+ */
+ @MainThread
+ public void onChannelScanStarted() {
+ if (mScanStarted || !Features.ENABLE_CLOUD_EPG_REGION.isEnabled(mContext)) {
+ return;
}
-
- try {
- Address address = LocationUtils.getCurrentAddress(mContext);
- if (address != null
- && !TextUtils.equals(address.getCountryCode(), SUPPORTED_COUNTRY_CODE)) {
- if (DEBUG) Log.d(TAG, "Country not supported: " + address.getCountryCode());
- return false;
+ mScanStarted = true;
+ stopFetchingJob();
+ synchronized (mFetchDuringScanHandlerLock) {
+ if (mFetchDuringScanHandler == null) {
+ HandlerThread thread = new HandlerThread("EpgFetchDuringScan");
+ thread.start();
+ mFetchDuringScanHandler = new FetchDuringScanHandler(thread.getLooper());
}
- } catch (SecurityException e) {
- Log.w(TAG, "No permission to get the current location", e);
- return false;
- } catch (IOException e) {
- Log.w(TAG, "IO Exception when getting the current location", e);
+ mFetchDuringScanHandler.sendEmptyMessage(MSG_PREPARE_FETCH_DURING_SCAN);
}
- return true;
+ Log.i(TAG, "EPG fetching on channel scanning started.");
}
/**
- * Starts fetching EPG.
+ * Notifies EPG fetch service that channel scanning is finished.
*/
@MainThread
- public void start() {
- if (DEBUG) Log.d(TAG, "start()");
- if (mStarted) {
- if (DEBUG) Log.d(TAG, "EpgFetcher thread already started.");
+ public void onChannelScanFinished() {
+ if (!mScanStarted) {
return;
}
- if (!canStart()) {
- return;
+ mScanStarted = false;
+ mFetchDuringScanHandler.sendEmptyMessage(MSG_FINISH_FETCH_DURING_SCAN);
+ }
+
+ @MainThread
+ private void stopFetchingJob() {
+ if (DEBUG) Log.d(TAG, "Try to stop routinely fetching job...");
+ if (mFetchTask != null) {
+ mFetchTask.cancel(true);
+ mFetchTask = null;
+ Log.i(TAG, "EPG routinely fetching job stopped.");
}
- mStarted = true;
- if (DEBUG) Log.d(TAG, "Starting EpgFetcher thread.");
- HandlerThread handlerThread = new HandlerThread("EpgFetcher");
- handlerThread.start();
- mHandler = new EpgFetcherHandler(handlerThread.getLooper(), this);
- mRecurringRunner = new RecurringRunner(mContext, EPG_PREFETCH_RECURRING_PERIOD_MS,
- new EpgRunner(), null);
- mRecurringRunner.start();
- if (DEBUG) Log.d(TAG, "EpgFetcher thread started successfully.");
}
- /**
- * Starts fetching EPG immediately if possible without waiting for the timer.
- */
@MainThread
- public void startImmediately() {
- start();
- if (mStarted) {
- if (DEBUG) Log.d(TAG, "Starting fetcher immediately");
- fetchEpg();
+ private boolean executeFetchTaskIfPossible(JobService service, JobParameters params) {
+ SoftPreconditions.checkState(mChannelDataManager.isDbLoadFinished());
+ if (!TvCommonUtils.isRunningInTest() && checkFetchPrerequisite()) {
+ mFetchTask = new FetchAsyncTask(service, params);
+ mFetchTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ return true;
}
+ return false;
}
- /**
- * Stops fetching EPG.
- */
@MainThread
- public void stop() {
- if (DEBUG) Log.d(TAG, "stop()");
- if (!mStarted) {
- return;
+ private boolean checkFetchPrerequisite() {
+ if (DEBUG) Log.d(TAG, "Check prerequisite of routinely fetching job.");
+ if (!Features.ENABLE_CLOUD_EPG_REGION.isEnabled(mContext)) {
+ Log.i(TAG, "Cannot start routine service: country not supported: "
+ + LocationUtils.getCurrentCountry(mContext));
+ return false;
+ }
+ if (mFetchTask != null) {
+ // Fetching job is already running or ready to run, no need to start again.
+ return false;
+ }
+ if (mFetchDuringScanHandler != null) {
+ if (DEBUG) Log.d(TAG, "Cannot start routine service: scanning channels.");
+ return false;
+ }
+ if (getTunerChannelCount() == 0) {
+ if (DEBUG) Log.d(TAG, "Cannot start routine service: no internal tuner channels.");
+ return false;
}
- mStarted = false;
- mRecurringRunner.stop();
- mHandler.removeCallbacksAndMessages(null);
- mHandler.getLooper().quit();
+ if (!TextUtils.isEmpty(EpgFetchHelper.getLastLineupId(mContext))) {
+ return true;
+ }
+ if (!TextUtils.isEmpty(PostalCodeUtils.getLastPostalCode(mContext))) {
+ return true;
+ }
+ return true;
}
- private void fetchEpg() {
- fetchEpg(0);
+ @MainThread
+ private int getTunerChannelCount() {
+ for (TvInputInfo input : TvApplication.getSingletons(mContext)
+ .getTvInputManagerHelper().getTvInputInfos(true, true)) {
+ String inputId = input.getId();
+ if (Utils.isInternalTvInput(mContext, inputId)) {
+ return mChannelDataManager.getChannelCountForInput(inputId);
+ }
+ }
+ return 0;
}
- private void fetchEpg(long delay) {
- mHandler.removeMessages(MSG_FETCH_EPG);
- mHandler.sendEmptyMessageDelayed(MSG_FETCH_EPG, delay);
+ @AnyThread
+ private void clearUnusedLineups(@Nullable String lineupId) {
+ synchronized (mPossibleLineupsLock) {
+ if (mPossibleLineups == null) {
+ return;
+ }
+ for (Lineup lineup : mPossibleLineups) {
+ if (!TextUtils.equals(lineupId, lineup.id)) {
+ mEpgReader.clearCachedChannels(lineup.id);
+ }
+ }
+ mPossibleLineups = null;
+ }
}
- private void onFetchEpg() {
- if (DEBUG) Log.d(TAG, "Start fetching EPG.");
+ @WorkerThread
+ private Integer prepareFetchEpg(boolean forceUpdatePossibleLineups) {
if (!mEpgReader.isAvailable()) {
- if (DEBUG) Log.d(TAG, "EPG reader is not temporarily available.");
- fetchEpg(EPG_READER_INIT_WAIT_MS);
- return;
+ Log.i(TAG, "EPG reader is temporarily unavailable.");
+ return REASON_EPG_READER_NOT_READY;
}
- String lineupId = getLastLineupId();
- if (lineupId == null) {
- Address address;
- try {
- address = LocationUtils.getCurrentAddress(mContext);
- } catch (IOException e) {
- if (DEBUG) Log.d(TAG, "Couldn't get the current location.", e);
- fetchEpg(LOCATION_ERROR_WAIT_MS);
- return;
- } catch (SecurityException e) {
- Log.w(TAG, "No permission to get the current location.");
- return;
+ // Checks the EPG Timestamp.
+ mEpgTimeStamp = mEpgReader.getEpgTimestamp();
+ if (mEpgTimeStamp <= EpgFetchHelper.getLastEpgUpdatedTimestamp(mContext)) {
+ if (DEBUG) Log.d(TAG, "No new EPG.");
+ return REASON_NO_NEW_EPG;
+ }
+ // Updates postal code.
+ boolean postalCodeChanged = false;
+ try {
+ postalCodeChanged = PostalCodeUtils.updatePostalCode(mContext);
+ } catch (IOException e) {
+ if (DEBUG) Log.d(TAG, "Couldn't get the current location.", e);
+ if (TextUtils.isEmpty(PostalCodeUtils.getLastPostalCode(mContext))) {
+ return REASON_LOCATION_INFO_UNAVAILABLE;
}
- if (address == null) {
- if (DEBUG) Log.d(TAG, "Null address returned.");
- fetchEpg(LOCATION_INIT_WAIT_MS);
- return;
+ } catch (SecurityException e) {
+ Log.w(TAG, "No permission to get the current location.");
+ if (TextUtils.isEmpty(PostalCodeUtils.getLastPostalCode(mContext))) {
+ return REASON_LOCATION_PERMISSION_NOT_GRANTED;
}
- if (DEBUG) Log.d(TAG, "Current location is " + address);
-
- lineupId = getLineupForAddress(address);
- if (lineupId != null) {
- if (DEBUG) Log.d(TAG, "Saving lineup " + lineupId + "found for " + address);
- setLastLineupId(lineupId);
- } else {
- if (DEBUG) Log.d(TAG, "No lineup found for " + address);
- return;
+ } catch (PostalCodeUtils.NoPostalCodeException e) {
+ Log.i(TAG, "Cannot get address or postal code.");
+ return REASON_LOCATION_INFO_UNAVAILABLE;
+ }
+ // Updates possible lineups if necessary.
+ SoftPreconditions.checkState(mPossibleLineups == null, TAG, "Possible lineups not reset.");
+ if (postalCodeChanged || forceUpdatePossibleLineups
+ || EpgFetchHelper.getLastLineupId(mContext) == null) {
+ // To prevent main thread being blocked, though theoretically it should not happen.
+ List<Lineup> possibleLineups =
+ mEpgReader.getLineups(PostalCodeUtils.getLastPostalCode(mContext));
+ if (possibleLineups.isEmpty()) {
+ return REASON_NO_EPG_DATA_RETURNED;
+ }
+ for (Lineup lineup : possibleLineups) {
+ mEpgReader.preloadChannels(lineup.id);
+ }
+ synchronized (mPossibleLineupsLock) {
+ mPossibleLineups = possibleLineups;
}
+ EpgFetchHelper.setLastLineupId(mContext, null);
}
+ return null;
+ }
- // Check the EPG Timestamp.
- long epgTimestamp = mEpgReader.getEpgTimestamp();
- if (epgTimestamp <= getLastUpdatedEpgTimestamp()) {
- if (DEBUG) Log.d(TAG, "No new EPG.");
+ @WorkerThread
+ private void batchFetchEpg(List<Channel> channels, long durationSec) {
+ Log.i(TAG, "Start batch fetching (" + durationSec + ")...." + channels.size());
+ if (channels.size() == 0) {
return;
}
-
- boolean updated = false;
- List<Channel> channels = mEpgReader.getChannels(lineupId);
+ List<Long> queryChannelIds = new ArrayList<>(QUERY_CHANNEL_COUNT);
for (Channel channel : channels) {
- List<Program> programs = new ArrayList<>(mEpgReader.getPrograms(channel.getId()));
- Collections.sort(programs);
- if (DEBUG) {
- Log.d(TAG, "Fetched " + programs.size() + " programs for channel " + channel);
- }
- if (updateEpg(channel.getId(), programs)) {
- updated = true;
+ queryChannelIds.add(channel.getId());
+ if (queryChannelIds.size() >= QUERY_CHANNEL_COUNT) {
+ batchUpdateEpg(mEpgReader.getPrograms(queryChannelIds, durationSec));
+ queryChannelIds.clear();
}
}
-
- final boolean epgUpdated = updated;
- setLastUpdatedEpgTimestamp(epgTimestamp);
- mHandler.removeMessages(MSG_FETCH_EPG);
- if (DEBUG) Log.d(TAG, "Fetching EPG is finished.");
+ if (!queryChannelIds.isEmpty()) {
+ batchUpdateEpg(mEpgReader.getPrograms(queryChannelIds, durationSec));
+ }
}
- @Nullable
- private String getLineupForAddress(Address address) {
- String lineup = null;
- if (TextUtils.equals(address.getCountryCode(), SUPPORTED_COUNTRY_CODE)) {
- String postalCode = address.getPostalCode();
- if (!TextUtils.isEmpty(postalCode)) {
- lineup = getLineupForPostalCode(postalCode);
+ @WorkerThread
+ private void batchUpdateEpg(Map<Long, List<Program>> allPrograms) {
+ for (Map.Entry<Long, List<Program>> entry : allPrograms.entrySet()) {
+ List<Program> programs = entry.getValue();
+ if (programs == null) {
+ continue;
}
+ Collections.sort(programs);
+ Log.i(TAG, "Batch fetched " + programs.size() + " programs for channel "
+ + entry.getKey());
+ EpgFetchHelper.updateEpgData(mContext, entry.getKey(), programs);
}
- return lineup;
}
@Nullable
- private String getLineupForPostalCode(String postalCode) {
- List<Lineup> lineups = mEpgReader.getLineups(postalCode);
- for (Lineup lineup : lineups) {
- // TODO(EPG): handle more than OTA digital
- if (lineup.type == Lineup.LINEUP_BROADCAST_DIGITAL) {
- if (DEBUG) Log.d(TAG, "Setting lineup to " + lineup.name + "(" + lineup.id + ")");
- return lineup.id;
+ @WorkerThread
+ private String pickBestLineupId(List<Channel> currentChannelList) {
+ String maxLineupId = null;
+ synchronized (mPossibleLineupsLock) {
+ if (mPossibleLineups == null) {
+ return null;
+ }
+ int maxCount = 0;
+ for (Lineup lineup : mPossibleLineups) {
+ int count = getMatchedChannelCount(lineup.id, currentChannelList);
+ Log.i(TAG, lineup.name + " (" + lineup.id + ") - " + count + " matches");
+ if (count > maxCount) {
+ maxCount = count;
+ maxLineupId = lineup.id;
+ }
}
}
- return null;
+ return maxLineupId;
}
- private long getLastUpdatedEpgTimestamp() {
- if (mLastEpgTimestamp < 0) {
- mLastEpgTimestamp = PreferenceManager.getDefaultSharedPreferences(mContext).getLong(
- KEY_LAST_UPDATED_EPG_TIMESTAMP, 0);
+ @WorkerThread
+ private int getMatchedChannelCount(String lineupId, List<Channel> currentChannelList) {
+ // Construct a list of display numbers for existing channels.
+ if (currentChannelList.isEmpty()) {
+ if (DEBUG) Log.d(TAG, "No existing channel to compare");
+ return 0;
+ }
+ List<String> numbers = new ArrayList<>(currentChannelList.size());
+ for (Channel channel : currentChannelList) {
+ // We only support channels from internal tuner inputs.
+ if (Utils.isInternalTvInput(mContext, channel.getInputId())) {
+ numbers.add(channel.getDisplayNumber());
+ }
}
- return mLastEpgTimestamp;
+ numbers.retainAll(mEpgReader.getChannelNumbers(lineupId));
+ return numbers.size();
}
- private void setLastUpdatedEpgTimestamp(long timestamp) {
- mLastEpgTimestamp = timestamp;
- PreferenceManager.getDefaultSharedPreferences(mContext).edit().putLong(
- KEY_LAST_UPDATED_EPG_TIMESTAMP, timestamp).commit();
- }
+ public static class EpgFetchService extends JobService {
+ private EpgFetcher mEpgFetcher;
- private String getLastLineupId() {
- if (mLineupId == null) {
- mLineupId = PreferenceManager.getDefaultSharedPreferences(mContext)
- .getString(KEY_LAST_LINEUP_ID, null);
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ TvApplication.setCurrentRunningProcess(this, true);
+ mEpgFetcher = EpgFetcher.getInstance(this);
}
- if (DEBUG) Log.d(TAG, "Last lineup_id " + mLineupId);
- return mLineupId;
- }
- private void setLastLineupId(String lineupId) {
- mLineupId = lineupId;
- PreferenceManager.getDefaultSharedPreferences(mContext).edit()
- .putString(KEY_LAST_LINEUP_ID, lineupId).commit();
- }
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ if (!mEpgFetcher.mChannelDataManager.isDbLoadFinished()) {
+ mEpgFetcher.mChannelDataManager.addListener(new ChannelDataManager.Listener() {
+ @Override
+ public void onLoadFinished() {
+ mEpgFetcher.mChannelDataManager.removeListener(this);
+ if (!mEpgFetcher.executeFetchTaskIfPossible(EpgFetchService.this, params)) {
+ jobFinished(params, false);
+ }
+ }
- private boolean updateEpg(long channelId, List<Program> newPrograms) {
- final int fetchedProgramsCount = newPrograms.size();
- if (fetchedProgramsCount == 0) {
+ @Override
+ public void onChannelListUpdated() { }
+
+ @Override
+ public void onChannelBrowsableChanged() { }
+ });
+ return true;
+ } else {
+ return mEpgFetcher.executeFetchTaskIfPossible(this, params);
+ }
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ mEpgFetcher.stopFetchingJob();
return false;
}
- boolean updated = false;
- long startTimeMs = System.currentTimeMillis();
- long endTimeMs = startTimeMs + PROGRAM_QUERY_DURATION;
- List<Program> oldPrograms = queryPrograms(channelId, startTimeMs, endTimeMs);
- Program currentOldProgram = oldPrograms.size() > 0 ? oldPrograms.get(0) : null;
- int oldProgramsIndex = 0;
- int newProgramsIndex = 0;
- // Skip the past programs. They will be automatically removed by the system.
- if (currentOldProgram != null) {
- long oldStartTimeUtcMillis = currentOldProgram.getStartTimeUtcMillis();
- for (Program program : newPrograms) {
- if (program.getEndTimeUtcMillis() > oldStartTimeUtcMillis) {
- break;
- }
- newProgramsIndex++;
- }
+ }
+
+ private class FetchAsyncTask extends AsyncTask<Void, Void, Integer> {
+ private final JobService mService;
+ private final JobParameters mParams;
+ private List<Channel> mCurrentChannelList;
+ private TimerEvent mTimerEvent;
+
+ private FetchAsyncTask(JobService service, JobParameters params) {
+ mService = service;
+ mParams = params;
}
- // Compare the new programs with old programs one by one and update/delete the old one
- // or insert new program if there is no matching program in the database.
- ArrayList<ContentProviderOperation> ops = new ArrayList<>();
- while (newProgramsIndex < fetchedProgramsCount) {
- // TODO: Extract to method and make test.
- Program oldProgram = oldProgramsIndex < oldPrograms.size()
- ? oldPrograms.get(oldProgramsIndex) : null;
- Program newProgram = newPrograms.get(newProgramsIndex);
- boolean addNewProgram = false;
- if (oldProgram != null) {
- if (oldProgram.equals(newProgram)) {
- // Exact match. No need to update. Move on to the next programs.
- oldProgramsIndex++;
- newProgramsIndex++;
- } else if (isSameTitleAndOverlap(oldProgram, newProgram)) {
- // Partial match. Update the old program with the new one.
- // NOTE: Use 'update' in this case instead of 'insert' and 'delete'. There
- // could be application specific settings which belong to the old program.
- ops.add(ContentProviderOperation.newUpdate(
- TvContract.buildProgramUri(oldProgram.getId()))
- .withValues(toContentValues(newProgram))
- .build());
- oldProgramsIndex++;
- newProgramsIndex++;
- } else if (oldProgram.getEndTimeUtcMillis()
- < newProgram.getEndTimeUtcMillis()) {
- // No match. Remove the old program first to see if the next program in
- // {@code oldPrograms} partially matches the new program.
- ops.add(ContentProviderOperation.newDelete(
- TvContract.buildProgramUri(oldProgram.getId()))
- .build());
- oldProgramsIndex++;
+
+ @Override
+ protected void onPreExecute() {
+ mTimerEvent = mPerformanceMonitor.startTimer();
+ mCurrentChannelList = mChannelDataManager.getChannelList();
+ }
+
+ @Override
+ protected Integer doInBackground(Void... args) {
+ final int oldTag = TrafficStats.getThreadStatsTag();
+ TrafficStats.setThreadStatsTag(NetworkTrafficTags.EPG_FETCH);
+ try {
+ if (DEBUG) Log.d(TAG, "Start EPG routinely fetching.");
+ Integer failureReason = prepareFetchEpg(false);
+ // InterruptedException might be caught by RPC, we should check it here.
+ if (failureReason != null || this.isCancelled()) {
+ return failureReason;
+ }
+ String lineupId = EpgFetchHelper.getLastLineupId(mContext);
+ lineupId = lineupId == null ? pickBestLineupId(mCurrentChannelList) : lineupId;
+ if (lineupId != null) {
+ Log.i(TAG, "Selecting the lineup " + lineupId);
+ // During normal fetching process, the lineup ID should be confirmed since all
+ // channels are known, clear up possible lineups to save resources.
+ EpgFetchHelper.setLastLineupId(mContext, lineupId);
+ clearUnusedLineups(lineupId);
} else {
- // No match. The new program does not match any of the old programs. Insert
- // it as a new program.
- addNewProgram = true;
- newProgramsIndex++;
+ Log.i(TAG, "Failed to get lineup id");
+ return REASON_NO_EPG_DATA_RETURNED;
}
- } else {
- // No old programs. Just insert new programs.
- addNewProgram = true;
- newProgramsIndex++;
- }
- if (addNewProgram) {
- ops.add(ContentProviderOperation
- .newInsert(TvContract.Programs.CONTENT_URI)
- .withValues(toContentValues(newProgram))
- .build());
- }
- // Throttle the batch operation not to cause TransactionTooLargeException.
- if (ops.size() > BATCH_OPERATION_COUNT || newProgramsIndex >= fetchedProgramsCount) {
- try {
- if (DEBUG) {
- int size = ops.size();
- Log.d(TAG, "Running " + size + " operations for channel " + channelId);
- for (int i = 0; i < size; ++i) {
- Log.d(TAG, "Operation(" + i + "): " + ops.get(i));
- }
+ final List<Channel> channels = mEpgReader.getChannels(lineupId);
+ // InterruptedException might be caught by RPC, we should check it here.
+ if (this.isCancelled()) {
+ return null;
+ }
+ if (channels.isEmpty()) {
+ Log.i(TAG, "Failed to get EPG channels.");
+ return REASON_NO_EPG_DATA_RETURNED;
+ }
+ if (System.currentTimeMillis() - EpgFetchHelper.getLastEpgUpdatedTimestamp(mContext)
+ > mEpgDataExpiredTimeLimitMs) {
+ batchFetchEpg(channels, mFastFetchDurationSec);
+ }
+ new Handler(mContext.getMainLooper())
+ .post(
+ new Runnable() {
+ @Override
+ public void run() {
+ ChannelLogoFetcher.startFetchingChannelLogos(
+ mContext, channels);
+ }
+ });
+ for (Channel channel : channels) {
+ if (this.isCancelled()) {
+ return null;
}
- mContext.getContentResolver().applyBatch(TvContract.AUTHORITY, ops);
- updated = true;
- } catch (RemoteException | OperationApplicationException e) {
- Log.e(TAG, "Failed to insert programs.", e);
- return updated;
+ long channelId = channel.getId();
+ List<Program> programs = new ArrayList<>(mEpgReader.getPrograms(channelId));
+ // InterruptedException might be caught by RPC, we should check it here.
+ Collections.sort(programs);
+ Log.i(TAG, "Fetched " + programs.size() + " programs for channel " + channelId);
+ EpgFetchHelper.updateEpgData(mContext, channelId, programs);
}
- ops.clear();
+ EpgFetchHelper.setLastEpgUpdatedTimestamp(mContext, mEpgTimeStamp);
+ if (DEBUG) Log.d(TAG, "Fetching EPG is finished.");
+ return null;
+ } finally {
+ TrafficStats.setThreadStatsTag(oldTag);
}
}
- if (DEBUG) {
- Log.d(TAG, "Updated " + fetchedProgramsCount + " programs for channel " + channelId);
- }
- return updated;
- }
- private List<Program> queryPrograms(long channelId, long startTimeMs, long endTimeMs) {
- try (Cursor c = mContext.getContentResolver().query(
- TvContract.buildProgramsUriForChannel(channelId, startTimeMs, endTimeMs),
- Program.PROJECTION, null, null, Programs.COLUMN_START_TIME_UTC_MILLIS)) {
- if (c == null) {
- return Collections.emptyList();
- }
- ArrayList<Program> programs = new ArrayList<>();
- while (c.moveToNext()) {
- programs.add(Program.fromCursor(c));
+ @Override
+ protected void onPostExecute(Integer failureReason) {
+ mFetchTask = null;
+ if (failureReason == null || failureReason == REASON_LOCATION_PERMISSION_NOT_GRANTED
+ || failureReason == REASON_NO_NEW_EPG) {
+ jobFinished(false);
+ } else {
+ // Applies back-off policy
+ jobFinished(true);
}
- return programs;
+ mPerformanceMonitor.stopTimer(mTimerEvent, EventNames.FETCH_EPG_TASK);
+ mPerformanceMonitor.recordMemory(EventNames.FETCH_EPG_TASK);
}
- }
- /**
- * Returns {@code true} if the {@code oldProgram} program needs to be updated with the
- * {@code newProgram} program.
- */
- private boolean isSameTitleAndOverlap(Program oldProgram, Program newProgram) {
- // NOTE: Here, we update the old program if it has the same title and overlaps with the
- // new program. The test logic is just an example and you can modify this. E.g. check
- // whether the both programs have the same program ID if your EPG supports any ID for
- // the programs.
- return Objects.equals(oldProgram.getTitle(), newProgram.getTitle())
- && oldProgram.getStartTimeUtcMillis() <= newProgram.getEndTimeUtcMillis()
- && newProgram.getStartTimeUtcMillis() <= oldProgram.getEndTimeUtcMillis();
- }
+ @Override
+ protected void onCancelled(Integer failureReason) {
+ clearUnusedLineups(null);
+ jobFinished(false);
+ }
- @SuppressLint("InlinedApi")
- @SuppressWarnings("deprecation")
- private static ContentValues toContentValues(Program program) {
- ContentValues values = new ContentValues();
- values.put(TvContract.Programs.COLUMN_CHANNEL_ID, program.getChannelId());
- putValue(values, TvContract.Programs.COLUMN_TITLE, program.getTitle());
- putValue(values, TvContract.Programs.COLUMN_EPISODE_TITLE, program.getEpisodeTitle());
- if (BuildCompat.isAtLeastN()) {
- putValue(values, TvContract.Programs.COLUMN_SEASON_DISPLAY_NUMBER,
- program.getSeasonNumber());
- putValue(values, TvContract.Programs.COLUMN_EPISODE_DISPLAY_NUMBER,
- program.getEpisodeNumber());
- } else {
- putValue(values, TvContract.Programs.COLUMN_SEASON_NUMBER, program.getSeasonNumber());
- putValue(values, TvContract.Programs.COLUMN_EPISODE_NUMBER, program.getEpisodeNumber());
- }
- putValue(values, TvContract.Programs.COLUMN_SHORT_DESCRIPTION, program.getDescription());
- putValue(values, TvContract.Programs.COLUMN_POSTER_ART_URI, program.getPosterArtUri());
- putValue(values, TvContract.Programs.COLUMN_THUMBNAIL_URI, program.getThumbnailUri());
- String[] canonicalGenres = program.getCanonicalGenres();
- if (canonicalGenres != null && canonicalGenres.length > 0) {
- putValue(values, TvContract.Programs.COLUMN_CANONICAL_GENRE,
- Genres.encode(canonicalGenres));
- } else {
- putValue(values, TvContract.Programs.COLUMN_CANONICAL_GENRE, "");
- }
- TvContentRating[] ratings = program.getContentRatings();
- if (ratings != null && ratings.length > 0) {
- StringBuilder sb = new StringBuilder(ratings[0].flattenToString());
- for (int i = 1; i < ratings.length; ++i) {
- sb.append(CONTENT_RATING_SEPARATOR);
- sb.append(ratings[i].flattenToString());
+ private void jobFinished(boolean reschedule) {
+ if (mService != null && mParams != null) {
+ // Task is executed from JobService, need to report jobFinished.
+ mService.jobFinished(mParams, reschedule);
}
- putValue(values, TvContract.Programs.COLUMN_CONTENT_RATING, sb.toString());
- } else {
- putValue(values, TvContract.Programs.COLUMN_CONTENT_RATING, "");
- }
- values.put(TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS,
- program.getStartTimeUtcMillis());
- values.put(TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS, program.getEndTimeUtcMillis());
- putValue(values, TvContract.Programs.COLUMN_INTERNAL_PROVIDER_DATA,
- InternalDataUtils.serializeInternalProviderData(program));
- return values;
- }
-
- private static void putValue(ContentValues contentValues, String key, String value) {
- if (TextUtils.isEmpty(value)) {
- contentValues.putNull(key);
- } else {
- contentValues.put(key, value);
}
}
- private static void putValue(ContentValues contentValues, String key, byte[] value) {
- if (value == null || value.length == 0) {
- contentValues.putNull(key);
- } else {
- contentValues.put(key, value);
- }
- }
+ @WorkerThread
+ private class FetchDuringScanHandler extends Handler {
+ private final Set<Long> mFetchedChannelIdsDuringScan = new HashSet<>();
+ private String mPossibleLineupId;
+
+ private final ChannelDataManager.Listener mDuringScanChannelListener =
+ new ChannelDataManager.Listener() {
+ @Override
+ public void onLoadFinished() {
+ if (DEBUG) Log.d(TAG, "ChannelDataManager.onLoadFinished()");
+ if (getTunerChannelCount() >= MINIMUM_CHANNELS_TO_DECIDE_LINEUP
+ && !hasMessages(MSG_CHANNEL_UPDATED_DURING_SCAN)) {
+ Message.obtain(FetchDuringScanHandler.this,
+ MSG_CHANNEL_UPDATED_DURING_SCAN, new ArrayList<>(
+ mChannelDataManager.getChannelList())).sendToTarget();
+ }
+ }
+
+ @Override
+ public void onChannelListUpdated() {
+ if (DEBUG) Log.d(TAG, "ChannelDataManager.onChannelListUpdated()");
+ if (getTunerChannelCount() >= MINIMUM_CHANNELS_TO_DECIDE_LINEUP
+ && !hasMessages(MSG_CHANNEL_UPDATED_DURING_SCAN)) {
+ Message.obtain(FetchDuringScanHandler.this,
+ MSG_CHANNEL_UPDATED_DURING_SCAN,
+ mChannelDataManager.getChannelList()).sendToTarget();
+ }
+ }
+
+ @Override
+ public void onChannelBrowsableChanged() {
+ // Do nothing
+ }
+ };
- private static class EpgFetcherHandler extends WeakHandler<EpgFetcher> {
- public EpgFetcherHandler (@NonNull Looper looper, EpgFetcher ref) {
- super(looper, ref);
+ @AnyThread
+ private FetchDuringScanHandler(Looper looper) {
+ super(looper);
}
@Override
- public void handleMessage(Message msg, @NonNull EpgFetcher epgFetcher) {
+ public void handleMessage(Message msg) {
switch (msg.what) {
- case MSG_FETCH_EPG:
- epgFetcher.onFetchEpg();
+ case MSG_PREPARE_FETCH_DURING_SCAN:
+ case MSG_RETRY_PREPARE_FETCH_DURING_SCAN:
+ onPrepareFetchDuringScan();
break;
- default:
- super.handleMessage(msg);
+ case MSG_CHANNEL_UPDATED_DURING_SCAN:
+ if (!hasMessages(MSG_CHANNEL_UPDATED_DURING_SCAN)) {
+ onChannelUpdatedDuringScan((List<Channel>) msg.obj);
+ }
+ break;
+ case MSG_FINISH_FETCH_DURING_SCAN:
+ removeMessages(MSG_RETRY_PREPARE_FETCH_DURING_SCAN);
+ if (hasMessages(MSG_CHANNEL_UPDATED_DURING_SCAN)) {
+ sendEmptyMessage(MSG_FINISH_FETCH_DURING_SCAN);
+ } else {
+ onFinishFetchDuringScan();
+ }
break;
}
}
- }
- private class EpgRunner implements Runnable {
- @Override
- public void run() {
- fetchEpg();
+ private void onPrepareFetchDuringScan() {
+ Integer failureReason = prepareFetchEpg(true);
+ if (failureReason != null) {
+ sendEmptyMessageDelayed(
+ MSG_RETRY_PREPARE_FETCH_DURING_SCAN, FETCH_DURING_SCAN_WAIT_TIME_MS);
+ return;
+ }
+ mChannelDataManager.addListener(mDuringScanChannelListener);
+ }
+
+ private void onChannelUpdatedDuringScan(List<Channel> currentChannelList) {
+ String lineupId = pickBestLineupId(currentChannelList);
+ Log.i(TAG, "Fast fetch channels for lineup ID: " + lineupId);
+ if (TextUtils.isEmpty(lineupId)) {
+ if (TextUtils.isEmpty(mPossibleLineupId)) {
+ return;
+ }
+ } else if (!TextUtils.equals(lineupId, mPossibleLineupId)) {
+ mFetchedChannelIdsDuringScan.clear();
+ mPossibleLineupId = lineupId;
+ }
+ List<Long> currentChannelIds = new ArrayList<>();
+ for (Channel channel : currentChannelList) {
+ currentChannelIds.add(channel.getId());
+ }
+ mFetchedChannelIdsDuringScan.retainAll(currentChannelIds);
+ List<Channel> newChannels = new ArrayList<>();
+ for (Channel channel : mEpgReader.getChannels(mPossibleLineupId)) {
+ if (!mFetchedChannelIdsDuringScan.contains(channel.getId())) {
+ newChannels.add(channel);
+ mFetchedChannelIdsDuringScan.add(channel.getId());
+ }
+ }
+ batchFetchEpg(newChannels, FETCH_DURING_SCAN_DURATION_SEC);
+ }
+
+ private void onFinishFetchDuringScan() {
+ mChannelDataManager.removeListener(mDuringScanChannelListener);
+ EpgFetchHelper.setLastLineupId(mContext, mPossibleLineupId);
+ clearUnusedLineups(null);
+ mFetchedChannelIdsDuringScan.clear();
+ synchronized (mFetchDuringScanHandlerLock) {
+ if (!hasMessages(MSG_PREPARE_FETCH_DURING_SCAN)) {
+ removeCallbacksAndMessages(null);
+ getLooper().quit();
+ mFetchDuringScanHandler = null;
+ }
+ }
+ // Clear timestamp to make routine service start right away.
+ EpgFetchHelper.setLastEpgUpdatedTimestamp(mContext, 0);
+ Log.i(TAG, "EPG Fetching during channel scanning finished.");
+ new Handler(Looper.getMainLooper()).post(new Runnable() {
+ @Override
+ public void run() {
+ fetchImmediately();
+ }
+ });
}
}
}
diff --git a/src/com/android/tv/data/epg/EpgReader.java b/src/com/android/tv/data/epg/EpgReader.java
index 4f3b6f52..c5aeca27 100644
--- a/src/com/android/tv/data/epg/EpgReader.java
+++ b/src/com/android/tv/data/epg/EpgReader.java
@@ -16,15 +16,17 @@
package com.android.tv.data.epg;
+import android.support.annotation.AnyThread;
import android.support.annotation.NonNull;
import android.support.annotation.WorkerThread;
import com.android.tv.data.Channel;
import com.android.tv.data.Lineup;
import com.android.tv.data.Program;
-import com.android.tv.dvr.SeriesInfo;
+import com.android.tv.dvr.data.SeriesInfo;
import java.util.List;
+import java.util.Map;
/**
* An interface used to retrieve the EPG data. This class should be used in worker thread.
@@ -42,25 +44,48 @@ public interface EpgReader {
*/
long getEpgTimestamp();
+ /** Sets the region code. */
+ void setRegionCode(String regionCode);
+
+ /** Returns the lineups list. */
+ List<Lineup> getLineups(@NonNull String postalCode);
+
/**
- * Returns the channels list.
+ * Returns the list of channel numbers (unsorted) for the given lineup. The result is used to
+ * choose the most appropriate lineup among others by comparing the channel numbers of the
+ * existing channels on the device.
+ */
+ List<String> getChannelNumbers(@NonNull String lineupId);
+
+ /**
+ * Returns the list of channels for the given lineup. The returned channels should map into the
+ * existing channels on the device. This method is usually called after selecting the lineup.
*/
List<Channel> getChannels(@NonNull String lineupId);
+ /** Pre-loads and caches channels for a given lineup. */
+ void preloadChannels(@NonNull String lineupId);
+
/**
- * Returns the lineups list.
+ * Clears cached channels for a given lineup.
*/
- List<Lineup> getLineups(@NonNull String postalCode);
+ @AnyThread
+ void clearCachedChannels(@NonNull String lineupId);
/**
- * Returns the programs for the given channel. The result is sorted by the start time.
- * Note that the {@code Program} doesn't have valid program ID because it's not retrieved from
- * TvProvider.
+ * Returns the programs for the given channel. Must call {@link #getChannels(String)}
+ * beforehand. Note that the {@code Program} doesn't have valid program ID because it's not
+ * retrieved from TvProvider.
*/
List<Program> getPrograms(long channelId);
/**
- * Returns the series information for the given series ID.
+ * Returns the programs for the given channels. Note that the {@code Program} doesn't have valid
+ * program ID because it's not retrieved from TvProvider. This method is only used to get
+ * programs for a short duration typically.
*/
- SeriesInfo getSeriesInfo(String seriesId);
-}
+ Map<Long, List<Program>> getPrograms(@NonNull List<Long> channelIds, long duration);
+
+ /** Returns the series information for the given series ID. */
+ SeriesInfo getSeriesInfo(@NonNull String seriesId);
+} \ No newline at end of file
diff --git a/src/com/android/tv/data/epg/StubEpgReader.java b/src/com/android/tv/data/epg/StubEpgReader.java
index 64093f89..ab6935ad 100644
--- a/src/com/android/tv/data/epg/StubEpgReader.java
+++ b/src/com/android/tv/data/epg/StubEpgReader.java
@@ -18,13 +18,15 @@ package com.android.tv.data.epg;
import android.content.Context;
+import android.support.annotation.NonNull;
import com.android.tv.data.Channel;
import com.android.tv.data.Lineup;
import com.android.tv.data.Program;
-import com.android.tv.dvr.SeriesInfo;
+import com.android.tv.dvr.data.SeriesInfo;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
/**
* A stub class to read EPG.
@@ -44,22 +46,47 @@ public class StubEpgReader implements EpgReader{
}
@Override
- public List<Channel> getChannels(String lineupId) {
+ public void setRegionCode(String regionCode) {
+ // Do nothing
+ }
+
+ @Override
+ public List<Lineup> getLineups(@NonNull String postalCode) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<String> getChannelNumbers(@NonNull String lineupId) {
return Collections.emptyList();
}
@Override
- public List<Lineup> getLineups(String postalCode) {
+ public List<Channel> getChannels(@NonNull String lineupId) {
return Collections.emptyList();
}
@Override
+ public void preloadChannels(@NonNull String lineupId) {
+ // Do nothing
+ }
+
+ @Override
+ public void clearCachedChannels(@NonNull String lineupId) {
+ // Do nothing
+ }
+
+ @Override
public List<Program> getPrograms(long channelId) {
return Collections.emptyList();
}
@Override
- public SeriesInfo getSeriesInfo(String seriesId) {
+ public Map<Long, List<Program>> getPrograms(@NonNull List<Long> channelIds, long duration) {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public SeriesInfo getSeriesInfo(@NonNull String seriesId) {
return null;
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/dialog/DvrHistoryDialogFragment.java b/src/com/android/tv/dialog/DvrHistoryDialogFragment.java
new file mode 100644
index 00000000..d686e6e6
--- /dev/null
+++ b/src/com/android/tv/dialog/DvrHistoryDialogFragment.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2016 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.tv.dialog;
+
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.data.Channel;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.ui.DvrUiHelper;
+import com.android.tv.util.Utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Displays the DVR history.
+ */
+@TargetApi(VERSION_CODES.N)
+public class DvrHistoryDialogFragment extends SafeDismissDialogFragment {
+ public static final String DIALOG_TAG = DvrHistoryDialogFragment.class.getSimpleName();
+
+ private static final String TRACKER_LABEL = "DVR history";
+ private final List<ScheduledRecording> mSchedules = new ArrayList<>();
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ ApplicationSingletons singletons = TvApplication.getSingletons(getContext());
+ DvrDataManager dataManager = singletons.getDvrDataManager();
+ ChannelDataManager channelDataManager = singletons.getChannelDataManager();
+ for (ScheduledRecording schedule : dataManager.getAllScheduledRecordings()) {
+ if (!schedule.isInProgress() && !schedule.isNotStarted()) {
+ mSchedules.add(schedule);
+ }
+ }
+ mSchedules.sort(ScheduledRecording.START_TIME_COMPARATOR.reversed());
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ ArrayAdapter adapter = new ArrayAdapter<ScheduledRecording>(getContext(),
+ R.layout.list_item_dvr_history, ScheduledRecording.toArray(mSchedules)) {
+ @NonNull
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View view = inflater.inflate(R.layout.list_item_dvr_history, parent, false);
+ ScheduledRecording schedule = mSchedules.get(position);
+ setText(view, R.id.state, getStateString(schedule.getState()));
+ setText(view, R.id.schedule_time, getRecordingTimeText(schedule));
+ setText(view, R.id.program_title, DvrUiHelper.getStyledTitleWithEpisodeNumber(
+ getContext(), schedule, 0));
+ setText(view, R.id.channel_name, getChannelNameText(schedule));
+ return view;
+ }
+
+ private void setText(View view, int id, CharSequence text) {
+ ((TextView) view.findViewById(id)).setText(text);
+ }
+
+ private void setText(View view, int id, int text) {
+ ((TextView) view.findViewById(id)).setText(text);
+ }
+
+ @SuppressLint("SwitchIntDef")
+ private int getStateString(@RecordingState int state) {
+ switch (state) {
+ case ScheduledRecording.STATE_RECORDING_CLIPPED:
+ return R.string.dvr_history_dialog_state_clip;
+ case ScheduledRecording.STATE_RECORDING_FAILED:
+ return R.string.dvr_history_dialog_state_fail;
+ case ScheduledRecording.STATE_RECORDING_FINISHED:
+ return R.string.dvr_history_dialog_state_success;
+ default:
+ break;
+ }
+ return 0;
+ }
+
+ private String getChannelNameText(ScheduledRecording schedule) {
+ Channel channel = channelDataManager.getChannel(schedule.getChannelId());
+ return channel == null ? null :
+ TextUtils.isEmpty(channel.getDisplayName()) ? channel.getDisplayNumber() :
+ channel.getDisplayName().trim() + " " + channel.getDisplayNumber();
+ }
+
+ private String getRecordingTimeText(ScheduledRecording schedule) {
+ return Utils.getDurationString(getContext(), schedule.getStartTimeMs(),
+ schedule.getEndTimeMs(), true, true, true, 0);
+ }
+ };
+ ListView listView = new ListView(getActivity());
+ listView.setAdapter(adapter);
+ return new AlertDialog.Builder(getActivity()).setTitle(R.string.dvr_history_dialog_title)
+ .setView(listView).create();
+ }
+
+ @Override
+ public String getTrackerLabel() {
+ return TRACKER_LABEL;
+ }
+}
diff --git a/src/com/android/tv/dialog/FullscreenDialogFragment.java b/src/com/android/tv/dialog/FullscreenDialogFragment.java
index d16202a1..d00422a7 100644
--- a/src/com/android/tv/dialog/FullscreenDialogFragment.java
+++ b/src/com/android/tv/dialog/FullscreenDialogFragment.java
@@ -77,7 +77,7 @@ public class FullscreenDialogFragment extends SafeDismissDialogFragment {
return mTrackerLabel;
}
- private class FullscreenDialog extends TvDialog {
+ private class FullscreenDialog extends Dialog {
public FullscreenDialog(Context context, int theme) {
super(context, theme);
}
diff --git a/src/com/android/tv/dialog/HalfSizedDialogFragment.java b/src/com/android/tv/dialog/HalfSizedDialogFragment.java
new file mode 100644
index 00000000..315c6a93
--- /dev/null
+++ b/src/com/android/tv/dialog/HalfSizedDialogFragment.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2016 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.tv.dialog;
+
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.tv.R;
+
+import java.util.concurrent.TimeUnit;
+
+public class HalfSizedDialogFragment extends SafeDismissDialogFragment {
+ public static final String DIALOG_TAG = HalfSizedDialogFragment.class.getSimpleName();
+ public static final String TRACKER_LABEL = "Half sized dialog";
+
+ private static final long AUTO_DISMISS_TIME_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30);
+
+ private OnActionClickListener mOnActionClickListener;
+
+ private Handler mHandler = new Handler();
+ private Runnable mAutoDismisser = new Runnable() {
+ @Override
+ public void run() {
+ dismiss();
+ }
+ };
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.halfsized_dialog, container, false);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mHandler.postDelayed(mAutoDismisser, AUTO_DISMISS_TIME_THRESHOLD_MS);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (mOnActionClickListener != null) {
+ // Dismisses the dialog to prevent the callback being forgotten during
+ // fragment re-creating.
+ dismiss();
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mHandler.removeCallbacks(mAutoDismisser);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Dialog dialog = super.onCreateDialog(savedInstanceState);
+ dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
+ public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent keyEvent) {
+ mHandler.removeCallbacks(mAutoDismisser);
+ mHandler.postDelayed(mAutoDismisser, AUTO_DISMISS_TIME_THRESHOLD_MS);
+ return false;
+ }
+ });
+ return dialog;
+ }
+
+ @Override
+ public int getTheme() {
+ return R.style.Theme_TV_dialog_HalfSizedDialog;
+ }
+
+ @Override
+ public String getTrackerLabel() {
+ return TRACKER_LABEL;
+ }
+
+ /**
+ * Sets {@link OnActionClickListener} for the dialog fragment. If listener is set, the dialog
+ * will be automatically closed when it's paused to prevent the fragment being re-created by
+ * the framework, which will result the listener being forgotten.
+ */
+ public void setOnActionClickListener(OnActionClickListener listener) {
+ mOnActionClickListener = listener;
+ }
+
+ /**
+ * Returns {@link OnActionClickListener} for sub-classes or any inner fragments.
+ */
+ protected OnActionClickListener getOnActionClickListener() {
+ return mOnActionClickListener;
+ }
+
+ /**
+ * An interface to provide callbacks for half-sized dialogs. Subclasses or inner fragments
+ * should invoke {@link OnActionClickListener#onActionClick(long)} and provide the identifier
+ * of the action user clicked.
+ */
+ public interface OnActionClickListener {
+ void onActionClick(long actionId);
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dialog/PinDialogFragment.java b/src/com/android/tv/dialog/PinDialogFragment.java
index d9d6c73f..d5c154da 100644
--- a/src/com/android/tv/dialog/PinDialogFragment.java
+++ b/src/com/android/tv/dialog/PinDialogFragment.java
@@ -28,6 +28,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Resources;
+import android.media.tv.TvContentRating;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
@@ -45,11 +46,13 @@ import android.widget.TextView;
import android.widget.Toast;
import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
import com.android.tv.util.TvSettings;
public class PinDialogFragment extends SafeDismissDialogFragment {
private static final String TAG = "PinDialogFragment";
- private static final boolean DBG = true;
+ private static final boolean DEBUG = true;
/**
* PIN code dialog for unlock channel
@@ -80,18 +83,13 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
*/
public static final int PIN_DIALOG_TYPE_UNLOCK_DVR = 5;
- private static final int PIN_DIALOG_RESULT_SUCCESS = 0;
- private static final int PIN_DIALOG_RESULT_FAIL = 1;
-
private static final int MAX_WRONG_PIN_COUNT = 5;
private static final int DISABLE_PIN_DURATION_MILLIS = 60 * 1000; // 1 minute
private static final String INITIAL_TEXT = "—";
private static final String TRACKER_LABEL = "Pin dialog";
-
- public interface ResultListener {
- void done(boolean success);
- }
+ private static final String ARGS_TYPE = "args_type";
+ private static final String ARGS_RATING = "args_rating";
public static final String DIALOG_TAG = PinDialogFragment.class.getName();
@@ -99,8 +97,9 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
R.id.first, R.id.second, R.id.third, R.id.fourth };
private int mType;
- private ResultListener mListener;
- private int mRetCode;
+ private int mRequestType;
+ private boolean mPinChecked;
+ private boolean mDismissSilently;
private TextView mWrongPinView;
private View mEnterPinView;
@@ -114,29 +113,35 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
private long mDisablePinUntil;
private final Handler mHandler = new Handler();
- public PinDialogFragment(int type, ResultListener listener) {
- this(type, listener, null);
+ public static PinDialogFragment create(int type) {
+ return create(type, null);
}
- public PinDialogFragment(int type, ResultListener listener, String rating) {
- mType = type;
- mListener = listener;
- mRetCode = PIN_DIALOG_RESULT_FAIL;
- mRatingString = rating;
+ public static PinDialogFragment create(int type, String rating) {
+ PinDialogFragment fragment = new PinDialogFragment();
+ Bundle args = new Bundle();
+ args.putInt(ARGS_TYPE, type);
+ args.putString(ARGS_RATING, rating);
+ fragment.setArguments(args);
+ return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mRequestType = getArguments().getInt(ARGS_TYPE, PIN_DIALOG_TYPE_ENTER_PIN);
+ mType = mRequestType;
+ mRatingString = getArguments().getString(ARGS_RATING);
setStyle(STYLE_NO_TITLE, 0);
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
mDisablePinUntil = TvSettings.getDisablePinUntil(getActivity());
if (ActivityManager.isUserAMonkey()) {
// Skip PIN dialog half the time for monkeys
if (Math.random() < 0.5) {
- exit(PIN_DIALOG_RESULT_SUCCESS);
+ exit(true);
}
}
+ mPinChecked = false;
}
@Override
@@ -186,7 +191,19 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
mTitleView.setText(R.string.pin_enter_unlock_program);
break;
case PIN_DIALOG_TYPE_UNLOCK_DVR:
- mTitleView.setText(getString(R.string.pin_enter_unlock_dvr, mRatingString));
+ TvContentRating tvContentRating =
+ TvContentRating.unflattenFromString(mRatingString);
+ if (TvContentRating.UNRATED.equals(tvContentRating)) {
+ mTitleView.setText(getString(R.string.pin_enter_unlock_dvr_unrated));
+ } else {
+ mTitleView.setText(
+ getString(
+ R.string.pin_enter_unlock_dvr,
+ TvApplication.getSingletons(getContext())
+ .getTvInputManagerHelper()
+ .getContentRatingsManager()
+ .getDisplayNameForRating(tvContentRating)));
+ }
break;
case PIN_DIALOG_TYPE_ENTER_PIN:
mTitleView.setText(R.string.pin_enter_pin);
@@ -217,10 +234,6 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
return v;
}
- public void setResultListener(ResultListener listener) {
- mListener = listener;
- }
-
private final Runnable mUpdateEnterPinRunnable = new Runnable() {
@Override
public void run() {
@@ -250,18 +263,27 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
}
}
- private void exit(int retCode) {
- mRetCode = retCode;
+ private void exit(boolean pinChecked) {
+ mPinChecked = pinChecked;
+ dismiss();
+ }
+
+ /** Dismisses the pin dialog without calling activity listener. */
+ public void dismissSilently() {
+ mDismissSilently = true;
dismiss();
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
- if (DBG) Log.d(TAG, "onDismiss: mRetCode=" + mRetCode);
- if (mListener != null) {
- mListener.done(mRetCode == PIN_DIALOG_RESULT_SUCCESS);
+ if (DEBUG) Log.d(TAG, "onDismiss: mPinChecked=" + mPinChecked);
+ SoftPreconditions.checkState(getActivity() instanceof OnPinCheckedListener);
+ if (!mDismissSilently && getActivity() instanceof OnPinCheckedListener) {
+ ((OnPinCheckedListener) getActivity()).onPinChecked(
+ mPinChecked, mRequestType, mRatingString);
}
+ mDismissSilently = false;
}
private void handleWrongPin() {
@@ -279,15 +301,14 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
}
private void done(String pin) {
- if (DBG) Log.d(TAG, "done: mType=" + mType + " pin=" + pin + " stored=" + getPin());
+ if (DEBUG) Log.d(TAG, "done: mType=" + mType + " pin=" + pin + " stored=" + getPin());
switch (mType) {
case PIN_DIALOG_TYPE_UNLOCK_CHANNEL:
case PIN_DIALOG_TYPE_UNLOCK_PROGRAM:
case PIN_DIALOG_TYPE_UNLOCK_DVR:
case PIN_DIALOG_TYPE_ENTER_PIN:
- // TODO: Implement limited number of retrials and timeout logic.
if (TextUtils.isEmpty(getPin()) || pin.equals(getPin())) {
- exit(PIN_DIALOG_RESULT_SUCCESS);
+ exit(true);
} else {
resetPinInput();
handleWrongPin();
@@ -301,7 +322,7 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
} else {
if (pin.equals(mPrevPin)) {
setPin(pin);
- exit(PIN_DIALOG_RESULT_SUCCESS);
+ exit(true);
} else {
if (TextUtils.isEmpty(getPin())) {
mTitleView.setText(R.string.pin_enter_create_pin);
@@ -332,7 +353,7 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
}
private void setPin(String pin) {
- if (DBG) Log.d(TAG, "setPin: " + pin);
+ if (DEBUG) Log.d(TAG, "setPin: " + pin);
mPin = pin;
mSharedPreferences.edit().putString(TvSettings.PREF_PIN, pin).apply();
}
@@ -684,4 +705,20 @@ public class PinDialogFragment extends SafeDismissDialogFragment {
: (value > mMaxValue) ? value - interval : value;
}
}
+
+ /**
+ * A listener to the result of {@link PinDialogFragment}. Any activity requiring pin code
+ * checking should implement this listener to receive the result.
+ */
+ public interface OnPinCheckedListener {
+ /**
+ * Called when {@link PinDialogFragment} is dismissed.
+ *
+ * @param checked {@code true} if the pin code entered is checked to be correct,
+ * otherwise {@code false}.
+ * @param type The dialog type regarding to what pin entering is for.
+ * @param rating The target rating to unblock for.
+ */
+ void onPinChecked(boolean checked, int type, String rating);
+ }
}
diff --git a/src/com/android/tv/dialog/SafeDismissDialogFragment.java b/src/com/android/tv/dialog/SafeDismissDialogFragment.java
index f671a87d..e3390b0a 100644
--- a/src/com/android/tv/dialog/SafeDismissDialogFragment.java
+++ b/src/com/android/tv/dialog/SafeDismissDialogFragment.java
@@ -17,11 +17,7 @@
package com.android.tv.dialog;
import android.app.Activity;
-import android.app.Dialog;
import android.app.DialogFragment;
-import android.content.Context;
-import android.os.Bundle;
-import android.view.KeyEvent;
import com.android.tv.MainActivity;
import com.android.tv.TvApplication;
@@ -39,11 +35,6 @@ public abstract class SafeDismissDialogFragment extends DialogFragment
private Tracker mTracker;
@Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- return new TvDialog(getActivity(), getTheme());
- }
-
- @Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mAttached = true;
@@ -92,21 +83,4 @@ public abstract class SafeDismissDialogFragment extends DialogFragment
super.dismiss();
}
}
-
- protected class TvDialog extends Dialog {
- public TvDialog(Context context, int theme) {
- super(context, theme);
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- // When a dialog is showing, key events are handled by the dialog instead of
- // MainActivity. Therefore, unless a key is a global key, it should be handled here.
- if (mAttached && keyCode == KeyEvent.KEYCODE_SEARCH && mActivity != null) {
- mActivity.showSearchActivity();
- return true;
- }
- return super.onKeyUp(keyCode, event);
- }
- }
}
diff --git a/src/com/android/tv/dialog/WebDialogFragment.java b/src/com/android/tv/dialog/WebDialogFragment.java
index 75f93bb2..171a256b 100644
--- a/src/com/android/tv/dialog/WebDialogFragment.java
+++ b/src/com/android/tv/dialog/WebDialogFragment.java
@@ -37,6 +37,7 @@ public class WebDialogFragment extends SafeDismissDialogFragment {
private static final String TITLE = "TITLE";
private static final String TRACKER_LABEL = "TRACKER_LABEL";
+ private WebView mWebView;
private String mTrackerLabel;
/**
@@ -73,13 +74,21 @@ public class WebDialogFragment extends SafeDismissDialogFragment {
String title = getArguments().getString(TITLE);
getDialog().setTitle(title);
- WebView webView = new WebView(getActivity());
- webView.setWebViewClient(new WebViewClient());
+ mWebView = new WebView(getActivity());
+ mWebView.setWebViewClient(new WebViewClient());
String url = getArguments().getString(URL);
- webView.loadUrl(url);
+ mWebView.loadUrl(url);
Log.d(TAG, "Loading web content from " + url);
- return webView;
+ return mWebView;
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ if (mWebView != null) {
+ mWebView.destroy();
+ }
}
@Override
diff --git a/src/com/android/tv/dvr/BaseDvrDataManager.java b/src/com/android/tv/dvr/BaseDvrDataManager.java
index 89661df3..a8637449 100644
--- a/src/com/android/tv/dvr/BaseDvrDataManager.java
+++ b/src/com/android/tv/dvr/BaseDvrDataManager.java
@@ -26,7 +26,10 @@ import android.util.Log;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.dvr.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.util.Clock;
import java.util.ArrayList;
@@ -318,5 +321,41 @@ public abstract class BaseDvrDataManager implements WritableDvrDataManager {
}
@Override
+ public void checkAndRemoveEmptySeriesRecording(long... seriesRecordingIds) {
+ List<SeriesRecording> toRemove = new ArrayList<>();
+ for (long rId : seriesRecordingIds) {
+ SeriesRecording seriesRecording = getSeriesRecording(rId);
+ if (seriesRecording != null && isEmptySeriesRecording(seriesRecording)) {
+ toRemove.add(seriesRecording);
+ }
+ }
+ removeSeriesRecording(SeriesRecording.toArray(toRemove));
+ }
+
+ /**
+ * Returns {@code true}, if the series recording is empty and can be removed. If a series
+ * recording is in NORMAL state or has recordings or schedules, it is not empty and cannot be
+ * removed.
+ */
+ protected final boolean isEmptySeriesRecording(@NonNull SeriesRecording seriesRecording) {
+ if (!seriesRecording.isStopped()) {
+ return false;
+ }
+ long seriesRecordingId = seriesRecording.getId();
+ for (ScheduledRecording r : getAvailableScheduledRecordings()) {
+ if (r.getSeriesRecordingId() == seriesRecordingId) {
+ return false;
+ }
+ }
+ String seriesId = seriesRecording.getSeriesId();
+ for (RecordedProgram r : getRecordedPrograms()) {
+ if (seriesId.equals(r.getSeriesId())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
public void forgetStorage(String inputId) { }
}
diff --git a/src/com/android/tv/dvr/ConflictChecker.java b/src/com/android/tv/dvr/ConflictChecker.java
deleted file mode 100644
index 201e379e..00000000
--- a/src/com/android/tv/dvr/ConflictChecker.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import android.annotation.TargetApi;
-import android.content.ContentUris;
-import android.media.tv.TvContract;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Message;
-import android.support.annotation.MainThread;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.tv.ApplicationSingletons;
-import com.android.tv.InputSessionManager;
-import com.android.tv.InputSessionManager.OnTvViewChannelChangeListener;
-import com.android.tv.MainActivity;
-import com.android.tv.TvApplication;
-import com.android.tv.common.WeakHandler;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Checking the runtime conflict of DVR recording.
- * <p>
- * This class runs only while the {@link MainActivity} is resumed and holds the upcoming conflicts.
- */
-@TargetApi(Build.VERSION_CODES.N)
-@MainThread
-public class ConflictChecker {
- private static final String TAG = "ConflictChecker";
- private static final boolean DEBUG = false;
-
- private static final int MSG_CHECK_CONFLICT = 1;
-
- private static final long CHECK_RETRY_PERIOD_MS = TimeUnit.SECONDS.toMillis(30);
-
- /**
- * To show watch conflict dialog, the start time of the earliest conflicting schedule should be
- * less than or equal to this time.
- */
- private static final long MAX_WATCH_CONFLICT_CHECK_TIME_MS = TimeUnit.MINUTES.toMillis(5);
- /**
- * To show watch conflict dialog, the start time of the earliest conflicting schedule should be
- * greater than or equal to this time.
- */
- private static final long MIN_WATCH_CONFLICT_CHECK_TIME_MS = TimeUnit.SECONDS.toMillis(30);
-
- private final MainActivity mMainActivity;
- private final ChannelDataManager mChannelDataManager;
- private final DvrScheduleManager mScheduleManager;
- private final InputSessionManager mSessionManager;
- private final ConflictCheckerHandler mHandler = new ConflictCheckerHandler(this);
-
- private final List<ScheduledRecording> mUpcomingConflicts = new ArrayList<>();
- private final Set<OnUpcomingConflictChangeListener> mOnUpcomingConflictChangeListeners =
- new ArraySet<>();
- private final Map<Long, List<ScheduledRecording>> mCheckedConflictsMap = new HashMap<>();
-
- private final ScheduledRecordingListener mScheduledRecordingListener =
- new ScheduledRecordingListener() {
- @Override
- public void onScheduledRecordingAdded(ScheduledRecording... scheduledRecordings) {
- if (DEBUG) Log.d(TAG, "onScheduledRecordingAdded: " + scheduledRecordings);
- mHandler.sendEmptyMessage(MSG_CHECK_CONFLICT);
- }
-
- @Override
- public void onScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings) {
- if (DEBUG) Log.d(TAG, "onScheduledRecordingRemoved: " + scheduledRecordings);
- mHandler.sendEmptyMessage(MSG_CHECK_CONFLICT);
- }
-
- @Override
- public void onScheduledRecordingStatusChanged(ScheduledRecording... scheduledRecordings) {
- if (DEBUG) Log.d(TAG, "onScheduledRecordingStatusChanged: " + scheduledRecordings);
- mHandler.sendEmptyMessage(MSG_CHECK_CONFLICT);
- }
- };
-
- private final OnTvViewChannelChangeListener mOnTvViewChannelChangeListener =
- new OnTvViewChannelChangeListener() {
- @Override
- public void onTvViewChannelChange(@Nullable Uri channelUri) {
- mHandler.sendEmptyMessage(MSG_CHECK_CONFLICT);
- }
- };
-
- private boolean mStarted;
-
- public ConflictChecker(MainActivity mainActivity) {
- mMainActivity = mainActivity;
- ApplicationSingletons appSingletons = TvApplication.getSingletons(mainActivity);
- mChannelDataManager = appSingletons.getChannelDataManager();
- mScheduleManager = appSingletons.getDvrScheduleManager();
- mSessionManager = appSingletons.getInputSessionManager();
- }
-
- /**
- * Starts checking the conflict.
- */
- public void start() {
- if (mStarted) {
- return;
- }
- mStarted = true;
- mHandler.sendEmptyMessage(MSG_CHECK_CONFLICT);
- mScheduleManager.addScheduledRecordingListener(mScheduledRecordingListener);
- mSessionManager.addOnTvViewChannelChangeListener(mOnTvViewChannelChangeListener);
- }
-
- /**
- * Stops checking the conflict.
- */
- public void stop() {
- if (!mStarted) {
- return;
- }
- mStarted = false;
- mSessionManager.removeOnTvViewChannelChangeListener(mOnTvViewChannelChangeListener);
- mScheduleManager.removeScheduledRecordingListener(mScheduledRecordingListener);
- mHandler.removeCallbacksAndMessages(null);
- }
-
- /**
- * Returns the upcoming conflicts.
- */
- public List<ScheduledRecording> getUpcomingConflicts() {
- return new ArrayList<>(mUpcomingConflicts);
- }
-
- /**
- * Adds a {@link OnUpcomingConflictChangeListener}.
- */
- public void addOnUpcomingConflictChangeListener(OnUpcomingConflictChangeListener listener) {
- mOnUpcomingConflictChangeListeners.add(listener);
- }
-
- /**
- * Removes the {@link OnUpcomingConflictChangeListener}.
- */
- public void removeOnUpcomingConflictChangeListener(OnUpcomingConflictChangeListener listener) {
- mOnUpcomingConflictChangeListeners.remove(listener);
- }
-
- private void notifyUpcomingConflictChanged() {
- for (OnUpcomingConflictChangeListener l : mOnUpcomingConflictChangeListeners) {
- l.onUpcomingConflictChange();
- }
- }
-
- /**
- * Remembers the user's decision to record while watching the channel.
- */
- public void setCheckedConflictsForChannel(long mChannelId, List<ScheduledRecording> conflicts) {
- mCheckedConflictsMap.put(mChannelId, new ArrayList<>(conflicts));
- }
-
- void onCheckConflict() {
- // Checks the conflicting schedules and setup the next re-check time.
- // If there are upcoming conflicts soon, it opens the conflict dialog.
- if (DEBUG) Log.d(TAG, "Handling MSG_CHECK_CONFLICT");
- mHandler.removeMessages(MSG_CHECK_CONFLICT);
- mUpcomingConflicts.clear();
- if (!mScheduleManager.isInitialized()
- || !mChannelDataManager.isDbLoadFinished()) {
- mHandler.sendEmptyMessageDelayed(MSG_CHECK_CONFLICT, CHECK_RETRY_PERIOD_MS);
- notifyUpcomingConflictChanged();
- return;
- }
- if (mSessionManager.getCurrentTvViewChannelUri() == null) {
- // As MainActivity is not using a tuner, no need to check the conflict.
- notifyUpcomingConflictChanged();
- return;
- }
- Uri channelUri = mSessionManager.getCurrentTvViewChannelUri();
- if (TvContract.isChannelUriForPassthroughInput(channelUri)) {
- notifyUpcomingConflictChanged();
- return;
- }
- long channelId = ContentUris.parseId(channelUri);
- Channel channel = mChannelDataManager.getChannel(channelId);
- // The conflicts caused by watching the channel.
- List<ScheduledRecording> conflicts = mScheduleManager
- .getConflictingSchedulesForWatching(channel.getId());
- long earliestToCheck = Long.MAX_VALUE;
- long currentTimeMs = System.currentTimeMillis();
- for (ScheduledRecording schedule : conflicts) {
- long startTimeMs = schedule.getStartTimeMs();
- if (startTimeMs < currentTimeMs + MIN_WATCH_CONFLICT_CHECK_TIME_MS) {
- // The start time of the upcoming conflict remains less than the minimum
- // check time.
- continue;
- }
- if (startTimeMs > currentTimeMs + MAX_WATCH_CONFLICT_CHECK_TIME_MS) {
- // The start time of the upcoming conflict remains greater than the
- // maximum check time. Setup the next re-check time.
- long nextCheckTimeMs = startTimeMs - MAX_WATCH_CONFLICT_CHECK_TIME_MS;
- if (earliestToCheck > nextCheckTimeMs) {
- earliestToCheck = nextCheckTimeMs;
- }
- } else {
- // Found upcoming conflicts which will start soon.
- mUpcomingConflicts.add(schedule);
- // The schedule will be removed from the "upcoming conflict" when the
- // recording is almost started.
- long nextCheckTimeMs = startTimeMs - MIN_WATCH_CONFLICT_CHECK_TIME_MS;
- if (earliestToCheck > nextCheckTimeMs) {
- earliestToCheck = nextCheckTimeMs;
- }
- }
- }
- if (earliestToCheck != Long.MAX_VALUE) {
- mHandler.sendEmptyMessageDelayed(MSG_CHECK_CONFLICT,
- earliestToCheck - currentTimeMs);
- }
- if (DEBUG) Log.d(TAG, "upcoming conflicts: " + mUpcomingConflicts);
- notifyUpcomingConflictChanged();
- if (!mUpcomingConflicts.isEmpty()
- && !DvrUiHelper.isChannelWatchConflictDialogShown(mMainActivity)) {
- // Don't show the conflict dialog if the user already knows.
- List<ScheduledRecording> checkedConflicts = mCheckedConflictsMap.get(
- channel.getId());
- if (checkedConflicts == null
- || !checkedConflicts.containsAll(mUpcomingConflicts)) {
- DvrUiHelper.showChannelWatchConflictDialog(mMainActivity, channel);
- }
- }
- }
-
- private static class ConflictCheckerHandler extends WeakHandler<ConflictChecker> {
- ConflictCheckerHandler(ConflictChecker conflictChecker) {
- super(conflictChecker);
- }
-
- @Override
- protected void handleMessage(Message msg, @NonNull ConflictChecker conflictChecker) {
- switch (msg.what) {
- case MSG_CHECK_CONFLICT:
- conflictChecker.onCheckConflict();
- break;
- }
- }
- }
-
- /**
- * A listener for the change of upcoming conflicts.
- */
- public interface OnUpcomingConflictChangeListener {
- void onUpcomingConflictChange();
- }
-}
diff --git a/src/com/android/tv/dvr/DvrDataManager.java b/src/com/android/tv/dvr/DvrDataManager.java
index 06613667..6d400b82 100644
--- a/src/com/android/tv/dvr/DvrDataManager.java
+++ b/src/com/android/tv/dvr/DvrDataManager.java
@@ -21,7 +21,10 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Range;
-import com.android.tv.dvr.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.data.SeriesRecording;
import java.util.Collection;
import java.util.List;
@@ -211,6 +214,13 @@ public interface DvrDataManager {
Collection<Long> getDisallowedProgramIds();
/**
+ * Checks each of the give series recordings to see if it's empty, i.e., it doesn't contains
+ * any available schedules or recorded programs, and it's status is
+ * {@link SeriesRecording#STATE_SERIES_STOPPED}; and removes those empty series recordings.
+ */
+ void checkAndRemoveEmptySeriesRecording(long... seriesRecordingIds);
+
+ /**
* Listens for the DVR schedules loading finished.
*/
interface OnDvrScheduleLoadFinishedListener {
diff --git a/src/com/android/tv/dvr/DvrDataManagerImpl.java b/src/com/android/tv/dvr/DvrDataManagerImpl.java
index 46682a48..6094ca72 100644
--- a/src/com/android/tv/dvr/DvrDataManagerImpl.java
+++ b/src/com/android/tv/dvr/DvrDataManagerImpl.java
@@ -42,7 +42,11 @@ import android.util.Range;
import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.dvr.DvrStorageStatusManager.OnStorageMountChangedListener;
-import com.android.tv.dvr.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.data.IdGenerator;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.AsyncDvrDbTask.AsyncAddScheduleTask;
import com.android.tv.dvr.provider.AsyncDvrDbTask.AsyncAddSeriesRecordingTask;
import com.android.tv.dvr.provider.AsyncDvrDbTask.AsyncDeleteScheduleTask;
@@ -51,12 +55,14 @@ import com.android.tv.dvr.provider.AsyncDvrDbTask.AsyncDvrQueryScheduleTask;
import com.android.tv.dvr.provider.AsyncDvrDbTask.AsyncDvrQuerySeriesRecordingTask;
import com.android.tv.dvr.provider.AsyncDvrDbTask.AsyncUpdateScheduleTask;
import com.android.tv.dvr.provider.AsyncDvrDbTask.AsyncUpdateSeriesRecordingTask;
+import com.android.tv.dvr.provider.DvrDbSync;
+import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.AsyncDbTask.AsyncRecordedProgramQueryTask;
import com.android.tv.util.Clock;
import com.android.tv.util.Filter;
import com.android.tv.util.TvInputManagerHelper;
-import com.android.tv.util.TvProviderUriMatcher;
+import com.android.tv.util.TvUriMatcher;
import com.android.tv.util.Utils;
import java.util.ArrayList;
@@ -267,11 +273,14 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
removeScheduledRecording(ScheduledRecording.toArray(toDelete));
}
IdGenerator.SCHEDULED_RECORDING.setMaxId(maxId);
+ if (mRecordedProgramLoadFinished) {
+ validateSeriesRecordings();
+ }
mDvrLoadFinished = true;
notifyDvrScheduleLoadFinished();
- mDbSync = new DvrDbSync(mContext, DvrDataManagerImpl.this);
- mDbSync.start();
if (isInitialized()) {
+ mDbSync = new DvrDbSync(mContext, DvrDataManagerImpl.this);
+ mDbSync.start();
SeriesRecordingScheduler.getInstance(mContext).start();
}
}
@@ -306,8 +315,11 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
if (uri == null) {
uri = RecordedPrograms.CONTENT_URI;
}
- int match = TvProviderUriMatcher.match(uri);
- if (match == TvProviderUriMatcher.MATCH_RECORDED_PROGRAM) {
+ if (recordedPrograms == null) {
+ recordedPrograms = Collections.emptyList();
+ }
+ int match = TvUriMatcher.match(uri);
+ if (match == TvUriMatcher.MATCH_RECORDED_PROGRAM) {
if (!mRecordedProgramLoadFinished) {
for (RecordedProgram recorded : recordedPrograms) {
if (isInputAvailable(recorded.getInputId())) {
@@ -318,7 +330,11 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
mRecordedProgramLoadFinished = true;
notifyRecordedProgramLoadFinished();
- } else if (recordedPrograms == null || recordedPrograms.isEmpty()) {
+ if (isInitialized()) {
+ mDbSync = new DvrDbSync(mContext, DvrDataManagerImpl.this);
+ mDbSync.start();
+ }
+ } else if (recordedPrograms.isEmpty()) {
List<RecordedProgram> oldRecordedPrograms =
new ArrayList<>(mRecordedPrograms.values());
mRecordedPrograms.clear();
@@ -355,19 +371,24 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
}
if (isInitialized()) {
+ validateSeriesRecordings();
SeriesRecordingScheduler.getInstance(mContext).start();
}
- } else if (match == TvProviderUriMatcher.MATCH_RECORDED_PROGRAM_ID) {
+ } else if (match == TvUriMatcher.MATCH_RECORDED_PROGRAM_ID) {
if (!mRecordedProgramLoadFinished) {
return;
}
long id = ContentUris.parseId(uri);
if (DEBUG) Log.d(TAG, "changed recorded program #" + id + " to " + recordedPrograms);
- if (recordedPrograms == null || recordedPrograms.isEmpty()) {
+ if (recordedPrograms.isEmpty()) {
mRecordedProgramsForRemovedInput.remove(id);
RecordedProgram old = mRecordedPrograms.remove(id);
if (old != null) {
notifyRecordedProgramsRemoved(old);
+ SeriesRecording r = mSeriesId2SeriesRecordings.get(old.getSeriesId());
+ if (r != null && isEmptySeriesRecording(r)) {
+ removeSeriesRecording(r);
+ }
}
} else {
RecordedProgram recordedProgram = recordedPrograms.get(0);
@@ -592,10 +613,16 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
public void removeScheduledRecording(boolean forceRemove, ScheduledRecording... schedules) {
List<ScheduledRecording> schedulesToDelete = new ArrayList<>();
List<ScheduledRecording> schedulesNotToDelete = new ArrayList<>();
+ Set<Long> seriesRecordingIdsToCheck = new HashSet<>();
for (ScheduledRecording r : schedules) {
mScheduledRecordings.remove(r.getId());
- getDeletedScheduleMap().remove(r.getId());
+ getDeletedScheduleMap().remove(r.getProgramId());
mProgramId2ScheduledRecordings.remove(r.getProgramId());
+ if (r.getSeriesRecordingId() != SeriesRecording.ID_NOT_SET
+ && (r.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED
+ || r.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS)) {
+ seriesRecordingIdsToCheck.add(r.getSeriesRecordingId());
+ }
boolean isScheduleForRemovedInput =
mScheduledRecordingsForRemovedInput.remove(r.getProgramId()) != null;
// If it belongs to the series recording and it's not started yet, just mark delete
@@ -614,8 +641,19 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
}
if (mDvrLoadFinished) {
+ if (mRecordedProgramLoadFinished) {
+ checkAndRemoveEmptySeriesRecording(seriesRecordingIdsToCheck);
+ }
notifyScheduledRecordingRemoved(schedules);
}
+ Iterator<ScheduledRecording> iterator = schedulesNotToDelete.iterator();
+ while (iterator.hasNext()) {
+ ScheduledRecording r = iterator.next();
+ if (!mSeriesRecordings.containsKey(r.getSeriesRecordingId())) {
+ iterator.remove();
+ schedulesToDelete.add(r);
+ }
+ }
if (!schedulesToDelete.isEmpty()) {
new AsyncDeleteScheduleTask(mContext).executeOnDbThread(
ScheduledRecording.toArray(schedulesToDelete));
@@ -669,6 +707,7 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
private void updateScheduledRecording(boolean updateDb, final ScheduledRecording... schedules) {
List<ScheduledRecording> toUpdate = new ArrayList<>();
+ Set<Long> seriesRecordingIdsToCheck = new HashSet<>();
for (ScheduledRecording r : schedules) {
if (!SoftPreconditions.checkState(mScheduledRecordings.containsKey(r.getId()), TAG,
"Recording not found for: " + r)) {
@@ -691,6 +730,13 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
if (programId != ScheduledRecording.ID_NOT_SET) {
mProgramId2ScheduledRecordings.put(programId, r);
}
+ if (r.getState() == ScheduledRecording.STATE_RECORDING_FAILED
+ && r.getSeriesRecordingId() != SeriesRecording.ID_NOT_SET) {
+ // If the scheduled recording is failed, it may cause the automatically generated
+ // series recording for this schedule becomes invalid (with no future schedules and
+ // past recordings.) We should check and remove these series recordings.
+ seriesRecordingIdsToCheck.add(r.getSeriesRecordingId());
+ }
}
if (toUpdate.isEmpty()) {
return;
@@ -702,12 +748,17 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
if (updateDb) {
new AsyncUpdateScheduleTask(mContext).executeOnDbThread(scheduleArray);
}
+ checkAndRemoveEmptySeriesRecording(seriesRecordingIdsToCheck);
removeDeletedSchedules(schedules);
}
@Override
public void updateSeriesRecording(final SeriesRecording... seriesRecordings) {
for (SeriesRecording r : seriesRecordings) {
+ if (!SoftPreconditions.checkArgument(mSeriesRecordings.containsKey(r.getId()), TAG,
+ "Non Existing Series ID: " + r)) {
+ continue;
+ }
SeriesRecording old1 = mSeriesRecordings.put(r.getId(), r);
SeriesRecording old2 = mSeriesId2SeriesRecordings.put(r.getSeriesId(), r);
SoftPreconditions.checkArgument(old1.equals(old2), TAG, "Series ID cannot be"
@@ -769,14 +820,6 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
return r.getInputId().equals(inputId);
}
});
- List<SeriesRecording> movedSeriesRecordings =
- moveElements(mSeriesRecordingsForRemovedInput, mSeriesRecordings,
- new Filter<SeriesRecording>() {
- @Override
- public boolean filter(SeriesRecording r) {
- return r.getInputId().equals(inputId);
- }
- });
List<RecordedProgram> movedRecordedPrograms =
moveElements(mRecordedProgramsForRemovedInput, mRecordedPrograms,
new Filter<RecordedProgram>() {
@@ -785,6 +828,21 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
return r.getInputId().equals(inputId);
}
});
+ List<SeriesRecording> removedSeriesRecordings = new ArrayList<>();
+ List<SeriesRecording> movedSeriesRecordings =
+ moveElements(mSeriesRecordingsForRemovedInput, mSeriesRecordings,
+ new Filter<SeriesRecording>() {
+ @Override
+ public boolean filter(SeriesRecording r) {
+ if (r.getInputId().equals(inputId)) {
+ if (!isEmptySeriesRecording(r)) {
+ return true;
+ }
+ removedSeriesRecordings.add(r);
+ }
+ return false;
+ }
+ });
if (!movedSchedules.isEmpty()) {
for (ScheduledRecording schedule : movedSchedules) {
mProgramId2ScheduledRecordings.put(schedule.getProgramId(), schedule);
@@ -795,6 +853,11 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
mSeriesId2SeriesRecordings.put(seriesRecording.getSeriesId(), seriesRecording);
}
}
+ for (SeriesRecording r : removedSeriesRecordings) {
+ mSeriesRecordingsForRemovedInput.remove(r.getId());
+ }
+ new AsyncDeleteSeriesRecordingTask(mContext).executeOnDbThread(
+ SeriesRecording.toArray(removedSeriesRecordings));
// Notify after all the data are moved.
if (!movedSchedules.isEmpty()) {
notifyScheduledRecordingAdded(ScheduledRecording.toArray(movedSchedules));
@@ -811,20 +874,20 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
if (DEBUG) Log.d(TAG, "hideInput " + inputId);
List<ScheduledRecording> movedSchedules =
moveElements(mScheduledRecordings, mScheduledRecordingsForRemovedInput,
- new Filter<ScheduledRecording>() {
- @Override
- public boolean filter(ScheduledRecording r) {
- return r.getInputId().equals(inputId);
- }
- });
+ new Filter<ScheduledRecording>() {
+ @Override
+ public boolean filter(ScheduledRecording r) {
+ return r.getInputId().equals(inputId);
+ }
+ });
List<SeriesRecording> movedSeriesRecordings =
moveElements(mSeriesRecordings, mSeriesRecordingsForRemovedInput,
- new Filter<SeriesRecording>() {
- @Override
- public boolean filter(SeriesRecording r) {
- return r.getInputId().equals(inputId);
- }
- });
+ new Filter<SeriesRecording>() {
+ @Override
+ public boolean filter(SeriesRecording r) {
+ return r.getInputId().equals(inputId);
+ }
+ });
List<RecordedProgram> movedRecordedPrograms =
moveElements(mRecordedPrograms, mRecordedProgramsForRemovedInput,
new Filter<RecordedProgram>() {
@@ -855,6 +918,15 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}
}
+ private void checkAndRemoveEmptySeriesRecording(Set<Long> seriesRecordingIds) {
+ int i = 0;
+ long[] rIds = new long[seriesRecordingIds.size()];
+ for (long rId : seriesRecordingIds) {
+ rIds[i++] = rId;
+ }
+ checkAndRemoveEmptySeriesRecording(rIds);
+ }
+
@Override
public void forgetStorage(String inputId) {
List<ScheduledRecording> schedulesToDelete = new ArrayList<>();
@@ -901,6 +973,25 @@ public class DvrDataManagerImpl extends BaseDvrDataManager {
}.executeOnDbThread();
}
+ private void validateSeriesRecordings() {
+ Iterator<SeriesRecording> iter = mSeriesRecordings.values().iterator();
+ List<SeriesRecording> removedSeriesRecordings = new ArrayList<>();
+ while (iter.hasNext()) {
+ SeriesRecording r = iter.next();
+ if (isEmptySeriesRecording(r)) {
+ iter.remove();
+ removedSeriesRecordings.add(r);
+ }
+ }
+ if (!removedSeriesRecordings.isEmpty()) {
+ SeriesRecording[] removed = SeriesRecording.toArray(removedSeriesRecordings);
+ new AsyncDeleteSeriesRecordingTask(mContext).executeOnDbThread(removed);
+ if (mDvrLoadFinished) {
+ notifySeriesRecordingRemoved(removed);
+ }
+ }
+ }
+
private final class RecordedProgramsQueryTask extends AsyncRecordedProgramQueryTask {
private final Uri mUri;
diff --git a/src/com/android/tv/dvr/DvrDbSync.java b/src/com/android/tv/dvr/DvrDbSync.java
deleted file mode 100644
index df181455..00000000
--- a/src/com/android/tv/dvr/DvrDbSync.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.content.ContentUris;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.media.tv.TvContract.Programs;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
-import android.support.annotation.MainThread;
-import android.support.annotation.VisibleForTesting;
-import android.util.Log;
-
-import com.android.tv.TvApplication;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.Program;
-import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
-import com.android.tv.util.AsyncDbTask.AsyncQueryProgramTask;
-import com.android.tv.util.TvProviderUriMatcher;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Queue;
-import java.util.Set;
-
-/**
- * A class to synchronizes DVR DB with TvProvider.
- *
- * <p>The current implementation of AsyncDbTask allows only one task to run at a time, and all the
- * other tasks are blocked until the current one finishes. As this class performs the low priority
- * jobs which take long time, it should not block others if possible. For this reason, only one
- * program is queried at a time and others are queued and will be executed on the other
- * AsyncDbTask's after the current one finishes to minimize the execution time of one AsyncDbTask.
- */
-@MainThread
-@TargetApi(Build.VERSION_CODES.N)
-class DvrDbSync {
- private static final String TAG = "DvrDbSync";
- private static final boolean DEBUG = false;
-
- private final Context mContext;
- private final DvrDataManagerImpl mDataManager;
- private final ChannelDataManager mChannelDataManager;
- private final Queue<Long> mProgramIdQueue = new LinkedList<>();
- private QueryProgramTask mQueryProgramTask;
- private final SeriesRecordingScheduler mSeriesRecordingScheduler;
- private final ContentObserver mContentObserver = new ContentObserver(new Handler(
- Looper.getMainLooper())) {
- @SuppressLint("SwitchIntDef")
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- switch (TvProviderUriMatcher.match(uri)) {
- case TvProviderUriMatcher.MATCH_PROGRAM:
- if (DEBUG) Log.d(TAG, "onProgramsUpdated");
- onProgramsUpdated();
- break;
- case TvProviderUriMatcher.MATCH_PROGRAM_ID:
- if (DEBUG) {
- Log.d(TAG, "onProgramUpdated: programId=" + ContentUris.parseId(uri));
- }
- onProgramUpdated(ContentUris.parseId(uri));
- break;
- }
- }
- };
-
- private final ChannelDataManager.Listener mChannelDataManagerListener =
- new ChannelDataManager.Listener() {
- @Override
- public void onLoadFinished() {
- start();
- }
-
- @Override
- public void onChannelListUpdated() {
- onChannelsUpdated();
- }
-
- @Override
- public void onChannelBrowsableChanged() { }
- };
-
- private final ScheduledRecordingListener mScheduleListener = new ScheduledRecordingListener() {
- @Override
- public void onScheduledRecordingAdded(ScheduledRecording... schedules) {
- for (ScheduledRecording schedule : schedules) {
- addProgramIdToCheckIfNeeded(schedule);
- }
- startNextUpdateIfNeeded();
- }
-
- @Override
- public void onScheduledRecordingRemoved(ScheduledRecording... schedules) {
- for (ScheduledRecording schedule : schedules) {
- mProgramIdQueue.remove(schedule.getProgramId());
- }
- }
-
- @Override
- public void onScheduledRecordingStatusChanged(ScheduledRecording... schedules) {
- for (ScheduledRecording schedule : schedules) {
- mProgramIdQueue.remove(schedule.getProgramId());
- addProgramIdToCheckIfNeeded(schedule);
- }
- startNextUpdateIfNeeded();
- }
- };
-
- DvrDbSync(Context context, DvrDataManagerImpl dataManager) {
- this(context, dataManager, TvApplication.getSingletons(context).getChannelDataManager());
- }
-
- @VisibleForTesting
- DvrDbSync(Context context, DvrDataManagerImpl dataManager,
- ChannelDataManager channelDataManager) {
- mContext = context;
- mDataManager = dataManager;
- mChannelDataManager = channelDataManager;
- mSeriesRecordingScheduler = SeriesRecordingScheduler.getInstance(context);
- }
-
- /**
- * Starts the DB sync.
- */
- public void start() {
- if (!mChannelDataManager.isDbLoadFinished()) {
- mChannelDataManager.addListener(mChannelDataManagerListener);
- return;
- }
- mContext.getContentResolver().registerContentObserver(Programs.CONTENT_URI, true,
- mContentObserver);
- mDataManager.addScheduledRecordingListener(mScheduleListener);
- onChannelsUpdated();
- onProgramsUpdated();
- }
-
- /**
- * Stops the DB sync.
- */
- public void stop() {
- mProgramIdQueue.clear();
- if (mQueryProgramTask != null) {
- mQueryProgramTask.cancel(true);
- }
- mChannelDataManager.removeListener(mChannelDataManagerListener);
- mDataManager.removeScheduledRecordingListener(mScheduleListener);
- mContext.getContentResolver().unregisterContentObserver(mContentObserver);
- }
-
- private void onChannelsUpdated() {
- List<SeriesRecording> seriesRecordingsToUpdate = new ArrayList<>();
- for (SeriesRecording r : mDataManager.getSeriesRecordings()) {
- if (r.getChannelOption() == SeriesRecording.OPTION_CHANNEL_ONE
- && !mChannelDataManager.doesChannelExistInDb(r.getChannelId())) {
- seriesRecordingsToUpdate.add(SeriesRecording.buildFrom(r)
- .setChannelOption(SeriesRecording.OPTION_CHANNEL_ALL)
- .setState(SeriesRecording.STATE_SERIES_STOPPED).build());
- }
- }
- if (!seriesRecordingsToUpdate.isEmpty()) {
- mDataManager.updateSeriesRecording(
- SeriesRecording.toArray(seriesRecordingsToUpdate));
- }
- List<ScheduledRecording> schedulesToRemove = new ArrayList<>();
- for (ScheduledRecording r : mDataManager.getAvailableScheduledRecordings()) {
- if (!mChannelDataManager.doesChannelExistInDb(r.getChannelId())) {
- schedulesToRemove.add(r);
- mProgramIdQueue.remove(r.getProgramId());
- }
- }
- if (!schedulesToRemove.isEmpty()) {
- mDataManager.removeScheduledRecording(
- ScheduledRecording.toArray(schedulesToRemove));
- }
- }
-
- private void onProgramsUpdated() {
- for (ScheduledRecording schedule : mDataManager.getAvailableScheduledRecordings()) {
- addProgramIdToCheckIfNeeded(schedule);
- }
- startNextUpdateIfNeeded();
- }
-
- private void onProgramUpdated(long programId) {
- addProgramIdToCheckIfNeeded(mDataManager.getScheduledRecordingForProgramId(programId));
- startNextUpdateIfNeeded();
- }
-
- private void addProgramIdToCheckIfNeeded(ScheduledRecording schedule) {
- if (schedule == null) {
- return;
- }
- long programId = schedule.getProgramId();
- if (programId != ScheduledRecording.ID_NOT_SET
- && !mProgramIdQueue.contains(programId)
- && (schedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED
- || schedule.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS)) {
- if (DEBUG) Log.d(TAG, "Program ID enqueued: " + programId);
- mProgramIdQueue.offer(programId);
- // There are schedules to be updated. Pause the SeriesRecordingScheduler until all the
- // schedule updates finish.
- // Note that the SeriesRecordingScheduler should be paused even though the program to
- // check is not episodic because it can be changed to the episodic program after the
- // update, which affect the SeriesRecordingScheduler.
- mSeriesRecordingScheduler.pauseUpdate();
- }
- }
-
- private void startNextUpdateIfNeeded() {
- if (mQueryProgramTask != null && !mQueryProgramTask.isCancelled()) {
- return;
- }
- if (!mProgramIdQueue.isEmpty()) {
- if (DEBUG) Log.d(TAG, "Program ID dequeued: " + mProgramIdQueue.peek());
- mQueryProgramTask = new QueryProgramTask(mProgramIdQueue.poll());
- mQueryProgramTask.executeOnDbThread();
- } else {
- mSeriesRecordingScheduler.resumeUpdate();
- }
- }
-
- @VisibleForTesting
- void handleUpdateProgram(Program program, long programId) {
- Set<SeriesRecording> seriesRecordingsToUpdate = new HashSet<>();
- ScheduledRecording schedule = mDataManager.getScheduledRecordingForProgramId(programId);
- if (schedule != null
- && (schedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED
- || schedule.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS)) {
- if (program == null) {
- mDataManager.removeScheduledRecording(schedule);
- if (schedule.getSeriesRecordingId() != SeriesRecording.ID_NOT_SET) {
- SeriesRecording seriesRecording =
- mDataManager.getSeriesRecording(schedule.getSeriesRecordingId());
- if (seriesRecording != null) {
- seriesRecordingsToUpdate.add(seriesRecording);
- }
- }
- } else {
- long currentTimeMs = System.currentTimeMillis();
- ScheduledRecording.Builder builder = ScheduledRecording.buildFrom(schedule)
- .setEndTimeMs(program.getEndTimeUtcMillis())
- .setSeasonNumber(program.getSeasonNumber())
- .setEpisodeNumber(program.getEpisodeNumber())
- .setEpisodeTitle(program.getEpisodeTitle())
- .setProgramDescription(program.getDescription())
- .setProgramLongDescription(program.getLongDescription())
- .setProgramPosterArtUri(program.getPosterArtUri())
- .setProgramThumbnailUri(program.getThumbnailUri());
- boolean needUpdate = false;
- // Check the series recording.
- SeriesRecording seriesRecordingForOldSchedule =
- mDataManager.getSeriesRecording(schedule.getSeriesRecordingId());
- if (program.getSeriesId() != null) {
- // New program belongs to a series.
- SeriesRecording seriesRecording =
- mDataManager.getSeriesRecording(program.getSeriesId());
- if (seriesRecording == null) {
- // The new program is episodic while the previous one isn't.
- SeriesRecording newSeriesRecording = TvApplication.getSingletons(mContext)
- .getDvrManager().addSeriesRecording(program,
- Collections.singletonList(program),
- SeriesRecording.STATE_SERIES_STOPPED);
- builder.setSeriesRecordingId(newSeriesRecording.getId());
- needUpdate = true;
- } else if (seriesRecording.getId() != schedule.getSeriesRecordingId()) {
- // The new program belongs to the other series.
- builder.setSeriesRecordingId(seriesRecording.getId());
- needUpdate = true;
- seriesRecordingsToUpdate.add(seriesRecording);
- if (seriesRecordingForOldSchedule != null) {
- seriesRecordingsToUpdate.add(seriesRecordingForOldSchedule);
- }
- } else if (!Objects.equals(schedule.getSeasonNumber(),
- program.getSeasonNumber())
- || !Objects.equals(schedule.getEpisodeNumber(),
- program.getEpisodeNumber())) {
- // The episode number has been changed.
- if (seriesRecordingForOldSchedule != null) {
- seriesRecordingsToUpdate.add(seriesRecordingForOldSchedule);
- }
- }
- } else if (seriesRecordingForOldSchedule != null) {
- // Old program belongs to a series but the new one doesn't.
- seriesRecordingsToUpdate.add(seriesRecordingForOldSchedule);
- }
- // Change start time only when the recording start time has not passed.
- boolean needToChangeStartTime = schedule.getStartTimeMs() > currentTimeMs
- && program.getStartTimeUtcMillis() != schedule.getStartTimeMs();
- if (needToChangeStartTime) {
- builder.setStartTimeMs(program.getStartTimeUtcMillis());
- needUpdate = true;
- }
- if (needUpdate || schedule.getEndTimeMs() != program.getEndTimeUtcMillis()
- || !Objects.equals(schedule.getSeasonNumber(), program.getSeasonNumber())
- || !Objects.equals(schedule.getEpisodeNumber(), program.getEpisodeNumber())
- || !Objects.equals(schedule.getEpisodeTitle(), program.getEpisodeTitle())
- || !Objects.equals(schedule.getProgramDescription(),
- program.getDescription())
- || !Objects.equals(schedule.getProgramLongDescription(),
- program.getLongDescription())
- || !Objects.equals(schedule.getProgramPosterArtUri(),
- program.getPosterArtUri())
- || !Objects.equals(schedule.getProgramThumbnailUri(),
- program.getThumbnailUri())) {
- mDataManager.updateScheduledRecording(builder.build());
- }
- if (!seriesRecordingsToUpdate.isEmpty()) {
- // The series recordings will be updated after it's resumed.
- mSeriesRecordingScheduler.updateSchedules(seriesRecordingsToUpdate);
- }
- }
- }
- }
-
- private class QueryProgramTask extends AsyncQueryProgramTask {
- private final long mProgramId;
-
- QueryProgramTask(long programId) {
- super(mContext.getContentResolver(), programId);
- mProgramId = programId;
- }
-
- @Override
- protected void onCancelled(Program program) {
- if (mQueryProgramTask == this) {
- mQueryProgramTask = null;
- }
- startNextUpdateIfNeeded();
- }
-
- @Override
- protected void onPostExecute(Program program) {
- if (mQueryProgramTask == this) {
- mQueryProgramTask = null;
- }
- handleUpdateProgram(program, mProgramId);
- startNextUpdateIfNeeded();
- }
- }
-}
diff --git a/src/com/android/tv/dvr/DvrManager.java b/src/com/android/tv/dvr/DvrManager.java
index 5fa6f90f..d222003d 100644
--- a/src/com/android/tv/dvr/DvrManager.java
+++ b/src/com/android/tv/dvr/DvrManager.java
@@ -46,7 +46,9 @@ import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager.OnRecordedProgramLoadFinishedListener;
import com.android.tv.dvr.DvrDataManager.RecordedProgramListener;
import com.android.tv.dvr.DvrScheduleManager.OnInitializeListener;
-import com.android.tv.dvr.SeriesRecording.SeriesState;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.util.AsyncDbTask;
import com.android.tv.util.Utils;
@@ -142,7 +144,7 @@ public class DvrManager {
}
private void createSeriesRecordingForRecordedProgramIfNeeded(RecordedProgram recordedProgram) {
- if (recordedProgram.getSeriesId() != null) {
+ if (recordedProgram.isEpisodic()) {
SeriesRecording seriesRecording =
mDataManager.getSeriesRecording(recordedProgram.getSeriesId());
if (seriesRecording == null) {
@@ -234,7 +236,7 @@ public class DvrManager {
* Adds a new series recording and schedules for the programs with the initial state.
*/
public SeriesRecording addSeriesRecording(Program selectedProgram,
- List<Program> programsToSchedule, @SeriesState int initialState) {
+ List<Program> programsToSchedule, @SeriesRecording.SeriesState int initialState) {
Log.i(TAG, "Adding series recording for program " + selectedProgram + ", and schedules: "
+ programsToSchedule);
if (!SoftPreconditions.checkState(mDataManager.isInitialized())) {
@@ -308,8 +310,7 @@ public class DvrManager {
ScheduledRecording scheduleWithSameProgram =
mDataManager.getScheduledRecordingForProgramId(program.getId());
if (scheduleWithSameProgram != null) {
- if (scheduleWithSameProgram.getState()
- == ScheduledRecording.STATE_RECORDING_NOT_STARTED) {
+ if (scheduleWithSameProgram.isNotStarted()) {
ScheduledRecording r = ScheduledRecording.buildFrom(scheduleWithSameProgram)
.setSeriesRecordingId(series.getId())
.build();
@@ -337,10 +338,10 @@ public class DvrManager {
*/
public void updateSeriesRecording(SeriesRecording series) {
if (SoftPreconditions.checkState(mDataManager.isDvrScheduleLoadFinished())) {
- SeriesRecordingScheduler scheduler = SeriesRecordingScheduler.getInstance(mAppContext);
- scheduler.pauseUpdate();
SeriesRecording previousSeries = mDataManager.getSeriesRecording(series.getId());
if (previousSeries != null) {
+ // If the channel option of series changed, remove the existing schedules. The new
+ // schedules will be added by SeriesRecordingScheduler or by SeriesSettingsFragment.
if (previousSeries.getChannelOption() != series.getChannelOption()
|| (previousSeries.getChannelOption() == SeriesRecording.OPTION_CHANNEL_ONE
&& previousSeries.getChannelId() != series.getChannelId())) {
@@ -350,6 +351,18 @@ public class DvrManager {
for (ScheduledRecording schedule : schedules) {
if (schedule.isNotStarted()) {
schedulesToRemove.add(schedule);
+ } else if (schedule.isInProgress()
+ && series.getChannelOption() == SeriesRecording.OPTION_CHANNEL_ONE
+ && schedule.getChannelId() != series.getChannelId()) {
+ stopRecording(schedule);
+ }
+ }
+ List<ScheduledRecording> deletedSchedules =
+ new ArrayList<>(mDataManager.getDeletedSchedules());
+ for (ScheduledRecording deletedSchedule : deletedSchedules) {
+ if (deletedSchedule.getSeriesRecordingId() == series.getId()
+ && deletedSchedule.getEndTimeMs() > System.currentTimeMillis()) {
+ schedulesToRemove.add(deletedSchedule);
}
}
mDataManager.removeScheduledRecording(true,
@@ -363,7 +376,7 @@ public class DvrManager {
List<ScheduledRecording> schedulesToUpdate = new ArrayList<>();
for (ScheduledRecording schedule
: mDataManager.getScheduledRecordings(series.getId())) {
- if (schedule.isNotStarted()) {
+ if (schedule.isNotStarted() || schedule.isInProgress()) {
schedulesToUpdate.add(ScheduledRecording.buildFrom(schedule)
.setPriority(priority).build());
}
@@ -373,7 +386,6 @@ public class DvrManager {
ScheduledRecording.toArray(schedulesToUpdate));
}
}
- scheduler.resumeUpdate();
}
}
@@ -400,33 +412,6 @@ public class DvrManager {
}
/**
- * Returns true, if the series recording can be removed. If a series recording is NORMAL state
- * or has recordings or schedules, it cannot be removed.
- */
- public boolean canRemoveSeriesRecording(long seriesRecordingId) {
- SeriesRecording seriesRecording = mDataManager.getSeriesRecording(seriesRecordingId);
- if (seriesRecording == null) {
- return false;
- }
- if (!seriesRecording.isStopped()) {
- return false;
- }
- for (ScheduledRecording r : mDataManager.getAvailableScheduledRecordings()) {
- if (r.getSeriesRecordingId() == seriesRecordingId) {
- return false;
- }
- }
- String seriesId = seriesRecording.getSeriesId();
- SoftPreconditions.checkNotNull(seriesId);
- for (RecordedProgram r : mDataManager.getRecordedPrograms()) {
- if (seriesId.equals(r.getSeriesId())) {
- return false;
- }
- }
- return true;
- }
-
- /**
* Stops the currently recorded program
*/
public void stopRecording(final ScheduledRecording recording) {
@@ -509,13 +494,16 @@ public class DvrManager {
if (!SoftPreconditions.checkState(mDataManager.isInitialized())) {
return;
}
- new AsyncDbTask<Void, Void, Void>() {
+ new AsyncDbTask<Void, Void, Integer>() {
@Override
- protected Void doInBackground(Void... params) {
+ protected Integer doInBackground(Void... params) {
ContentResolver resolver = mAppContext.getContentResolver();
- int deletedCounts = resolver.delete(recordedProgram.getUri(), null, null);
+ return resolver.delete(recordedProgram.getUri(), null, null);
+ }
+
+ @Override
+ protected void onPostExecute(Integer deletedCounts) {
if (deletedCounts > 0) {
- // TODO: executeOnExecutor should be called on the main thread.
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
@@ -524,7 +512,6 @@ public class DvrManager {
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
- return null;
}
}.executeOnDbThread();
}
@@ -539,13 +526,22 @@ public class DvrManager {
dbOperations.add(ContentProviderOperation.newDelete(r.getUri()).build());
}
}
- new AsyncDbTask<Void, Void, Void>() {
+ new AsyncDbTask<Void, Void, Boolean>() {
@Override
- protected Void doInBackground(Void... params) {
+ protected Boolean doInBackground(Void... params) {
ContentResolver resolver = mAppContext.getContentResolver();
try {
resolver.applyBatch(TvContract.AUTHORITY, dbOperations);
- // TODO: executeOnExecutor should be called on the main thread.
+ } catch (RemoteException | OperationApplicationException e) {
+ Log.w(TAG, "Remove recorded programs from DB failed.", e);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean success) {
+ if (success) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
@@ -555,10 +551,7 @@ public class DvrManager {
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- } catch (RemoteException | OperationApplicationException e) {
- Log.w(TAG, "Remove reocrded programs from DB failed.", e);
}
- return null;
}
}.executeOnDbThread();
}
@@ -657,6 +650,9 @@ public class DvrManager {
if (!mDataManager.isDvrScheduleLoadFinished() || channel == null) {
return false;
}
+ if (channel.isRecordingProhibited()) {
+ return false;
+ }
TvInputInfo info = Utils.getTvInputInfoForChannelId(mAppContext, channel.getId());
if (info == null) {
Log.w(TAG, "Could not find TvInputInfo for " + channel);
@@ -680,7 +676,12 @@ public class DvrManager {
if (!mDataManager.isInitialized()) {
return false;
}
- TvInputInfo info = Utils.getTvInputInfoForProgram(mAppContext, program);
+ Channel channel = TvApplication.getSingletons(mAppContext).getChannelDataManager()
+ .getChannel(program.getChannelId());
+ if (channel == null || channel.isRecordingProhibited()) {
+ return false;
+ }
+ TvInputInfo info = Utils.getTvInputInfoForChannelId(mAppContext, channel.getId());
if (info == null) {
Log.w(TAG, "Could not find TvInputInfo for " + program);
return false;
@@ -733,6 +734,17 @@ public class DvrManager {
return mDataManager.getSeriesRecording(program.getSeriesId());
}
+ /**
+ * Returns if there are valid items. Valid item contains {@link RecordedProgram},
+ * available {@link ScheduledRecording} and {@link SeriesRecording}.
+ */
+ public boolean hasValidItems() {
+ return !(mDataManager.getRecordedPrograms().isEmpty()
+ && mDataManager.getStartedRecordings().isEmpty()
+ && mDataManager.getNonStartedScheduledRecordings().isEmpty()
+ && mDataManager.getSeriesRecordings().isEmpty());
+ }
+
@WorkerThread
@VisibleForTesting
// Should be public to use mock DvrManager object.
@@ -840,9 +852,10 @@ public class DvrManager {
}
/**
- * Listener internally used inside dvr package.
+ * Listener to stop recording request. Should only be internally used inside dvr and its
+ * sub-package.
*/
- interface Listener {
+ public interface Listener {
void onStopRecordingRequested(ScheduledRecording scheduledRecording);
}
}
diff --git a/src/com/android/tv/dvr/DvrPlaybackActivity.java b/src/com/android/tv/dvr/DvrPlaybackActivity.java
deleted file mode 100644
index 5deda44a..00000000
--- a/src/com/android/tv/dvr/DvrPlaybackActivity.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.dvr.ui.DvrPlaybackOverlayFragment;
-
-/**
- * Activity to play a {@link RecordedProgram}.
- */
-public class DvrPlaybackActivity extends Activity {
- private static final String TAG = "DvrPlaybackActivity";
- private static final boolean DEBUG = false;
-
- private DvrPlaybackOverlayFragment mOverlayFragment;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- TvApplication.setCurrentRunningProcess(this, true);
- if (DEBUG) Log.d(TAG, "onCreate");
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_dvr_playback);
- mOverlayFragment = (DvrPlaybackOverlayFragment) getFragmentManager()
- .findFragmentById(R.id.dvr_playback_controls_fragment);
- }
-
- @Override
- public void onVisibleBehindCanceled() {
- if (DEBUG) Log.d(TAG, "onVisibleBehindCanceled");
- super.onVisibleBehindCanceled();
- finish();
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- mOverlayFragment.onNewIntent(intent);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- float density = getResources().getDisplayMetrics().density;
- mOverlayFragment.onWindowSizeChanged((int) (newConfig.screenWidthDp * density),
- (int) (newConfig.screenHeightDp * density));
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/DvrPlaybackMediaSessionHelper.java b/src/com/android/tv/dvr/DvrPlaybackMediaSessionHelper.java
deleted file mode 100644
index 9759a856..00000000
--- a/src/com/android/tv/dvr/DvrPlaybackMediaSessionHelper.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.media.MediaMetadata;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
-import android.media.tv.TvContract;
-import android.os.AsyncTask;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dvr.ui.DvrPlaybackOverlayFragment;
-import com.android.tv.util.ImageLoader;
-import com.android.tv.util.TimeShiftUtils;
-import com.android.tv.util.Utils;
-
-public class DvrPlaybackMediaSessionHelper {
- private static final String TAG = "DvrPlaybackMediaSessionHelper";
- private static final boolean DEBUG = false;
-
- private int mNowPlayingCardWidth;
- private int mNowPlayingCardHeight;
- private int mSpeedLevel;
- private long mProgramDurationMs;
-
- private Activity mActivity;
- private DvrPlayer mDvrPlayer;
- private MediaSession mMediaSession;
- private final DvrWatchedPositionManager mDvrWatchedPositionManager;
- private final ChannelDataManager mChannelDataManager;
-
- public DvrPlaybackMediaSessionHelper(Activity activity, String mediaSessionTag,
- DvrPlayer dvrPlayer, DvrPlaybackOverlayFragment overlayFragment) {
- mActivity = activity;
- mDvrPlayer = dvrPlayer;
- mDvrWatchedPositionManager =
- TvApplication.getSingletons(activity).getDvrWatchedPositionManager();
- mChannelDataManager = TvApplication.getSingletons(activity).getChannelDataManager();
- mDvrPlayer.setCallback(new DvrPlayer.DvrPlayerCallback() {
- @Override
- public void onPlaybackStateChanged(int playbackState, int playbackSpeed) {
- updateMediaSessionPlaybackState();
- }
-
- @Override
- public void onPlaybackPositionChanged(long positionMs) {
- updateMediaSessionPlaybackState();
- if (mDvrPlayer.isPlaybackPrepared()) {
- mDvrWatchedPositionManager
- .setWatchedPosition(mDvrPlayer.getProgram().getId(), positionMs);
- }
- }
-
- @Override
- public void onPlaybackEnded() {
- // TODO: Deal with watched over recordings in DVR library
- RecordedProgram nextEpisode =
- overlayFragment.getNextEpisode(mDvrPlayer.getProgram());
- if (nextEpisode == null) {
- mDvrPlayer.reset();
- mActivity.finish();
- } else {
- Intent intent = new Intent(activity, DvrPlaybackActivity.class);
- intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, nextEpisode.getId());
- mActivity.startActivity(intent);
- }
- }
- });
- initializeMediaSession(mediaSessionTag);
- }
-
- /**
- * Stops DVR player and release media session.
- */
- public void release() {
- if (mDvrPlayer != null) {
- mDvrPlayer.reset();
- }
- if (mMediaSession != null) {
- mMediaSession.release();
- }
- }
-
- /**
- * Updates media session's playback state and speed.
- */
- public void updateMediaSessionPlaybackState() {
- mMediaSession.setPlaybackState(new PlaybackState.Builder()
- .setState(mDvrPlayer.getPlaybackState(), mDvrPlayer.getPlaybackPosition(),
- mSpeedLevel).build());
- }
-
- /**
- * Sets the recorded program for playback.
- *
- * @param program The recorded program to play. {@code null} to reset the DVR player.
- */
- public void setupPlayback(RecordedProgram program, long seekPositionMs) {
- if (program != null) {
- mDvrPlayer.setProgram(program, seekPositionMs);
- setupMediaSession(program);
- } else {
- mDvrPlayer.reset();
- mMediaSession.setActive(false);
- }
- }
-
- /**
- * Returns the recorded program now playing.
- */
- public RecordedProgram getProgram() {
- return mDvrPlayer.getProgram();
- }
-
- /**
- * Checks if the recorded program is the same as now playing one.
- */
- public boolean isCurrentProgram(RecordedProgram program) {
- return program != null && program.equals(getProgram());
- }
-
- /**
- * Returns playback state.
- */
- public int getPlaybackState() {
- return mDvrPlayer.getPlaybackState();
- }
-
- /**
- * Returns the underlying DVR player.
- */
- public DvrPlayer getDvrPlayer() {
- return mDvrPlayer;
- }
-
- private void initializeMediaSession(String mediaSessionTag) {
- mMediaSession = new MediaSession(mActivity, mediaSessionTag);
- mMediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS
- | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
- mNowPlayingCardWidth = mActivity.getResources()
- .getDimensionPixelSize(R.dimen.notif_card_img_max_width);
- mNowPlayingCardHeight = mActivity.getResources()
- .getDimensionPixelSize(R.dimen.notif_card_img_height);
- mMediaSession.setCallback(new MediaSessionCallback());
- mActivity.setMediaController(
- new MediaController(mActivity, mMediaSession.getSessionToken()));
- updateMediaSessionPlaybackState();
- }
-
- private void setupMediaSession(RecordedProgram program) {
- mProgramDurationMs = program.getDurationMillis();
- String cardTitleText = program.getTitle();
- if (TextUtils.isEmpty(cardTitleText)) {
- Channel channel = mChannelDataManager.getChannel(program.getChannelId());
- cardTitleText = (channel != null) ? channel.getDisplayName()
- : mActivity.getString(R.string.no_program_information);
- }
- updateMediaMetadata(program.getId(), cardTitleText, program.getDescription(),
- mProgramDurationMs, null, 0);
- String posterArtUri = program.getPosterArtUri();
- if (posterArtUri == null) {
- posterArtUri = TvContract.buildChannelLogoUri(program.getChannelId()).toString();
- }
- updatePosterArt(program, cardTitleText, program.getDescription(),
- mProgramDurationMs, null, posterArtUri);
- mMediaSession.setActive(true);
- }
-
- private void updatePosterArt(RecordedProgram program, String cardTitleText,
- String cardSubtitleText, long duration,
- @Nullable Bitmap posterArt, @Nullable String posterArtUri) {
- if (posterArt != null) {
- updateMediaMetadata(program.getId(), cardTitleText,
- cardSubtitleText, duration, posterArt, 0);
- } else if (posterArtUri != null) {
- ImageLoader.loadBitmap(mActivity, posterArtUri, mNowPlayingCardWidth,
- mNowPlayingCardHeight, new ProgramPosterArtCallback(
- mActivity, program, cardTitleText, cardSubtitleText, duration));
- } else {
- updateMediaMetadata(program.getId(), cardTitleText,
- cardSubtitleText, duration, null, R.drawable.default_now_card);
- }
- }
-
- private class ProgramPosterArtCallback extends
- ImageLoader.ImageLoaderCallback<Activity> {
- private RecordedProgram mRecordedProgram;
- private String mCardTitleText;
- private String mCardSubtitleText;
- private long mDuration;
-
- public ProgramPosterArtCallback(Activity activity, RecordedProgram program,
- String cardTitleText, String cardSubtitleText, long duration) {
- super(activity);
- mRecordedProgram = program;
- mCardTitleText = cardTitleText;
- mCardSubtitleText = cardSubtitleText;
- mDuration = duration;
- }
-
- @Override
- public void onBitmapLoaded(Activity activity, @Nullable Bitmap posterArt) {
- if (isCurrentProgram(mRecordedProgram)) {
- updatePosterArt(mRecordedProgram, mCardTitleText,
- mCardSubtitleText, mDuration, posterArt, null);
- }
- }
- }
-
- private void updateMediaMetadata(final long programId, final String title,
- final String subtitle, final long duration,
- final Bitmap posterArt, final int imageResId) {
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... arg0) {
- MediaMetadata.Builder builder = new MediaMetadata.Builder();
- builder.putLong(MediaMetadata.METADATA_KEY_MEDIA_ID, programId)
- .putString(MediaMetadata.METADATA_KEY_TITLE, title)
- .putLong(MediaMetadata.METADATA_KEY_DURATION, duration);
- if (subtitle != null) {
- builder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE, subtitle);
- }
- Bitmap programPosterArt = posterArt;
- if (programPosterArt == null && imageResId != 0) {
- programPosterArt =
- BitmapFactory.decodeResource(mActivity.getResources(), imageResId);
- }
- if (programPosterArt != null) {
- builder.putBitmap(MediaMetadata.METADATA_KEY_ART, programPosterArt);
- }
- mMediaSession.setMetadata(builder.build());
- return null;
- }
- }.execute();
- }
-
- // An event was triggered by MediaController.TransportControls and must be handled here.
- // Here we update the media itself to act on the event that was triggered.
- private class MediaSessionCallback extends MediaSession.Callback {
- @Override
- public void onPrepare() {
- if (!mDvrPlayer.isPlaybackPrepared()) {
- mDvrPlayer.prepare(true);
- }
- }
-
- @Override
- public void onPlay() {
- if (mDvrPlayer.isPlaybackPrepared()) {
- mDvrPlayer.play();
- }
- }
-
- @Override
- public void onPause() {
- if (mDvrPlayer.isPlaybackPrepared()) {
- mDvrPlayer.pause();
- }
- }
-
- @Override
- public void onFastForward() {
- if (!mDvrPlayer.isPlaybackPrepared()) {
- return;
- }
- if (mDvrPlayer.getPlaybackState() == PlaybackState.STATE_FAST_FORWARDING) {
- if (mSpeedLevel < TimeShiftUtils.MAX_SPEED_LEVEL) {
- mSpeedLevel++;
- } else {
- return;
- }
- } else {
- mSpeedLevel = 0;
- }
- mDvrPlayer.fastForward(
- TimeShiftUtils.getPlaybackSpeed(mSpeedLevel, mProgramDurationMs));
- }
-
- @Override
- public void onRewind() {
- if (!mDvrPlayer.isPlaybackPrepared()) {
- return;
- }
- if (mDvrPlayer.getPlaybackState() == PlaybackState.STATE_REWINDING) {
- if (mSpeedLevel < TimeShiftUtils.MAX_SPEED_LEVEL) {
- mSpeedLevel++;
- } else {
- return;
- }
- } else {
- mSpeedLevel = 0;
- }
- mDvrPlayer.rewind(TimeShiftUtils.getPlaybackSpeed(mSpeedLevel, mProgramDurationMs));
- }
-
- @Override
- public void onSeekTo(long positionMs) {
- if (mDvrPlayer.isPlaybackPrepared()) {
- mDvrPlayer.seekTo(positionMs);
- }
- }
- }
-}
diff --git a/src/com/android/tv/dvr/DvrPlayer.java b/src/com/android/tv/dvr/DvrPlayer.java
deleted file mode 100644
index 5656655c..00000000
--- a/src/com/android/tv/dvr/DvrPlayer.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.media.PlaybackParams;
-import android.media.tv.TvContentRating;
-import android.media.tv.TvInputManager;
-import android.media.tv.TvTrackInfo;
-import android.media.tv.TvView;
-import android.media.session.PlaybackState;
-import android.util.Log;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-public class DvrPlayer {
- private static final String TAG = "DvrPlayer";
- private static final boolean DEBUG = false;
-
- /**
- * The max rewinding speed supported by DVR player.
- */
- public static final int MAX_REWIND_SPEED = 256;
- /**
- * The max fast-forwarding speed supported by DVR player.
- */
- public static final int MAX_FAST_FORWARD_SPEED = 256;
-
- private static final long SEEK_POSITION_MARGIN_MS = TimeUnit.SECONDS.toMillis(2);
- private static final long REWIND_POSITION_MARGIN_MS = 32; // Workaround value. b/29994826
-
- private RecordedProgram mProgram;
- private long mInitialSeekPositionMs;
- private final TvView mTvView;
- private DvrPlayerCallback mCallback;
- private AspectRatioChangedListener mAspectRatioChangedListener;
- private ContentBlockedListener mContentBlockedListener;
- private float mAspectRatio = Float.NaN;
- private int mPlaybackState = PlaybackState.STATE_NONE;
- private long mTimeShiftCurrentPositionMs;
- private boolean mPauseOnPrepared;
- private final PlaybackParams mPlaybackParams = new PlaybackParams();
- private final DvrPlayerCallback mEmptyCallback = new DvrPlayerCallback();
- private long mStartPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
- private boolean mTimeShiftPlayAvailable;
-
- public static class DvrPlayerCallback {
- /**
- * Called when the playback position is changed. The normal updating frequency is
- * around 1 sec., which is restricted to the implementation of
- * {@link android.media.tv.TvInputService}.
- */
- public void onPlaybackPositionChanged(long positionMs) { }
- /**
- * Called when the playback state or the playback speed is changed.
- */
- public void onPlaybackStateChanged(int playbackState, int playbackSpeed) { }
- /**
- * Called when the playback toward the end.
- */
- public void onPlaybackEnded() { }
- }
-
- public interface AspectRatioChangedListener {
- /**
- * Called when the Video's aspect ratio is changed.
- */
- void onAspectRatioChanged(float videoAspectRatio);
- }
-
- public interface ContentBlockedListener {
- /**
- * Called when the Video's aspect ratio is changed.
- */
- void onContentBlocked(TvContentRating rating);
- }
-
- public DvrPlayer(TvView tvView) {
- mTvView = tvView;
- mPlaybackParams.setSpeed(1.0f);
- setTvViewCallbacks();
- setCallback(null);
- }
-
- /**
- * Prepares playback.
- *
- * @param doPlay indicates DVR player do or do not start playback after media is prepared.
- */
- public void prepare(boolean doPlay) throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "prepare()");
- if (mProgram == null) {
- throw new IllegalStateException("Recorded program not set");
- } else if (mPlaybackState != PlaybackState.STATE_NONE) {
- throw new IllegalStateException("Playback is already prepared");
- }
- mTvView.timeShiftPlay(mProgram.getInputId(), mProgram.getUri());
- mPlaybackState = PlaybackState.STATE_CONNECTING;
- mPauseOnPrepared = !doPlay;
- mCallback.onPlaybackStateChanged(mPlaybackState, 1);
- }
-
- /**
- * Resumes playback.
- */
- public void play() throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "play()");
- if (!isPlaybackPrepared()) {
- throw new IllegalStateException("Recorded program not set or video not ready yet");
- }
- switch (mPlaybackState) {
- case PlaybackState.STATE_FAST_FORWARDING:
- case PlaybackState.STATE_REWINDING:
- setPlaybackSpeed(1);
- break;
- default:
- mTvView.timeShiftResume();
- }
- mPlaybackState = PlaybackState.STATE_PLAYING;
- mCallback.onPlaybackStateChanged(mPlaybackState, 1);
- }
-
- /**
- * Pauses playback.
- */
- public void pause() throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "pause()");
- if (!isPlaybackPrepared()) {
- throw new IllegalStateException("Recorded program not set or playback not started yet");
- }
- switch (mPlaybackState) {
- case PlaybackState.STATE_FAST_FORWARDING:
- case PlaybackState.STATE_REWINDING:
- setPlaybackSpeed(1);
- // falls through
- case PlaybackState.STATE_PLAYING:
- mTvView.timeShiftPause();
- mPlaybackState = PlaybackState.STATE_PAUSED;
- break;
- default:
- break;
- }
- mCallback.onPlaybackStateChanged(mPlaybackState, 1);
- }
-
- /**
- * Fast-forwards playback with the given speed. If the given speed is larger than
- * {@value #MAX_FAST_FORWARD_SPEED}, uses {@value #MAX_FAST_FORWARD_SPEED}.
- */
- public void fastForward(int speed) throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "fastForward()");
- if (!isPlaybackPrepared()) {
- throw new IllegalStateException("Recorded program not set or playback not started yet");
- }
- if (speed <= 0) {
- throw new IllegalArgumentException("Speed cannot be negative or 0");
- }
- if (mTimeShiftCurrentPositionMs >= mProgram.getDurationMillis() - SEEK_POSITION_MARGIN_MS) {
- return;
- }
- speed = Math.min(speed, MAX_FAST_FORWARD_SPEED);
- if (DEBUG) Log.d(TAG, "Let's play with speed: " + speed);
- setPlaybackSpeed(speed);
- mPlaybackState = PlaybackState.STATE_FAST_FORWARDING;
- mCallback.onPlaybackStateChanged(mPlaybackState, speed);
- }
-
- /**
- * Rewinds playback with the given speed. If the given speed is larger than
- * {@value #MAX_REWIND_SPEED}, uses {@value #MAX_REWIND_SPEED}.
- */
- public void rewind(int speed) throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "rewind()");
- if (!isPlaybackPrepared()) {
- throw new IllegalStateException("Recorded program not set or playback not started yet");
- }
- if (speed <= 0) {
- throw new IllegalArgumentException("Speed cannot be negative or 0");
- }
- if (mTimeShiftCurrentPositionMs <= REWIND_POSITION_MARGIN_MS) {
- return;
- }
- speed = Math.min(speed, MAX_REWIND_SPEED);
- if (DEBUG) Log.d(TAG, "Let's play with speed: " + speed);
- setPlaybackSpeed(-speed);
- mPlaybackState = PlaybackState.STATE_REWINDING;
- mCallback.onPlaybackStateChanged(mPlaybackState, speed);
- }
-
- /**
- * Seeks playback to the specified position.
- */
- public void seekTo(long positionMs) throws IllegalStateException {
- if (DEBUG) Log.d(TAG, "seekTo()");
- if (!isPlaybackPrepared()) {
- throw new IllegalStateException("Recorded program not set or playback not started yet");
- }
- if (mProgram == null || mPlaybackState == PlaybackState.STATE_NONE) {
- return;
- }
- positionMs = getRealSeekPosition(positionMs, SEEK_POSITION_MARGIN_MS);
- if (DEBUG) Log.d(TAG, "Now: " + getPlaybackPosition() + ", shift to: " + positionMs);
- mTvView.timeShiftSeekTo(positionMs + mStartPositionMs);
- if (mPlaybackState == PlaybackState.STATE_FAST_FORWARDING ||
- mPlaybackState == PlaybackState.STATE_REWINDING) {
- mPlaybackState = PlaybackState.STATE_PLAYING;
- mTvView.timeShiftResume();
- mCallback.onPlaybackStateChanged(mPlaybackState, 1);
- }
- }
-
- /**
- * Resets playback.
- */
- public void reset() {
- if (DEBUG) Log.d(TAG, "reset()");
- mCallback.onPlaybackStateChanged(PlaybackState.STATE_NONE, 1);
- mPlaybackState = PlaybackState.STATE_NONE;
- mTvView.reset();
- mTimeShiftPlayAvailable = false;
- mStartPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
- mTimeShiftCurrentPositionMs = 0;
- mPlaybackParams.setSpeed(1.0f);
- mProgram = null;
- }
-
- /**
- * Sets callbacks for playback.
- */
- public void setCallback(DvrPlayerCallback callback) {
- if (callback != null) {
- mCallback = callback;
- } else {
- mCallback = mEmptyCallback;
- }
- }
-
- /**
- * Sets listener to aspect ratio changing.
- */
- public void setAspectRatioChangedListener(AspectRatioChangedListener listener) {
- mAspectRatioChangedListener = listener;
- }
-
- /**
- * Sets listener to content blocking.
- */
- public void setContentBlockedListener(ContentBlockedListener listener) {
- mContentBlockedListener = listener;
- }
-
- /**
- * Sets recorded programs for playback. If the player is playing another program, stops it.
- */
- public void setProgram(RecordedProgram program, long initialSeekPositionMs) {
- if (mProgram != null && mProgram.equals(program)) {
- return;
- }
- if (mPlaybackState != PlaybackState.STATE_NONE) {
- reset();
- }
- mInitialSeekPositionMs = initialSeekPositionMs;
- mProgram = program;
- }
-
- /**
- * Returns the recorded program now playing.
- */
- public RecordedProgram getProgram() {
- return mProgram;
- }
-
- /**
- * Returns the currrent playback posistion in msecs.
- */
- public long getPlaybackPosition() {
- return mTimeShiftCurrentPositionMs;
- }
-
- /**
- * Returns the playback speed currently used.
- */
- public int getPlaybackSpeed() {
- return (int) mPlaybackParams.getSpeed();
- }
-
- /**
- * Returns the playback state defined in {@link android.media.session.PlaybackState}.
- */
- public int getPlaybackState() {
- return mPlaybackState;
- }
-
- /**
- * Returns if playback of the recorded program is started.
- */
- public boolean isPlaybackPrepared() {
- return mPlaybackState != PlaybackState.STATE_NONE
- && mPlaybackState != PlaybackState.STATE_CONNECTING;
- }
-
- private void setPlaybackSpeed(int speed) {
- mPlaybackParams.setSpeed(speed);
- mTvView.timeShiftSetPlaybackParams(mPlaybackParams);
- }
-
- private long getRealSeekPosition(long seekPositionMs, long endMarginMs) {
- return Math.max(0, Math.min(seekPositionMs, mProgram.getDurationMillis() - endMarginMs));
- }
-
- private void setTvViewCallbacks() {
- mTvView.setTimeShiftPositionCallback(new TvView.TimeShiftPositionCallback() {
- @Override
- public void onTimeShiftStartPositionChanged(String inputId, long timeMs) {
- if (DEBUG) Log.d(TAG, "onTimeShiftStartPositionChanged:" + timeMs);
- mStartPositionMs = timeMs;
- if (mTimeShiftPlayAvailable) {
- resumeToWatchedPositionIfNeeded();
- }
- }
-
- @Override
- public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
- if (DEBUG) Log.d(TAG, "onTimeShiftCurrentPositionChanged: " + timeMs);
- if (!mTimeShiftPlayAvailable) {
- // Workaround of b/31436263
- return;
- }
- // Workaround of b/32211561, TIF won't report start position when TIS report
- // its start position as 0. In that case, we have to do the prework of playback
- // on the first time we get current position, and the start position should be 0
- // at that time.
- if (mStartPositionMs == TvInputManager.TIME_SHIFT_INVALID_TIME) {
- mStartPositionMs = 0;
- resumeToWatchedPositionIfNeeded();
- }
- timeMs -= mStartPositionMs;
- if (mPlaybackState == PlaybackState.STATE_REWINDING
- && timeMs <= REWIND_POSITION_MARGIN_MS) {
- play();
- } else {
- mTimeShiftCurrentPositionMs = getRealSeekPosition(timeMs, 0);
- mCallback.onPlaybackPositionChanged(mTimeShiftCurrentPositionMs);
- if (timeMs >= mProgram.getDurationMillis()) {
- pause();
- mCallback.onPlaybackEnded();
- }
- }
- }
- });
- mTvView.setCallback(new TvView.TvInputCallback() {
- @Override
- public void onTimeShiftStatusChanged(String inputId, int status) {
- if (DEBUG) Log.d(TAG, "onTimeShiftStatusChanged:" + status);
- if (status == TvInputManager.TIME_SHIFT_STATUS_AVAILABLE
- && mPlaybackState == PlaybackState.STATE_CONNECTING) {
- mTimeShiftPlayAvailable = true;
- }
- }
-
- @Override
- public void onTrackSelected(String inputId, int type, String trackId) {
- if (trackId == null || type != TvTrackInfo.TYPE_VIDEO
- || mAspectRatioChangedListener == null) {
- return;
- }
- List<TvTrackInfo> trackInfos = mTvView.getTracks(TvTrackInfo.TYPE_VIDEO);
- if (trackInfos != null) {
- for (TvTrackInfo trackInfo : trackInfos) {
- if (trackInfo.getId().equals(trackId)) {
- float videoAspectRatio = trackInfo.getVideoPixelAspectRatio()
- * trackInfo.getVideoWidth() / trackInfo.getVideoHeight();
- if (DEBUG) Log.d(TAG, "Aspect Ratio: " + videoAspectRatio);
- if (!Float.isNaN(videoAspectRatio)
- && mAspectRatio != videoAspectRatio) {
- mAspectRatioChangedListener
- .onAspectRatioChanged(videoAspectRatio);
- mAspectRatio = videoAspectRatio;
- return;
- }
- }
- }
- }
- }
-
- @Override
- public void onContentBlocked(String inputId, TvContentRating rating) {
- if (mContentBlockedListener != null) {
- mContentBlockedListener.onContentBlocked(rating);
- }
- }
- });
- }
-
- private void resumeToWatchedPositionIfNeeded() {
- if (mInitialSeekPositionMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
- mTvView.timeShiftSeekTo(getRealSeekPosition(mInitialSeekPositionMs,
- SEEK_POSITION_MARGIN_MS) + mStartPositionMs);
- mInitialSeekPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
- }
- if (mPauseOnPrepared) {
- mTvView.timeShiftPause();
- mPlaybackState = PlaybackState.STATE_PAUSED;
- mPauseOnPrepared = false;
- } else {
- mTvView.timeShiftResume();
- mPlaybackState = PlaybackState.STATE_PLAYING;
- }
- mCallback.onPlaybackStateChanged(mPlaybackState, 1);
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/DvrRecordingService.java b/src/com/android/tv/dvr/DvrRecordingService.java
deleted file mode 100644
index 8c40aaa8..00000000
--- a/src/com/android/tv/dvr/DvrRecordingService.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import android.app.AlarmManager;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.util.Log;
-
-import com.android.tv.ApplicationSingletons;
-import com.android.tv.TvApplication;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.util.Clock;
-import com.android.tv.util.RecurringRunner;
-
-/**
- * DVR Scheduler service.
- *
- * <p> This service is responsible for:
- * <ul>
- * <li>Send record commands to TV inputs</li>
- * <li>Wake up at proper timing for recording</li>
- * <li>Deconflict schedule, handling overlapping times etc.</li>
- * <li>
- *
- * </ul>
- *
- * <p>The service does not stop it self.
- */
-public class DvrRecordingService extends Service {
- private static final String TAG = "DvrRecordingService";
- private static final boolean DEBUG = false;
- public static final String HANDLER_THREAD_NAME = "DvrRecordingService-handler";
-
- public static void startService(Context context) {
- Intent dvrSchedulerIntent = new Intent(context, DvrRecordingService.class);
- context.startService(dvrSchedulerIntent);
- }
-
- private final Clock mClock = Clock.SYSTEM;
- private RecurringRunner mReaperRunner;
-
- private Scheduler mScheduler;
- private HandlerThread mHandlerThread;
-
- @Override
- public void onCreate() {
- TvApplication.setCurrentRunningProcess(this, true);
- if (DEBUG) Log.d(TAG, "onCreate");
- super.onCreate();
- SoftPreconditions.checkFeatureEnabled(this, CommonFeatures.DVR, TAG);
- ApplicationSingletons singletons = TvApplication.getSingletons(this);
- WritableDvrDataManager dataManager = (WritableDvrDataManager) singletons.getDvrDataManager();
-
- AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
- // mScheduler may have been set for testing.
- if (mScheduler == null) {
- mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME);
- mHandlerThread.start();
- mScheduler = new Scheduler(mHandlerThread.getLooper(), singletons.getDvrManager(),
- singletons.getInputSessionManager(), dataManager,
- singletons.getChannelDataManager(), singletons.getTvInputManagerHelper(), this,
- mClock, alarmManager);
- mScheduler.start();
- }
- mReaperRunner = new RecurringRunner(this, java.util.concurrent.TimeUnit.DAYS.toMillis(1),
- new ScheduledProgramReaper(dataManager, mClock), null);
- mReaperRunner.start();
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if (DEBUG) Log.d(TAG, "onStartCommand (" + intent + "," + flags + "," + startId + ")");
- mScheduler.update();
- return START_STICKY;
- }
-
- @Override
- public void onDestroy() {
- if (DEBUG) Log.d(TAG, "onDestroy");
- mReaperRunner.stop();
- mScheduler.stop();
- mScheduler = null;
- if (mHandlerThread != null) {
- mHandlerThread.quitSafely();
- mHandlerThread = null;
- }
- super.onDestroy();
- }
-
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- @VisibleForTesting
- void setScheduler(Scheduler scheduler) {
- Log.i(TAG, "Setting scheduler for tests to " + scheduler);
- mScheduler = scheduler;
- }
-}
diff --git a/src/com/android/tv/dvr/DvrScheduleManager.java b/src/com/android/tv/dvr/DvrScheduleManager.java
index a5851a75..b72117aa 100644
--- a/src/com/android/tv/dvr/DvrScheduleManager.java
+++ b/src/com/android/tv/dvr/DvrScheduleManager.java
@@ -24,7 +24,6 @@ import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
-import android.util.LongSparseArray;
import android.util.Range;
import com.android.tv.ApplicationSingletons;
@@ -35,7 +34,10 @@ import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
+import com.android.tv.dvr.recorder.InputTaskScheduler;
import com.android.tv.util.CompositeComparator;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.util.Utils;
import java.util.ArrayList;
@@ -88,9 +90,8 @@ public class DvrScheduleManager {
private final Map<String, List<ScheduledRecording>> mInputScheduleMap = new HashMap<>();
// The inner map is a hash map from scheduled recording to its conflicting status, i.e.,
// the boolean value true denotes the schedule is just partially conflicting, which means
- // although there's conflictit, it might still be recorded partially.
- private final Map<String, Map<ScheduledRecording, Boolean>> mInputConflictInfoMap =
- new HashMap<>();
+ // although there's conflict, it might still be recorded partially.
+ private final Map<String, Map<Long, ConflictInfo>> mInputConflictInfoMap = new HashMap<>();
private boolean mInitialized;
@@ -171,10 +172,9 @@ public class DvrScheduleManager {
mInputScheduleMap.remove(inputId);
}
}
- Map<ScheduledRecording, Boolean> conflictInfo =
- mInputConflictInfoMap.get(inputId);
+ Map<Long, ConflictInfo> conflictInfo = mInputConflictInfoMap.get(inputId);
if (conflictInfo != null) {
- conflictInfo.remove(schedule);
+ conflictInfo.remove(schedule.getId());
if (conflictInfo.isEmpty()) {
mInputConflictInfoMap.remove(inputId);
}
@@ -221,21 +221,11 @@ public class DvrScheduleManager {
mInputScheduleMap.remove(inputId);
}
// Update conflict list as well
- Map<ScheduledRecording, Boolean> conflictInfo =
- mInputConflictInfoMap.get(inputId);
+ Map<Long, ConflictInfo> conflictInfo = mInputConflictInfoMap.get(inputId);
if (conflictInfo != null) {
- // Compare ID because ScheduledRecording.equals() doesn't work if the state
- // is changed.
- ScheduledRecording oldSchedule = null;
- for (ScheduledRecording s : conflictInfo.keySet()) {
- if (s.getId() == schedule.getId()) {
- oldSchedule = s;
- break;
- }
- }
- if (oldSchedule != null) {
- conflictInfo.put(schedule, conflictInfo.get(oldSchedule));
- conflictInfo.remove(oldSchedule);
+ ConflictInfo oldConflictInfo = conflictInfo.get(schedule.getId());
+ if (oldConflictInfo != null) {
+ oldConflictInfo.schedule = schedule;
}
}
}
@@ -317,24 +307,25 @@ public class DvrScheduleManager {
List<ScheduledRecording> addedConflicts = new ArrayList<>();
List<ScheduledRecording> removedConflicts = new ArrayList<>();
for (String inputId : mInputScheduleMap.keySet()) {
- Map<ScheduledRecording, Boolean> oldConflictsInfo = mInputConflictInfoMap.get(inputId);
+ Map<Long, ConflictInfo> oldConflictInfo = mInputConflictInfoMap.get(inputId);
Map<Long, ScheduledRecording> oldConflictMap = new HashMap<>();
- if (oldConflictsInfo != null) {
- for (ScheduledRecording r : oldConflictsInfo.keySet()) {
- oldConflictMap.put(r.getId(), r);
+ if (oldConflictInfo != null) {
+ for (ConflictInfo conflictInfo : oldConflictInfo.values()) {
+ oldConflictMap.put(conflictInfo.schedule.getId(), conflictInfo.schedule);
}
}
- Map<ScheduledRecording, Boolean> conflictInfo = getConflictingSchedulesInfo(inputId);
- if (conflictInfo.isEmpty()) {
+ List<ConflictInfo> conflicts = getConflictingSchedulesInfo(inputId);
+ if (conflicts.isEmpty()) {
mInputConflictInfoMap.remove(inputId);
} else {
- mInputConflictInfoMap.put(inputId, conflictInfo);
- List<ScheduledRecording> conflicts = new ArrayList<>(conflictInfo.keySet());
- for (ScheduledRecording r : conflicts) {
- if (oldConflictMap.remove(r.getId()) == null) {
- addedConflicts.add(r);
+ Map<Long, ConflictInfo> conflictInfos = new HashMap<>();
+ for (ConflictInfo conflictInfo : conflicts) {
+ conflictInfos.put(conflictInfo.schedule.getId(), conflictInfo);
+ if (oldConflictMap.remove(conflictInfo.schedule.getId()) == null) {
+ addedConflicts.add(conflictInfo.schedule);
}
}
+ mInputConflictInfoMap.put(inputId, conflictInfos);
}
removedConflicts.addAll(oldConflictMap.values());
}
@@ -565,8 +556,7 @@ public class DvrScheduleManager {
}
/**
- * Returns list of all conflicting scheduled recordings with schedules belonging to {@code
- * seriesRecording}
+ * Returns list of all conflicting scheduled recordings for the given {@code seriesRecording}
* recording.
* <p>
* Any empty list means there is no conflicts.
@@ -581,9 +571,18 @@ public class DvrScheduleManager {
if (input == null || !input.canRecord() || input.getTunerCount() <= 0) {
return Collections.emptyList();
}
- List<ScheduledRecording> schedulesForSeries = mDataManager.getScheduledRecordings(
+ List<ScheduledRecording> scheduledRecordingForSeries = mDataManager.getScheduledRecordings(
seriesRecording.getId());
- return getConflictingSchedules(input, schedulesForSeries);
+ List<ScheduledRecording> availableScheduledRecordingForSeries = new ArrayList<>();
+ for (ScheduledRecording scheduledRecording : scheduledRecordingForSeries) {
+ if (scheduledRecording.isNotStarted() || scheduledRecording.isInProgress()) {
+ availableScheduledRecordingForSeries.add(scheduledRecording);
+ }
+ }
+ if (availableScheduledRecordingForSeries.isEmpty()) {
+ return Collections.emptyList();
+ }
+ return getConflictingSchedules(input, availableScheduledRecordingForSeries);
}
/**
@@ -617,16 +616,16 @@ public class DvrScheduleManager {
* the given input.
*/
@NonNull
- private Map<ScheduledRecording, Boolean> getConflictingSchedulesInfo(String inputId) {
+ private List<ConflictInfo> getConflictingSchedulesInfo(String inputId) {
SoftPreconditions.checkState(mInitialized, TAG, "Not initialized yet");
TvInputInfo input = Utils.getTvInputInfoForInputId(mContext, inputId);
SoftPreconditions.checkState(input != null, TAG, "Can't find input for : " + inputId);
if (!mInitialized || input == null) {
- return Collections.emptyMap();
+ return Collections.emptyList();
}
List<ScheduledRecording> schedules = mInputScheduleMap.get(input.getId());
if (schedules == null || schedules.isEmpty()) {
- return Collections.emptyMap();
+ return Collections.emptyList();
}
return getConflictingSchedulesInfo(schedules, input.getTunerCount());
}
@@ -645,8 +644,8 @@ public class DvrScheduleManager {
if (!mInitialized || input == null) {
return false;
}
- Map<ScheduledRecording, Boolean> conflicts = mInputConflictInfoMap.get(input.getId());
- return conflicts != null && conflicts.containsKey(schedule);
+ Map<Long, ConflictInfo> conflicts = mInputConflictInfoMap.get(input.getId());
+ return conflicts != null && conflicts.containsKey(schedule.getId());
}
/**
@@ -664,8 +663,12 @@ public class DvrScheduleManager {
if (!mInitialized || input == null) {
return false;
}
- Map<ScheduledRecording, Boolean> conflicts = mInputConflictInfoMap.get(input.getId());
- return conflicts != null && conflicts.getOrDefault(schedule, false);
+ Map<Long, ConflictInfo> conflicts = mInputConflictInfoMap.get(input.getId());
+ if (conflicts != null) {
+ ConflictInfo conflictInfo = conflicts.get(schedule.getId());
+ return conflictInfo != null && conflictInfo.partialConflict;
+ }
+ return false;
}
/**
@@ -813,15 +816,17 @@ public class DvrScheduleManager {
@VisibleForTesting
static List<ScheduledRecording> getConflictingSchedules(
List<ScheduledRecording> schedules, int tunerCount, List<Range<Long>> periods) {
- List<ScheduledRecording> result = new ArrayList<>(
- getConflictingSchedulesInfo(schedules, tunerCount, periods).keySet());
- Collections.sort(result, RESULT_COMPARATOR);
+ List<ScheduledRecording> result = new ArrayList<>();
+ for (ConflictInfo conflictInfo :
+ getConflictingSchedulesInfo(schedules, tunerCount, periods)) {
+ result.add(conflictInfo.schedule);
+ }
return result;
}
@VisibleForTesting
- static Map<ScheduledRecording, Boolean> getConflictingSchedulesInfo(
- List<ScheduledRecording> schedules, int tunerCount) {
+ static List<ConflictInfo> getConflictingSchedulesInfo(List<ScheduledRecording> schedules,
+ int tunerCount) {
return getConflictingSchedulesInfo(schedules, tunerCount, null);
}
@@ -836,13 +841,13 @@ public class DvrScheduleManager {
* to be partially recorded under the given schedules and tuner count {@code true},
* or not {@code false}.
*/
- private static Map<ScheduledRecording, Boolean> getConflictingSchedulesInfo(
+ private static List<ConflictInfo> getConflictingSchedulesInfo(
List<ScheduledRecording> schedules, int tunerCount, List<Range<Long>> periods) {
List<ScheduledRecording> schedulesToCheck = new ArrayList<>(schedules);
// Sort by the same order as that in InputTaskScheduler.
Collections.sort(schedulesToCheck, InputTaskScheduler.getRecordingOrderComparator());
List<ScheduledRecording> recordings = new ArrayList<>();
- Map<ScheduledRecording, Boolean> conflicts = new HashMap<>();
+ Map<ScheduledRecording, ConflictInfo> conflicts = new HashMap<>();
Map<ScheduledRecording, ScheduledRecording> modified2OriginalSchedules = new HashMap<>();
// Simulate InputTaskScheduler.
while (!schedulesToCheck.isEmpty()) {
@@ -853,26 +858,29 @@ public class DvrScheduleManager {
if (modified2OriginalSchedules.containsKey(schedule)) {
// Schedule has been modified, which means it's already conflicted.
// Modify its state to partially conflicted.
- conflicts.put(modified2OriginalSchedules.get(schedule), true);
+ ScheduledRecording originalSchedule = modified2OriginalSchedules.get(schedule);
+ conflicts.put(originalSchedule, new ConflictInfo(originalSchedule, true));
}
} else {
ScheduledRecording candidate = findReplaceableRecording(recordings, schedule);
if (candidate != null) {
if (!modified2OriginalSchedules.containsKey(candidate)) {
- conflicts.put(candidate, true);
+ conflicts.put(candidate, new ConflictInfo(candidate, true));
}
recordings.remove(candidate);
recordings.add(schedule);
if (modified2OriginalSchedules.containsKey(schedule)) {
// Schedule has been modified, which means it's already conflicted.
// Modify its state to partially conflicted.
- conflicts.put(modified2OriginalSchedules.get(schedule), true);
+ ScheduledRecording originalSchedule =
+ modified2OriginalSchedules.get(schedule);
+ conflicts.put(originalSchedule, new ConflictInfo(originalSchedule, true));
}
} else {
if (!modified2OriginalSchedules.containsKey(schedule)) {
// if schedule has been modified, it's already conflicted.
// No need to add it again.
- conflicts.put(schedule, false);
+ conflicts.put(schedule, new ConflictInfo(schedule, false));
}
long earliestEndTime = getEarliestEndTime(recordings);
if (earliestEndTime < schedule.getEndTimeMs()) {
@@ -912,7 +920,14 @@ public class DvrScheduleManager {
}
}
}
- return conflicts;
+ List<ConflictInfo> result = new ArrayList<>(conflicts.values());
+ Collections.sort(result, new Comparator<ConflictInfo>() {
+ @Override
+ public int compare(ConflictInfo lhs, ConflictInfo rhs) {
+ return RESULT_COMPARATOR.compare(lhs.schedule, rhs.schedule);
+ }
+ });
+ return result;
}
private static void removeFinishedRecordings(List<ScheduledRecording> recordings,
@@ -954,6 +969,17 @@ public class DvrScheduleManager {
return earliest;
}
+ @VisibleForTesting
+ static class ConflictInfo {
+ public ScheduledRecording schedule;
+ public boolean partialConflict;
+
+ ConflictInfo(ScheduledRecording schedule, boolean partialConflict) {
+ this.schedule = schedule;
+ this.partialConflict = partialConflict;
+ }
+ }
+
/**
* A listener which is notified the initialization of schedule manager.
*/
@@ -970,6 +996,9 @@ public class DvrScheduleManager {
public interface OnConflictStateChangeListener {
/**
* Called when the conflicting schedules change.
+ * <p>
+ * Note that this can be called before
+ * {@link ScheduledRecordingListener#onScheduledRecordingAdded} is called.
*
* @param conflict {@code true} if the {@code schedules} are the new conflicts, otherwise
* {@code false}.
diff --git a/src/com/android/tv/dvr/DvrStartRecordingReceiver.java b/src/com/android/tv/dvr/DvrStartRecordingReceiver.java
deleted file mode 100644
index 6d2f0d43..00000000
--- a/src/com/android/tv/dvr/DvrStartRecordingReceiver.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import com.android.tv.TvApplication;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-/**
- * Signals the DVR to start recording shows <i>soon</i>.
- */
-public class DvrStartRecordingReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- TvApplication.setCurrentRunningProcess(context, true);
- DvrRecordingService.startService(context);
- }
-}
diff --git a/src/com/android/tv/dvr/DvrStorageStatusManager.java b/src/com/android/tv/dvr/DvrStorageStatusManager.java
index a653b5f4..2d41d732 100644
--- a/src/com/android/tv/dvr/DvrStorageStatusManager.java
+++ b/src/com/android/tv/dvr/DvrStorageStatusManager.java
@@ -25,6 +25,7 @@ import android.content.IntentFilter;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.media.tv.TvContract;
+import android.media.tv.TvInputInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
@@ -36,8 +37,11 @@ import android.support.annotation.IntDef;
import android.support.annotation.WorkerThread;
import android.util.Log;
+import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.tuner.tvinput.TunerTvInputService;
+import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import java.io.File;
@@ -294,7 +298,7 @@ public class DvrStorageStatusManager {
storageMounted, storageMountedDir, storageMountedCapacity);
}
- private class CleanUpDbTask extends AsyncTask<Void, Void, Void> {
+ private class CleanUpDbTask extends AsyncTask<Void, Void, Boolean> {
private final ContentResolver mContentResolver;
private CleanUpDbTask() {
@@ -302,13 +306,15 @@ public class DvrStorageStatusManager {
}
@Override
- protected Void doInBackground(Void... params) {
+ protected Boolean doInBackground(Void... params) {
@DvrStorageStatusManager.StorageStatus int storageStatus = getDvrStorageStatus();
if (storageStatus == DvrStorageStatusManager.STORAGE_STATUS_MISSING) {
return null;
}
- List<ContentProviderOperation> ops = getDeleteOps(storageStatus
- == DvrStorageStatusManager.STORAGE_STATUS_TOTAL_CAPACITY_TOO_SMALL);
+ if (storageStatus == DvrStorageStatusManager.STORAGE_STATUS_TOTAL_CAPACITY_TOO_SMALL) {
+ return true;
+ }
+ List<ContentProviderOperation> ops = getDeleteOps();
if (ops == null || ops.isEmpty()) {
return null;
}
@@ -329,13 +335,28 @@ public class DvrStorageStatusManager {
}
@Override
- protected void onPostExecute(Void result) {
+ protected void onPostExecute(Boolean forgetStorage) {
+ if (forgetStorage != null && forgetStorage == true) {
+ DvrManager dvrManager = TvApplication.getSingletons(mContext).getDvrManager();
+ TvInputManagerHelper tvInputManagerHelper =
+ TvApplication.getSingletons(mContext).getTvInputManagerHelper();
+ List<TvInputInfo> tvInputInfoList =
+ tvInputManagerHelper.getTvInputInfos(true, false);
+ if (tvInputInfoList == null || tvInputInfoList.isEmpty()) {
+ return;
+ }
+ for (TvInputInfo info : tvInputInfoList) {
+ if (Utils.isBundledInput(info.getId())) {
+ dvrManager.forgetStorage(info.getId());
+ }
+ }
+ }
if (mCleanUpDbTask == this) {
mCleanUpDbTask = null;
}
}
- private List<ContentProviderOperation> getDeleteOps(boolean deleteAll) {
+ private List<ContentProviderOperation> getDeleteOps() {
List<ContentProviderOperation> ops = new ArrayList<>();
try (Cursor c = mContentResolver.query(
@@ -364,7 +385,7 @@ public class DvrStorageStatusManager {
continue;
}
File recordedProgramDir = new File(dataUri.getPath());
- if (deleteAll || !recordedProgramDir.exists()) {
+ if (!recordedProgramDir.exists()) {
ops.add(ContentProviderOperation.newDelete(
TvContract.buildRecordedProgramUri(Long.parseLong(id))).build());
}
diff --git a/src/com/android/tv/dvr/DvrUiHelper.java b/src/com/android/tv/dvr/DvrUiHelper.java
deleted file mode 100644
index c0d3b0c5..00000000
--- a/src/com/android/tv/dvr/DvrUiHelper.java
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.media.tv.TvInputManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.annotation.MainThread;
-import android.support.annotation.Nullable;
-import android.support.v4.app.ActivityOptionsCompat;
-import android.text.TextUtils;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import com.android.tv.MainActivity;
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.Channel;
-import com.android.tv.data.Program;
-import com.android.tv.dvr.ui.DvrDetailsActivity;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrAlreadyRecordedDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrAlreadyScheduledDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrChannelRecordDurationOptionDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrChannelWatchConflictDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrInsufficientSpaceErrorDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrMissingStorageErrorDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrProgramConflictDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrScheduleDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrSmallSizedStorageErrorDialogFragment;
-import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrStopRecordingDialogFragment;
-import com.android.tv.dvr.ui.DvrSchedulesActivity;
-import com.android.tv.dvr.ui.DvrSeriesDeletionActivity;
-import com.android.tv.dvr.ui.DvrSeriesScheduledDialogActivity;
-import com.android.tv.dvr.ui.DvrSeriesSettingsActivity;
-import com.android.tv.dvr.ui.DvrStopRecordingFragment;
-import com.android.tv.dvr.ui.DvrStopSeriesRecordingDialogFragment;
-import com.android.tv.dvr.ui.DvrStopSeriesRecordingFragment;
-import com.android.tv.dvr.ui.HalfSizedDialogFragment;
-import com.android.tv.dvr.ui.list.DvrSchedulesFragment;
-import com.android.tv.dvr.ui.list.DvrSeriesSchedulesFragment;
-import com.android.tv.util.Utils;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A helper class for DVR UI.
- */
-@MainThread
-@TargetApi(Build.VERSION_CODES.N)
-public class DvrUiHelper {
- /**
- * Handles the action to create the new schedule. It returns {@code true} if the schedule is
- * added and there's no additional UI, otherwise {@code false}.
- */
- public static boolean handleCreateSchedule(MainActivity activity, Program program) {
- if (program == null) {
- return false;
- }
- DvrManager dvrManager = TvApplication.getSingletons(activity).getDvrManager();
- if (!program.isEpisodic()) {
- // One time recording.
- dvrManager.addSchedule(program);
- if (!dvrManager.getConflictingSchedules(program).isEmpty()) {
- DvrUiHelper.showScheduleConflictDialog(activity, program);
- return false;
- }
- } else {
- SeriesRecording seriesRecording = dvrManager.getSeriesRecording(program);
- if (seriesRecording == null || seriesRecording.isStopped()) {
- DvrUiHelper.showScheduleDialog(activity, program);
- return false;
- } else {
- // Show recorded program rather than the schedule.
- RecordedProgram recordedProgram = dvrManager.getRecordedProgram(program.getTitle(),
- program.getSeasonNumber(), program.getEpisodeNumber());
- if (recordedProgram != null) {
- DvrUiHelper.showAlreadyRecordedDialog(activity, program);
- return false;
- }
- ScheduledRecording duplicate = dvrManager.getScheduledRecording(program.getTitle(),
- program.getSeasonNumber(), program.getEpisodeNumber());
- if (duplicate != null
- && (duplicate.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED
- || duplicate.getState()
- == ScheduledRecording.STATE_RECORDING_IN_PROGRESS)) {
- DvrUiHelper.showAlreadyScheduleDialog(activity, program);
- return false;
- }
- // Just add the schedule.
- dvrManager.addSchedule(program);
- }
- }
- return true;
-
- }
-
- /**
- * Checks if the storage status is good for recording and shows error messages if needed.
- *
- * @return true if the storage status is fine to be recorded for {@code inputId}.
- */
- public static boolean checkStorageStatusAndShowErrorMessage(Activity activity, String inputId) {
- if (!Utils.isBundledInput(inputId)) {
- return true;
- }
- DvrStorageStatusManager dvrStorageStatusManager =
- TvApplication.getSingletons(activity).getDvrStorageStatusManager();
- int status = dvrStorageStatusManager.getDvrStorageStatus();
- if (status == DvrStorageStatusManager.STORAGE_STATUS_TOTAL_CAPACITY_TOO_SMALL) {
- showDvrSmallSizedStorageErrorDialog(activity);
- return false;
- } else if (status == DvrStorageStatusManager.STORAGE_STATUS_MISSING) {
- showDvrMissingStorageErrorDialog(activity, inputId);
- return false;
- } else if (status == DvrStorageStatusManager.STORAGE_STATUS_FREE_SPACE_INSUFFICIENT) {
- // TODO: handle insufficient storage case.
- return true;
- } else {
- return true;
- }
- }
-
- /**
- * Shows the schedule dialog.
- */
- public static void showScheduleDialog(MainActivity activity, Program program) {
- if (SoftPreconditions.checkNotNull(program) == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
- showDialogFragment(activity, new DvrScheduleDialogFragment(), args, true, true);
- }
-
- /**
- * Shows the recording duration options dialog.
- */
- public static void showChannelRecordDurationOptions(MainActivity activity, Channel channel) {
- if (SoftPreconditions.checkNotNull(channel) == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putLong(DvrHalfSizedDialogFragment.KEY_CHANNEL_ID, channel.getId());
- showDialogFragment(activity, new DvrChannelRecordDurationOptionDialogFragment(), args);
- }
-
- /**
- * Shows the dialog which says that the new schedule conflicts with others.
- */
- public static void showScheduleConflictDialog(MainActivity activity, Program program) {
- if (program == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
- showDialogFragment(activity, new DvrProgramConflictDialogFragment(), args, false, true);
- }
-
- /**
- * Shows the conflict dialog for the channel watching.
- */
- public static void showChannelWatchConflictDialog(MainActivity activity, Channel channel) {
- if (channel == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putLong(DvrHalfSizedDialogFragment.KEY_CHANNEL_ID, channel.getId());
- showDialogFragment(activity, new DvrChannelWatchConflictDialogFragment(), args);
- }
-
- /**
- * Shows DVR insufficient space error dialog.
- */
- public static void showDvrInsufficientSpaceErrorDialog(MainActivity activity) {
- showDialogFragment(activity, new DvrInsufficientSpaceErrorDialogFragment(), null);
- Utils.clearRecordingFailedReason(activity,
- TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE);
- }
-
- /**
- * Shows DVR missing storage error dialog.
- */
- private static void showDvrMissingStorageErrorDialog(Activity activity, String inputId) {
- SoftPreconditions.checkArgument(!TextUtils.isEmpty(inputId));
- Bundle args = new Bundle();
- args.putString(DvrHalfSizedDialogFragment.KEY_INPUT_ID, inputId);
- showDialogFragment(activity, new DvrMissingStorageErrorDialogFragment(), args);
- }
-
- /**
- * Shows DVR small sized storage error dialog.
- */
- public static void showDvrSmallSizedStorageErrorDialog(Activity activity) {
- showDialogFragment(activity, new DvrSmallSizedStorageErrorDialogFragment(), null);
- }
-
- /**
- * Shows stop recording dialog.
- */
- public static void showStopRecordingDialog(Activity activity, long channelId, int reason,
- HalfSizedDialogFragment.OnActionClickListener listener) {
- Bundle args = new Bundle();
- args.putLong(DvrHalfSizedDialogFragment.KEY_CHANNEL_ID, channelId);
- args.putInt(DvrStopRecordingFragment.KEY_REASON, reason);
- DvrHalfSizedDialogFragment fragment = new DvrStopRecordingDialogFragment();
- fragment.setOnActionClickListener(listener);
- showDialogFragment(activity, fragment, args);
- }
-
- /**
- * Shows "already scheduled" dialog.
- */
- public static void showAlreadyScheduleDialog(MainActivity activity, Program program) {
- if (program == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
- showDialogFragment(activity, new DvrAlreadyScheduledDialogFragment(), args, false, true);
- }
-
- /**
- * Shows "already recorded" dialog.
- */
- public static void showAlreadyRecordedDialog(MainActivity activity, Program program) {
- if (program == null) {
- return;
- }
- Bundle args = new Bundle();
- args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
- showDialogFragment(activity, new DvrAlreadyRecordedDialogFragment(), args, false, true);
- }
-
- private static void showDialogFragment(Activity activity,
- DvrHalfSizedDialogFragment dialogFragment, Bundle args) {
- showDialogFragment(activity, dialogFragment, args, false, false);
- }
-
- private static void showDialogFragment(Activity activity,
- DvrHalfSizedDialogFragment dialogFragment, Bundle args, boolean keepSidePanelHistory,
- boolean keepProgramGuide) {
- dialogFragment.setArguments(args);
- if (activity instanceof MainActivity) {
- ((MainActivity) activity).getOverlayManager()
- .showDialogFragment(DvrHalfSizedDialogFragment.DIALOG_TAG, dialogFragment,
- keepSidePanelHistory, keepProgramGuide);
- } else {
- dialogFragment.show(activity.getFragmentManager(),
- DvrHalfSizedDialogFragment.DIALOG_TAG);
- }
- }
-
- /**
- * Checks whether channel watch conflict dialog is open or not.
- */
- public static boolean isChannelWatchConflictDialogShown(MainActivity activity) {
- return activity.getOverlayManager().getCurrentDialog() instanceof
- DvrChannelWatchConflictDialogFragment;
- }
-
- private static ScheduledRecording getEarliestScheduledRecording(List<ScheduledRecording>
- recordings) {
- ScheduledRecording earlistScheduledRecording = null;
- if (!recordings.isEmpty()) {
- Collections.sort(recordings,
- ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR);
- earlistScheduledRecording = recordings.get(0);
- }
- return earlistScheduledRecording;
- }
-
- /**
- * Shows the schedules activity to resolve the tune conflict.
- */
- public static void startSchedulesActivityForTuneConflict(Context context, Channel channel) {
- if (channel == null) {
- return;
- }
- List<ScheduledRecording> conflicts = TvApplication.getSingletons(context).getDvrManager()
- .getConflictingSchedulesForTune(channel.getId());
- startSchedulesActivity(context, getEarliestScheduledRecording(conflicts));
- }
-
- /**
- * Shows the schedules activity to resolve the one time recording conflict.
- */
- public static void startSchedulesActivityForOneTimeRecordingConflict(Context context,
- List<ScheduledRecording> conflicts) {
- startSchedulesActivity(context, getEarliestScheduledRecording(conflicts));
- }
-
- /**
- * Shows the schedules activity with full schedule.
- */
- public static void startSchedulesActivity(Context context, ScheduledRecording
- focusedScheduledRecording) {
- Intent intent = new Intent(context, DvrSchedulesActivity.class);
- intent.putExtra(DvrSchedulesActivity.KEY_SCHEDULES_TYPE,
- DvrSchedulesActivity.TYPE_FULL_SCHEDULE);
- if (focusedScheduledRecording != null) {
- intent.putExtra(DvrSchedulesFragment.SCHEDULES_KEY_SCHEDULED_RECORDING,
- focusedScheduledRecording);
- }
- context.startActivity(intent);
- }
-
- /**
- * Shows the schedules activity for series recording.
- */
- public static void startSchedulesActivityForSeries(Context context,
- SeriesRecording seriesRecording) {
- Intent intent = new Intent(context, DvrSchedulesActivity.class);
- intent.putExtra(DvrSchedulesActivity.KEY_SCHEDULES_TYPE,
- DvrSchedulesActivity.TYPE_SERIES_SCHEDULE);
- intent.putExtra(DvrSeriesSchedulesFragment.SERIES_SCHEDULES_KEY_SERIES_RECORDING,
- seriesRecording);
- context.startActivity(intent);
- }
-
- /**
- * Shows the series settings activity.
- *
- * @param channelIds Channel ID list which has programs belonging to the series.
- */
- public static void startSeriesSettingsActivity(Context context, long seriesRecordingId,
- @Nullable long[] channelIds, boolean removeEmptySeriesSchedule,
- boolean isWindowTranslucent, boolean showViewScheduleOptionInDialog) {
- Intent intent = new Intent(context, DvrSeriesSettingsActivity.class);
- intent.putExtra(DvrSeriesSettingsActivity.SERIES_RECORDING_ID, seriesRecordingId);
- intent.putExtra(DvrSeriesSettingsActivity.CHANNEL_ID_LIST, channelIds);
- intent.putExtra(DvrSeriesSettingsActivity.REMOVE_EMPTY_SERIES_RECORDING,
- removeEmptySeriesSchedule);
- intent.putExtra(DvrSeriesSettingsActivity.IS_WINDOW_TRANSLUCENT, isWindowTranslucent);
- intent.putExtra(DvrSeriesSettingsActivity.SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG,
- showViewScheduleOptionInDialog);
- context.startActivity(intent);
- }
-
- /**
- * Shows "series recording scheduled" dialog activity.
- */
- public static void StartSeriesScheduledDialogActivity(Context context,
- SeriesRecording seriesRecording, boolean showViewScheduleOptionInDialog) {
- if (seriesRecording == null) {
- return;
- }
- Intent intent = new Intent(context, DvrSeriesScheduledDialogActivity.class);
- intent.putExtra(DvrSeriesScheduledDialogActivity.SERIES_RECORDING_ID,
- seriesRecording.getId());
- intent.putExtra(DvrSeriesScheduledDialogActivity.SHOW_VIEW_SCHEDULE_OPTION,
- showViewScheduleOptionInDialog);
- context.startActivity(intent);
- }
-
- /**
- * Shows the details activity for the DVR items. The type of DVR items may be
- * {@link ScheduledRecording}, {@link RecordedProgram}, or {@link SeriesRecording}.
- */
- public static void startDetailsActivity(Activity activity, Object dvrItem,
- @Nullable ImageView imageView, boolean hideViewSchedule) {
- if (dvrItem == null) {
- return;
- }
- Intent intent = new Intent(activity, DvrDetailsActivity.class);
- long recordingId;
- int viewType;
- if (dvrItem instanceof ScheduledRecording) {
- ScheduledRecording schedule = (ScheduledRecording) dvrItem;
- recordingId = schedule.getId();
- if (schedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED) {
- viewType = DvrDetailsActivity.SCHEDULED_RECORDING_VIEW;
- } else if (schedule.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS) {
- viewType = DvrDetailsActivity.CURRENT_RECORDING_VIEW;
- } else {
- return;
- }
- } else if (dvrItem instanceof RecordedProgram) {
- recordingId = ((RecordedProgram) dvrItem).getId();
- viewType = DvrDetailsActivity.RECORDED_PROGRAM_VIEW;
- } else if (dvrItem instanceof SeriesRecording) {
- recordingId = ((SeriesRecording) dvrItem).getId();
- viewType = DvrDetailsActivity.SERIES_RECORDING_VIEW;
- } else {
- return;
- }
- intent.putExtra(DvrDetailsActivity.RECORDING_ID, recordingId);
- intent.putExtra(DvrDetailsActivity.DETAILS_VIEW_TYPE, viewType);
- intent.putExtra(DvrDetailsActivity.HIDE_VIEW_SCHEDULE, hideViewSchedule);
- Bundle bundle = null;
- if (imageView != null) {
- bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, imageView,
- DvrDetailsActivity.SHARED_ELEMENT_NAME).toBundle();
- }
- activity.startActivity(intent, bundle);
- }
-
- /**
- * Shows the cancel all dialog for series schedules list.
- */
- public static void showCancelAllSeriesRecordingDialog(DvrSchedulesActivity activity,
- SeriesRecording seriesRecording) {
- DvrStopSeriesRecordingDialogFragment dvrStopSeriesRecordingDialogFragment =
- new DvrStopSeriesRecordingDialogFragment();
- Bundle arguments = new Bundle();
- arguments.putParcelable(DvrStopSeriesRecordingFragment.KEY_SERIES_RECORDING,
- seriesRecording);
- dvrStopSeriesRecordingDialogFragment.setArguments(arguments);
- dvrStopSeriesRecordingDialogFragment.show(activity.getFragmentManager(),
- DvrStopSeriesRecordingDialogFragment.DIALOG_TAG);
- }
-
- /**
- * Shows the series deletion activity.
- */
- public static void startSeriesDeletionActivity(Context context, long seriesRecordingId) {
- Intent intent = new Intent(context, DvrSeriesDeletionActivity.class);
- intent.putExtra(DvrSeriesDeletionActivity.SERIES_RECORDING_ID, seriesRecordingId);
- context.startActivity(intent);
- }
-
- public static void showAddScheduleToast(Context context,
- String title, long startTimeMs, long endTimeMs) {
- String msg = (startTimeMs > System.currentTimeMillis()) ?
- context.getString(R.string.dvr_msg_program_scheduled, title)
- : context.getString(R.string.dvr_msg_current_program_scheduled, title,
- Utils.toTimeString(endTimeMs, false));
- Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
- }
-}
diff --git a/src/com/android/tv/dvr/DvrWatchedPositionManager.java b/src/com/android/tv/dvr/DvrWatchedPositionManager.java
index 4eada742..da6ddb1a 100644
--- a/src/com/android/tv/dvr/DvrWatchedPositionManager.java
+++ b/src/com/android/tv/dvr/DvrWatchedPositionManager.java
@@ -22,6 +22,7 @@ import android.media.tv.TvInputManager;
import android.support.annotation.IntDef;
import com.android.tv.common.SharedPreferencesUtils;
+import com.android.tv.dvr.data.RecordedProgram;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -36,9 +37,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
* It will remember and provides previous watched position of DVR playback.
*/
public class DvrWatchedPositionManager {
- private final static String TAG = "DvrWatchedPositionManager";
- private final boolean DEBUG = false;
-
private SharedPreferences mWatchedPositions;
private final Map<Long, Set> mListeners = new HashMap<>();
diff --git a/src/com/android/tv/dvr/EpisodicProgramLoadTask.java b/src/com/android/tv/dvr/EpisodicProgramLoadTask.java
deleted file mode 100644
index 15ca2700..00000000
--- a/src/com/android/tv/dvr/EpisodicProgramLoadTask.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.database.Cursor;
-import android.media.tv.TvContract;
-import android.media.tv.TvContract.Programs;
-import android.net.Uri;
-import android.os.Build;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.support.annotation.WorkerThread;
-import android.text.TextUtils;
-
-import com.android.tv.TvApplication;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.Program;
-import com.android.tv.util.AsyncDbTask.AsyncProgramQueryTask;
-import com.android.tv.util.AsyncDbTask.CursorFilter;
-import com.android.tv.util.PermissionUtils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * A wrapper of AsyncProgramQueryTask to load the episodic programs for the series recordings.
- */
-@TargetApi(Build.VERSION_CODES.N)
-abstract public class EpisodicProgramLoadTask {
- private static final String TAG = "EpisodicProgramLoadTask";
-
- private static final int PROGRAM_ID_INDEX = Program.getColumnIndex(Programs._ID);
- private static final int START_TIME_INDEX =
- Program.getColumnIndex(Programs.COLUMN_START_TIME_UTC_MILLIS);
- private static final int RECORDING_PROHIBITED_INDEX =
- Program.getColumnIndex(Programs.COLUMN_RECORDING_PROHIBITED);
-
- private static final String PARAM_START_TIME = "start_time";
- private static final String PARAM_END_TIME = "end_time";
-
- private static final String PROGRAM_PREDICATE =
- Programs.COLUMN_START_TIME_UTC_MILLIS + ">? AND "
- + Programs.COLUMN_RECORDING_PROHIBITED + "=0";
- private static final String PROGRAM_PREDICATE_WITH_CURRENT_PROGRAM =
- Programs.COLUMN_END_TIME_UTC_MILLIS + ">? AND "
- + Programs.COLUMN_RECORDING_PROHIBITED + "=0";
- private static final String CHANNEL_ID_PREDICATE = Programs.COLUMN_CHANNEL_ID + "=?";
- private static final String PROGRAM_TITLE_PREDICATE = Programs.COLUMN_TITLE + "=?";
-
- private final Context mContext;
- private final DvrDataManager mDataManager;
- private boolean mQueryAllChannels;
- private boolean mLoadCurrentProgram;
- private boolean mLoadScheduledEpisode;
- private boolean mLoadDisallowedProgram;
- // If true, match programs with OPTION_CHANNEL_ALL.
- private boolean mIgnoreChannelOption;
- private final ArrayList<SeriesRecording> mSeriesRecordings = new ArrayList<>();
- private AsyncProgramQueryTask mProgramQueryTask;
-
- /**
- *
- * Constructor used to load programs for one series recording with the given channel option.
- */
- public EpisodicProgramLoadTask(Context context, SeriesRecording seriesRecording) {
- this(context, Collections.singletonList(seriesRecording));
- }
-
- /**
- * Constructor used to load programs for multiple series recordings. The channel option is
- * {@link SeriesRecording#OPTION_CHANNEL_ALL}.
- */
- public EpisodicProgramLoadTask(Context context, Collection<SeriesRecording> seriesRecordings) {
- mContext = context.getApplicationContext();
- mDataManager = TvApplication.getSingletons(context).getDvrDataManager();
- mSeriesRecordings.addAll(seriesRecordings);
- }
-
- /**
- * Returns the series recordings.
- */
- public List<SeriesRecording> getSeriesRecordings() {
- return mSeriesRecordings;
- }
-
- /**
- * Returns the program query task. It is {@code null} until it is executed.
- */
- @Nullable
- public AsyncProgramQueryTask getTask() {
- return mProgramQueryTask;
- }
-
- /**
- * Enables loading current programs. The default value is {@code false}.
- */
- public EpisodicProgramLoadTask setLoadCurrentProgram(boolean loadCurrentProgram) {
- SoftPreconditions.checkState(mProgramQueryTask == null, TAG,
- "Can't change setting after execution.");
- mLoadCurrentProgram = loadCurrentProgram;
- return this;
- }
-
- /**
- * Enables already schedules episodes. The default value is {@code false}.
- */
- public EpisodicProgramLoadTask setLoadScheduledEpisode(boolean loadScheduledEpisode) {
- SoftPreconditions.checkState(mProgramQueryTask == null, TAG,
- "Can't change setting after execution.");
- mLoadScheduledEpisode = loadScheduledEpisode;
- return this;
- }
-
- /**
- * Enables loading disallowed programs whose schedules were removed manually by the user.
- * The default value is {@code false}.
- */
- public EpisodicProgramLoadTask setLoadDisallowedProgram(boolean loadDisallowedProgram) {
- SoftPreconditions.checkState(mProgramQueryTask == null, TAG,
- "Can't change setting after execution.");
- mLoadDisallowedProgram = loadDisallowedProgram;
- return this;
- }
-
- /**
- * Gives the option whether to ignore the channel option when matching programs.
- * If {@code ignoreChannelOption} is {@code true}, the program will be matched with
- * {@link SeriesRecording#OPTION_CHANNEL_ALL} option.
- */
- public EpisodicProgramLoadTask setIgnoreChannelOption(boolean ignoreChannelOption) {
- SoftPreconditions.checkState(mProgramQueryTask == null, TAG,
- "Can't change setting after execution.");
- mIgnoreChannelOption = ignoreChannelOption;
- return this;
- }
-
- /**
- * Executes the task.
- *
- * @see com.android.tv.util.AsyncDbTask#executeOnDbThread
- */
- public void execute() {
- if (SoftPreconditions.checkState(mProgramQueryTask == null, TAG,
- "Can't execute task: the task is already running.")) {
- mQueryAllChannels = mSeriesRecordings.size() > 1
- || mSeriesRecordings.get(0).getChannelOption()
- == SeriesRecording.OPTION_CHANNEL_ALL
- || mIgnoreChannelOption;
- mProgramQueryTask = createTask();
- mProgramQueryTask.executeOnDbThread();
- }
- }
-
- /**
- * Cancels the task.
- *
- * @see android.os.AsyncTask#cancel
- */
- public void cancel(boolean mayInterruptIfRunning) {
- if (mProgramQueryTask != null) {
- mProgramQueryTask.cancel(mayInterruptIfRunning);
- }
- }
-
- /**
- * Runs on the UI thread after the program loading finishes successfully.
- */
- protected void onPostExecute(List<Program> programs) {
- }
-
- /**
- * Runs on the UI thread after the program loading was canceled.
- */
- protected void onCancelled(List<Program> programs) {
- }
-
- private AsyncProgramQueryTask createTask() {
- SqlParams sqlParams = createSqlParams();
- return new AsyncProgramQueryTask(mContext.getContentResolver(), sqlParams.uri,
- sqlParams.selection, sqlParams.selectionArgs, null, sqlParams.filter) {
- @Override
- protected void onPostExecute(List<Program> programs) {
- EpisodicProgramLoadTask.this.onPostExecute(programs);
- }
-
- @Override
- protected void onCancelled(List<Program> programs) {
- EpisodicProgramLoadTask.this.onCancelled(programs);
- }
- };
- }
-
- private SqlParams createSqlParams() {
- SqlParams sqlParams = new SqlParams();
- if (PermissionUtils.hasAccessAllEpg(mContext)) {
- sqlParams.uri = Programs.CONTENT_URI;
- // Base
- StringBuilder selection = new StringBuilder(mLoadCurrentProgram
- ? PROGRAM_PREDICATE_WITH_CURRENT_PROGRAM : PROGRAM_PREDICATE);
- List<String> args = new ArrayList<>();
- args.add(Long.toString(System.currentTimeMillis()));
- // Channel option
- if (!mQueryAllChannels) {
- selection.append(" AND ").append(CHANNEL_ID_PREDICATE);
- args.add(Long.toString(mSeriesRecordings.get(0).getChannelId()));
- }
- // Title
- if (mSeriesRecordings.size() == 1) {
- selection.append(" AND ").append(PROGRAM_TITLE_PREDICATE);
- args.add(mSeriesRecordings.get(0).getTitle());
- }
- sqlParams.selection = selection.toString();
- sqlParams.selectionArgs = args.toArray(new String[args.size()]);
- sqlParams.filter = new SeriesRecordingCursorFilter(mSeriesRecordings);
- } else {
- // The query includes the current program. Will be filtered if needed.
- if (mQueryAllChannels) {
- sqlParams.uri = Programs.CONTENT_URI.buildUpon()
- .appendQueryParameter(PARAM_START_TIME,
- String.valueOf(System.currentTimeMillis()))
- .appendQueryParameter(PARAM_END_TIME, String.valueOf(Long.MAX_VALUE))
- .build();
- } else {
- sqlParams.uri = TvContract.buildProgramsUriForChannel(
- mSeriesRecordings.get(0).getChannelId(),
- System.currentTimeMillis(), Long.MAX_VALUE);
- }
- sqlParams.selection = null;
- sqlParams.selectionArgs = null;
- sqlParams.filter = new SeriesRecordingCursorFilterForNonSystem(mSeriesRecordings);
- }
- return sqlParams;
- }
-
- @VisibleForTesting
- static boolean isEpisodeScheduled(Collection<ScheduledEpisode> scheduledEpisodes,
- ScheduledEpisode episode) {
- // The episode whose season number or episode number is null will always be scheduled.
- return scheduledEpisodes.contains(episode) && !TextUtils.isEmpty(episode.seasonNumber)
- && !TextUtils.isEmpty(episode.episodeNumber);
- }
-
- /**
- * Filter the programs which match the series recording. The episodes which the schedules are
- * already created for are filtered out too.
- */
- private class SeriesRecordingCursorFilter implements CursorFilter {
- private final Set<Long> mDisallowedProgramIds = new HashSet<>();
- private final Set<ScheduledEpisode> mScheduledEpisodes = new HashSet<>();
-
- SeriesRecordingCursorFilter(List<SeriesRecording> seriesRecordings) {
- if (!mLoadDisallowedProgram) {
- mDisallowedProgramIds.addAll(mDataManager.getDisallowedProgramIds());
- }
- if (!mLoadScheduledEpisode) {
- Set<Long> seriesRecordingIds = new HashSet<>();
- for (SeriesRecording r : seriesRecordings) {
- seriesRecordingIds.add(r.getId());
- }
- for (ScheduledRecording r : mDataManager.getAllScheduledRecordings()) {
- if (seriesRecordingIds.contains(r.getSeriesRecordingId())
- && r.getState() != ScheduledRecording.STATE_RECORDING_FAILED
- && r.getState() != ScheduledRecording.STATE_RECORDING_CLIPPED) {
- mScheduledEpisodes.add(new ScheduledEpisode(r));
- }
- }
- }
- }
-
- @Override
- @WorkerThread
- public boolean filter(Cursor c) {
- if (!mLoadDisallowedProgram
- && mDisallowedProgramIds.contains(c.getLong(PROGRAM_ID_INDEX))) {
- return false;
- }
- Program program = Program.fromCursor(c);
- for (SeriesRecording seriesRecording : mSeriesRecordings) {
- boolean programMatches;
- if (mIgnoreChannelOption) {
- programMatches = seriesRecording.matchProgram(program,
- SeriesRecording.OPTION_CHANNEL_ALL);
- } else {
- programMatches = seriesRecording.matchProgram(program);
- }
- if (programMatches) {
- return mLoadScheduledEpisode
- || !isEpisodeScheduled(mScheduledEpisodes, new ScheduledEpisode(
- seriesRecording.getId(), program.getSeasonNumber(),
- program.getEpisodeNumber()));
- }
- }
- return false;
- }
- }
-
- private class SeriesRecordingCursorFilterForNonSystem extends SeriesRecordingCursorFilter {
- SeriesRecordingCursorFilterForNonSystem(List<SeriesRecording> seriesRecordings) {
- super(seriesRecordings);
- }
-
- @Override
- public boolean filter(Cursor c) {
- return (mLoadCurrentProgram || c.getLong(START_TIME_INDEX) > System.currentTimeMillis())
- && c.getInt(RECORDING_PROHIBITED_INDEX) != 0 && super.filter(c);
- }
- }
-
- private static class SqlParams {
- public Uri uri;
- public String selection;
- public String[] selectionArgs;
- public CursorFilter filter;
- }
-
- /**
- * A plain java object which includes the season/episode number for the series recording.
- */
- public static class ScheduledEpisode {
- public final long seriesRecordingId;
- public final String seasonNumber;
- public final String episodeNumber;
-
- /**
- * Create a new Builder with the values set from an existing {@link ScheduledRecording}.
- */
- ScheduledEpisode(ScheduledRecording r) {
- this(r.getSeriesRecordingId(), r.getSeasonNumber(), r.getEpisodeNumber());
- }
-
- public ScheduledEpisode(long seriesRecordingId, String seasonNumber, String episodeNumber) {
- this.seriesRecordingId = seriesRecordingId;
- this.seasonNumber = seasonNumber;
- this.episodeNumber = episodeNumber;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof ScheduledEpisode)) return false;
- ScheduledEpisode that = (ScheduledEpisode) o;
- return seriesRecordingId == that.seriesRecordingId
- && Objects.equals(seasonNumber, that.seasonNumber)
- && Objects.equals(episodeNumber, that.episodeNumber);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(seriesRecordingId, seasonNumber, episodeNumber);
- }
-
- @Override
- public String toString() {
- return "ScheduledEpisode{" +
- "seriesRecordingId=" + seriesRecordingId +
- ", seasonNumber='" + seasonNumber +
- ", episodeNumber=" + episodeNumber +
- '}';
- }
- }
-}
diff --git a/src/com/android/tv/dvr/IdGenerator.java b/src/com/android/tv/dvr/IdGenerator.java
deleted file mode 100644
index 0ed6362c..00000000
--- a/src/com/android/tv/dvr/IdGenerator.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * A class which generate the ID which increases sequentially.
- */
-public class IdGenerator {
- /**
- * ID generator for the scheduled recording.
- */
- public static final IdGenerator SCHEDULED_RECORDING = new IdGenerator();
-
- /**
- * ID generator for the series recording.
- */
- public static final IdGenerator SERIES_RECORDING = new IdGenerator();
-
- private final AtomicLong mMaxId = new AtomicLong(0);
-
- /**
- * Sets the new maximum ID.
- */
- public void setMaxId(long maxId) {
- mMaxId.set(maxId);
- }
-
- /**
- * Returns the new ID which is greater than the existing maximum ID by 1.
- */
- public long newId() {
- return mMaxId.incrementAndGet();
- }
-}
diff --git a/src/com/android/tv/dvr/InputTaskScheduler.java b/src/com/android/tv/dvr/InputTaskScheduler.java
deleted file mode 100644
index 53c89ebc..00000000
--- a/src/com/android/tv/dvr/InputTaskScheduler.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.content.Context;
-import android.media.tv.TvInputInfo;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.LongSparseArray;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.util.Clock;
-import com.android.tv.util.CompositeComparator;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * The scheduler for a TV input.
- */
-public class InputTaskScheduler {
- private static final String TAG = "InputTaskScheduler";
- private static final boolean DEBUG = false;
-
- private static final int MSG_ADD_SCHEDULED_RECORDING = 1;
- private static final int MSG_REMOVE_SCHEDULED_RECORDING = 2;
- private static final int MSG_UPDATE_SCHEDULED_RECORDING = 3;
- private static final int MSG_BUILD_SCHEDULE = 4;
- private static final int MSG_STOP_SCHEDULE = 5;
-
- private static final float MIN_REMAIN_DURATION_PERCENT = 0.05f;
-
- // The candidate comparator should be the consistent with
- // DvrScheduleManager#CANDIDATE_COMPARATOR.
- private static final Comparator<RecordingTask> CANDIDATE_COMPARATOR =
- new CompositeComparator<>(
- RecordingTask.PRIORITY_COMPARATOR,
- RecordingTask.END_TIME_COMPARATOR,
- RecordingTask.ID_COMPARATOR);
-
- /**
- * Returns the comparator which the schedules are sorted with when executed.
- */
- public static Comparator<ScheduledRecording> getRecordingOrderComparator() {
- return ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR;
- }
-
- /**
- * Wraps a {@link RecordingTask} removing it from {@link #mPendingRecordings} when it is done.
- */
- public final class HandlerWrapper extends Handler {
- public static final int MESSAGE_REMOVE = 999;
- private final long mId;
- private final RecordingTask mTask;
-
- HandlerWrapper(Looper looper, ScheduledRecording scheduledRecording,
- RecordingTask recordingTask) {
- super(looper, recordingTask);
- mId = scheduledRecording.getId();
- mTask = recordingTask;
- mTask.setHandler(this);
- }
-
- @Override
- public void handleMessage(Message msg) {
- // The RecordingTask gets a chance first.
- // It must return false to pass this message to here.
- if (msg.what == MESSAGE_REMOVE) {
- if (DEBUG) Log.d(TAG, "done " + mId);
- mPendingRecordings.remove(mId);
- }
- removeCallbacksAndMessages(null);
- mHandler.removeMessages(MSG_BUILD_SCHEDULE);
- mHandler.sendEmptyMessage(MSG_BUILD_SCHEDULE);
- super.handleMessage(msg);
- }
- }
-
- private TvInputInfo mInput;
- private final Looper mLooper;
- private final ChannelDataManager mChannelDataManager;
- private final DvrManager mDvrManager;
- private final WritableDvrDataManager mDataManager;
- private final InputSessionManager mSessionManager;
- private final Clock mClock;
- private final Context mContext;
-
- private final LongSparseArray<HandlerWrapper> mPendingRecordings = new LongSparseArray<>();
- private final Map<Long, ScheduledRecording> mWaitingSchedules = new ArrayMap<>();
- private final Handler mMainThreadHandler;
- private final Handler mHandler;
- private final Object mInputLock = new Object();
- private final RecordingTaskFactory mRecordingTaskFactory;
-
- public InputTaskScheduler(Context context, TvInputInfo input, Looper looper,
- ChannelDataManager channelDataManager, DvrManager dvrManager,
- DvrDataManager dataManager, InputSessionManager sessionManager, Clock clock) {
- this(context, input, looper, channelDataManager, dvrManager, dataManager, sessionManager,
- clock, new Handler(Looper.getMainLooper()), null, null);
- }
-
- @VisibleForTesting
- InputTaskScheduler(Context context, TvInputInfo input, Looper looper,
- ChannelDataManager channelDataManager, DvrManager dvrManager,
- DvrDataManager dataManager, InputSessionManager sessionManager, Clock clock,
- Handler mainThreadHandler, @Nullable Handler workerThreadHandler,
- RecordingTaskFactory recordingTaskFactory) {
- if (DEBUG) Log.d(TAG, "Creating scheduler for " + input);
- mContext = context;
- mInput = input;
- mLooper = looper;
- mChannelDataManager = channelDataManager;
- mDvrManager = dvrManager;
- mDataManager = (WritableDvrDataManager) dataManager;
- mSessionManager = sessionManager;
- mClock = clock;
- mMainThreadHandler = mainThreadHandler;
- mRecordingTaskFactory = recordingTaskFactory != null ? recordingTaskFactory
- : new RecordingTaskFactory() {
- @Override
- public RecordingTask createRecordingTask(ScheduledRecording schedule, Channel channel,
- DvrManager dvrManager, InputSessionManager sessionManager,
- WritableDvrDataManager dataManager, Clock clock) {
- return new RecordingTask(mContext, schedule, channel, mDvrManager, mSessionManager,
- mDataManager, mClock);
- }
- };
- if (workerThreadHandler == null) {
- mHandler = new WorkerThreadHandler(looper);
- } else {
- mHandler = workerThreadHandler;
- }
- }
-
- /**
- * Adds a {@link ScheduledRecording}.
- */
- public void addSchedule(ScheduledRecording schedule) {
- mHandler.sendMessage(mHandler.obtainMessage(MSG_ADD_SCHEDULED_RECORDING, schedule));
- }
-
- @VisibleForTesting
- void handleAddSchedule(ScheduledRecording schedule) {
- if (mPendingRecordings.get(schedule.getId()) != null
- || mWaitingSchedules.containsKey(schedule.getId())) {
- return;
- }
- mWaitingSchedules.put(schedule.getId(), schedule);
- mHandler.removeMessages(MSG_BUILD_SCHEDULE);
- mHandler.sendEmptyMessage(MSG_BUILD_SCHEDULE);
- }
-
- /**
- * Removes the {@link ScheduledRecording}.
- */
- public void removeSchedule(ScheduledRecording schedule) {
- mHandler.sendMessage(mHandler.obtainMessage(MSG_REMOVE_SCHEDULED_RECORDING, schedule));
- }
-
- @VisibleForTesting
- void handleRemoveSchedule(ScheduledRecording schedule) {
- HandlerWrapper wrapper = mPendingRecordings.get(schedule.getId());
- if (wrapper != null) {
- wrapper.mTask.cancel();
- return;
- }
- if (mWaitingSchedules.containsKey(schedule.getId())) {
- mWaitingSchedules.remove(schedule.getId());
- mHandler.removeMessages(MSG_BUILD_SCHEDULE);
- mHandler.sendEmptyMessage(MSG_BUILD_SCHEDULE);
- }
- }
-
- /**
- * Updates the {@link ScheduledRecording}.
- */
- public void updateSchedule(ScheduledRecording schedule) {
- mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_SCHEDULED_RECORDING, schedule));
- }
-
- @VisibleForTesting
- void handleUpdateSchedule(ScheduledRecording schedule) {
- HandlerWrapper wrapper = mPendingRecordings.get(schedule.getId());
- if (wrapper != null) {
- if (schedule.getStartTimeMs() > mClock.currentTimeMillis()
- && schedule.getStartTimeMs() > wrapper.mTask.getStartTimeMs()) {
- // It shouldn't have started. Cancel and put to the waiting list.
- // The schedules will be rebuilt when the task is removed.
- // The reschedule is called in Scheduler.
- wrapper.mTask.cancel();
- mWaitingSchedules.put(schedule.getId(), schedule);
- return;
- }
- wrapper.sendMessage(wrapper.obtainMessage(RecordingTask.MSG_UDPATE_SCHEDULE, schedule));
- return;
- }
- if (mWaitingSchedules.containsKey(schedule.getId())) {
- mWaitingSchedules.put(schedule.getId(), schedule);
- mHandler.removeMessages(MSG_BUILD_SCHEDULE);
- mHandler.sendEmptyMessage(MSG_BUILD_SCHEDULE);
- }
- }
-
- /**
- * Updates the TV input.
- */
- public void updateTvInputInfo(TvInputInfo input) {
- synchronized (mInputLock) {
- mInput = input;
- }
- }
-
- /**
- * Stops the input task scheduler.
- */
- public void stop() {
- mHandler.removeCallbacksAndMessages(null);
- mHandler.sendEmptyMessage(MSG_STOP_SCHEDULE);
- }
-
- private void handleStopSchedule() {
- mWaitingSchedules.clear();
- int size = mPendingRecordings.size();
- for (int i = 0; i < size; ++i) {
- RecordingTask task = mPendingRecordings.get(mPendingRecordings.keyAt(i)).mTask;
- task.cleanUp();
- }
- }
-
- @VisibleForTesting
- void handleBuildSchedule() {
- if (mWaitingSchedules.isEmpty()) {
- return;
- }
- long currentTimeMs = mClock.currentTimeMillis();
- // Remove past schedules.
- for (Iterator<ScheduledRecording> iter = mWaitingSchedules.values().iterator();
- iter.hasNext(); ) {
- ScheduledRecording schedule = iter.next();
- if (schedule.getEndTimeMs() - currentTimeMs
- <= MIN_REMAIN_DURATION_PERCENT * schedule.getDuration()) {
- fail(schedule);
- iter.remove();
- }
- }
- if (mWaitingSchedules.isEmpty()) {
- return;
- }
- // Record the schedules which should start now.
- List<ScheduledRecording> schedulesToStart = new ArrayList<>();
- for (ScheduledRecording schedule : mWaitingSchedules.values()) {
- if (schedule.getState() != ScheduledRecording.STATE_RECORDING_CANCELED
- && schedule.getStartTimeMs() - RecordingTask.RECORDING_EARLY_START_OFFSET_MS
- <= currentTimeMs && schedule.getEndTimeMs() > currentTimeMs) {
- schedulesToStart.add(schedule);
- }
- }
- // The schedules will be executed with the following order.
- // 1. The schedule which starts early. It can be replaced later when the schedule with the
- // higher priority needs to start.
- // 2. The schedule with the higher priority. It can be replaced later when the schedule with
- // the higher priority needs to start.
- // 3. The schedule which was created recently.
- Collections.sort(schedulesToStart, getRecordingOrderComparator());
- int tunerCount;
- synchronized (mInputLock) {
- tunerCount = mInput.canRecord() ? mInput.getTunerCount() : 0;
- }
- for (ScheduledRecording schedule : schedulesToStart) {
- if (hasTaskWhichFinishEarlier(schedule)) {
- // If there is a schedule which finishes earlier than the new schedule, rebuild the
- // schedules after it finishes.
- return;
- }
- if (mPendingRecordings.size() < tunerCount) {
- // Tuners available.
- createRecordingTask(schedule).start();
- mWaitingSchedules.remove(schedule.getId());
- } else {
- // No available tuners.
- RecordingTask task = getReplacableTask(schedule);
- if (task != null) {
- task.stop();
- // Just return. The schedules will be rebuilt after the task is stopped.
- return;
- }
- }
- }
- if (mWaitingSchedules.isEmpty()) {
- return;
- }
- // Set next scheduling.
- long earliest = Long.MAX_VALUE;
- for (ScheduledRecording schedule : mWaitingSchedules.values()) {
- // The conflicting schedules will be removed if they end before conflicting resolved.
- if (schedulesToStart.contains(schedule)) {
- if (earliest > schedule.getEndTimeMs()) {
- earliest = schedule.getEndTimeMs();
- }
- } else {
- if (earliest > schedule.getStartTimeMs()
- - RecordingTask.RECORDING_EARLY_START_OFFSET_MS) {
- earliest = schedule.getStartTimeMs()
- - RecordingTask.RECORDING_EARLY_START_OFFSET_MS;
- }
- }
- }
- mHandler.sendEmptyMessageDelayed(MSG_BUILD_SCHEDULE, earliest - currentTimeMs);
- }
-
- private RecordingTask createRecordingTask(ScheduledRecording schedule) {
- Channel channel = mChannelDataManager.getChannel(schedule.getChannelId());
- RecordingTask recordingTask = mRecordingTaskFactory.createRecordingTask(schedule, channel,
- mDvrManager, mSessionManager, mDataManager, mClock);
- HandlerWrapper handlerWrapper = new HandlerWrapper(mLooper, schedule, recordingTask);
- mPendingRecordings.put(schedule.getId(), handlerWrapper);
- return recordingTask;
- }
-
- private boolean hasTaskWhichFinishEarlier(ScheduledRecording schedule) {
- int size = mPendingRecordings.size();
- for (int i = 0; i < size; ++i) {
- RecordingTask task = mPendingRecordings.get(mPendingRecordings.keyAt(i)).mTask;
- if (task.getEndTimeMs() <= schedule.getStartTimeMs()) {
- return true;
- }
- }
- return false;
- }
-
- private RecordingTask getReplacableTask(ScheduledRecording schedule) {
- // Returns the recording with the following priority.
- // 1. The recording with the lowest priority is returned.
- // 2. If the priorities are the same, the recording which finishes early is returned.
- // 3. If 1) and 2) are the same, the early created schedule is returned.
- int size = mPendingRecordings.size();
- RecordingTask candidate = null;
- for (int i = 0; i < size; ++i) {
- RecordingTask task = mPendingRecordings.get(mPendingRecordings.keyAt(i)).mTask;
- if (schedule.getPriority() > task.getPriority()) {
- if (candidate == null || CANDIDATE_COMPARATOR.compare(candidate, task) > 0) {
- candidate = task;
- }
- }
- }
- return candidate;
- }
-
- private void fail(ScheduledRecording schedule) {
- // It's called when the scheduling has been failed without creating RecordingTask.
- runOnMainHandler(new Runnable() {
- @Override
- public void run() {
- ScheduledRecording scheduleInManager =
- mDataManager.getScheduledRecording(schedule.getId());
- if (scheduleInManager != null) {
- // The schedule should be updated based on the object from DataManager in case
- // when it has been updated.
- mDataManager.changeState(scheduleInManager,
- ScheduledRecording.STATE_RECORDING_FAILED);
- }
- }
- });
- }
-
- private void runOnMainHandler(Runnable runnable) {
- if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
- runnable.run();
- } else {
- mMainThreadHandler.post(runnable);
- }
- }
-
- @VisibleForTesting
- interface RecordingTaskFactory {
- RecordingTask createRecordingTask(ScheduledRecording scheduledRecording, Channel channel,
- DvrManager dvrManager, InputSessionManager sessionManager,
- WritableDvrDataManager dataManager, Clock clock);
- }
-
- private class WorkerThreadHandler extends Handler {
- public WorkerThreadHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_ADD_SCHEDULED_RECORDING:
- handleAddSchedule((ScheduledRecording) msg.obj);
- break;
- case MSG_REMOVE_SCHEDULED_RECORDING:
- handleRemoveSchedule((ScheduledRecording) msg.obj);
- break;
- case MSG_UPDATE_SCHEDULED_RECORDING:
- handleUpdateSchedule((ScheduledRecording) msg.obj);
- case MSG_BUILD_SCHEDULE:
- handleBuildSchedule();
- break;
- case MSG_STOP_SCHEDULE:
- handleStopSchedule();
- break;
- }
- }
- }
-}
diff --git a/src/com/android/tv/dvr/RecordedProgram.java b/src/com/android/tv/dvr/RecordedProgram.java
deleted file mode 100644
index dd744f80..00000000
--- a/src/com/android/tv/dvr/RecordedProgram.java
+++ /dev/null
@@ -1,868 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import static android.media.tv.TvContract.RecordedPrograms;
-
-import android.annotation.TargetApi;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.media.tv.TvContract;
-import android.net.Uri;
-import android.os.Build;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.android.tv.common.R;
-import com.android.tv.data.BaseProgram;
-import com.android.tv.data.GenreItems;
-import com.android.tv.data.InternalDataUtils;
-import com.android.tv.util.Utils;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Objects;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Immutable instance of {@link android.media.tv.TvContract.RecordedPrograms}.
- */
-@TargetApi(Build.VERSION_CODES.N)
-public class RecordedProgram extends BaseProgram {
- public static final int ID_NOT_SET = -1;
-
- public final static String[] PROJECTION = {
- // These are in exactly the order listed in RecordedPrograms
- RecordedPrograms._ID,
- RecordedPrograms.COLUMN_PACKAGE_NAME,
- RecordedPrograms.COLUMN_INPUT_ID,
- RecordedPrograms.COLUMN_CHANNEL_ID,
- RecordedPrograms.COLUMN_TITLE,
- RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER,
- RecordedPrograms.COLUMN_SEASON_TITLE,
- RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER,
- RecordedPrograms.COLUMN_EPISODE_TITLE,
- RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS,
- RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS,
- RecordedPrograms.COLUMN_BROADCAST_GENRE,
- RecordedPrograms.COLUMN_CANONICAL_GENRE,
- RecordedPrograms.COLUMN_SHORT_DESCRIPTION,
- RecordedPrograms.COLUMN_LONG_DESCRIPTION,
- RecordedPrograms.COLUMN_VIDEO_WIDTH,
- RecordedPrograms.COLUMN_VIDEO_HEIGHT,
- RecordedPrograms.COLUMN_AUDIO_LANGUAGE,
- RecordedPrograms.COLUMN_CONTENT_RATING,
- RecordedPrograms.COLUMN_POSTER_ART_URI,
- RecordedPrograms.COLUMN_THUMBNAIL_URI,
- RecordedPrograms.COLUMN_SEARCHABLE,
- RecordedPrograms.COLUMN_RECORDING_DATA_URI,
- RecordedPrograms.COLUMN_RECORDING_DATA_BYTES,
- RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS,
- RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS,
- RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1,
- RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2,
- RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3,
- RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4,
- RecordedPrograms.COLUMN_VERSION_NUMBER,
- RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
- };
-
- public static RecordedProgram fromCursor(Cursor cursor) {
- int index = 0;
- Builder builder = builder()
- .setId(cursor.getLong(index++))
- .setPackageName(cursor.getString(index++))
- .setInputId(cursor.getString(index++))
- .setChannelId(cursor.getLong(index++))
- .setTitle(cursor.getString(index++))
- .setSeasonNumber(cursor.getString(index++))
- .setSeasonTitle(cursor.getString(index++))
- .setEpisodeNumber(cursor.getString(index++))
- .setEpisodeTitle(cursor.getString(index++))
- .setStartTimeUtcMillis(cursor.getLong(index++))
- .setEndTimeUtcMillis(cursor.getLong(index++))
- .setBroadcastGenres(cursor.getString(index++))
- .setCanonicalGenres(cursor.getString(index++))
- .setShortDescription(cursor.getString(index++))
- .setLongDescription(cursor.getString(index++))
- .setVideoWidth(cursor.getInt(index++))
- .setVideoHeight(cursor.getInt(index++))
- .setAudioLanguage(cursor.getString(index++))
- .setContentRating(cursor.getString(index++))
- .setPosterArtUri(cursor.getString(index++))
- .setThumbnailUri(cursor.getString(index++))
- .setSearchable(cursor.getInt(index++) == 1)
- .setDataUri(cursor.getString(index++))
- .setDataBytes(cursor.getLong(index++))
- .setDurationMillis(cursor.getLong(index++))
- .setExpireTimeUtcMillis(cursor.getLong(index++))
- .setInternalProviderFlag1(cursor.getInt(index++))
- .setInternalProviderFlag2(cursor.getInt(index++))
- .setInternalProviderFlag3(cursor.getInt(index++))
- .setInternalProviderFlag4(cursor.getInt(index++))
- .setVersionNumber(cursor.getInt(index++));
- if (Utils.isInBundledPackageSet(builder.mPackageName)) {
- InternalDataUtils.deserializeInternalProviderData(cursor.getBlob(index), builder);
- }
- return builder.build();
- }
-
- public static ContentValues toValues(RecordedProgram recordedProgram) {
- ContentValues values = new ContentValues();
- if (recordedProgram.mId != ID_NOT_SET) {
- values.put(RecordedPrograms._ID, recordedProgram.mId);
- }
- values.put(RecordedPrograms.COLUMN_INPUT_ID, recordedProgram.mInputId);
- values.put(RecordedPrograms.COLUMN_CHANNEL_ID, recordedProgram.mChannelId);
- values.put(RecordedPrograms.COLUMN_TITLE, recordedProgram.mTitle);
- values.put(RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER, recordedProgram.mSeasonNumber);
- values.put(RecordedPrograms.COLUMN_SEASON_TITLE, recordedProgram.mSeasonTitle);
- values.put(RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER, recordedProgram.mEpisodeNumber);
- values.put(RecordedPrograms.COLUMN_EPISODE_TITLE, recordedProgram.mTitle);
- values.put(RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS,
- recordedProgram.mStartTimeUtcMillis);
- values.put(RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS, recordedProgram.mEndTimeUtcMillis);
- values.put(RecordedPrograms.COLUMN_BROADCAST_GENRE,
- safeEncode(recordedProgram.mBroadcastGenres));
- values.put(RecordedPrograms.COLUMN_CANONICAL_GENRE,
- safeEncode(recordedProgram.mCanonicalGenres));
- values.put(RecordedPrograms.COLUMN_SHORT_DESCRIPTION, recordedProgram.mShortDescription);
- values.put(RecordedPrograms.COLUMN_LONG_DESCRIPTION, recordedProgram.mLongDescription);
- if (recordedProgram.mVideoWidth == 0) {
- values.putNull(RecordedPrograms.COLUMN_VIDEO_WIDTH);
- } else {
- values.put(RecordedPrograms.COLUMN_VIDEO_WIDTH, recordedProgram.mVideoWidth);
- }
- if (recordedProgram.mVideoHeight == 0) {
- values.putNull(RecordedPrograms.COLUMN_VIDEO_HEIGHT);
- } else {
- values.put(RecordedPrograms.COLUMN_VIDEO_HEIGHT, recordedProgram.mVideoHeight);
- }
- values.put(RecordedPrograms.COLUMN_AUDIO_LANGUAGE, recordedProgram.mAudioLanguage);
- values.put(RecordedPrograms.COLUMN_CONTENT_RATING, recordedProgram.mContentRating);
- values.put(RecordedPrograms.COLUMN_POSTER_ART_URI, recordedProgram.mPosterArtUri);
- values.put(RecordedPrograms.COLUMN_THUMBNAIL_URI, recordedProgram.mThumbnailUri);
- values.put(RecordedPrograms.COLUMN_SEARCHABLE, recordedProgram.mSearchable ? 1 : 0);
- values.put(RecordedPrograms.COLUMN_RECORDING_DATA_URI,
- safeToString(recordedProgram.mDataUri));
- values.put(RecordedPrograms.COLUMN_RECORDING_DATA_BYTES, recordedProgram.mDataBytes);
- values.put(RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS,
- recordedProgram.mDurationMillis);
- values.put(RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS,
- recordedProgram.mExpireTimeUtcMillis);
- values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
- InternalDataUtils.serializeInternalProviderData(recordedProgram));
- values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1,
- recordedProgram.mInternalProviderFlag1);
- values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2,
- recordedProgram.mInternalProviderFlag2);
- values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3,
- recordedProgram.mInternalProviderFlag3);
- values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4,
- recordedProgram.mInternalProviderFlag4);
- values.put(RecordedPrograms.COLUMN_VERSION_NUMBER, recordedProgram.mVersionNumber);
- return values;
- }
-
- public static class Builder{
- private long mId = ID_NOT_SET;
- private String mPackageName;
- private String mInputId;
- private long mChannelId;
- private String mTitle;
- private String mSeriesId;
- private String mSeasonNumber;
- private String mSeasonTitle;
- private String mEpisodeNumber;
- private String mEpisodeTitle;
- private long mStartTimeUtcMillis;
- private long mEndTimeUtcMillis;
- private String[] mBroadcastGenres;
- private String[] mCanonicalGenres;
- private String mShortDescription;
- private String mLongDescription;
- private int mVideoWidth;
- private int mVideoHeight;
- private String mAudioLanguage;
- private String mContentRating;
- private String mPosterArtUri;
- private String mThumbnailUri;
- private boolean mSearchable = true;
- private Uri mDataUri;
- private long mDataBytes;
- private long mDurationMillis;
- private long mExpireTimeUtcMillis;
- private int mInternalProviderFlag1;
- private int mInternalProviderFlag2;
- private int mInternalProviderFlag3;
- private int mInternalProviderFlag4;
- private int mVersionNumber;
-
- public Builder setId(long id) {
- mId = id;
- return this;
- }
-
- public Builder setPackageName(String packageName) {
- mPackageName = packageName;
- return this;
- }
-
- public Builder setInputId(String inputId) {
- mInputId = inputId;
- return this;
- }
-
- public Builder setChannelId(long channelId) {
- mChannelId = channelId;
- return this;
- }
-
- public Builder setTitle(String title) {
- mTitle = title;
- return this;
- }
-
- public Builder setSeriesId(String seriesId) {
- mSeriesId = seriesId;
- return this;
- }
-
- public Builder setSeasonNumber(String seasonNumber) {
- mSeasonNumber = seasonNumber;
- return this;
- }
-
- public Builder setSeasonTitle(String seasonTitle) {
- mSeasonTitle = seasonTitle;
- return this;
- }
-
- public Builder setEpisodeNumber(String episodeNumber) {
- mEpisodeNumber = episodeNumber;
- return this;
- }
-
- public Builder setEpisodeTitle(String episodeTitle) {
- mEpisodeTitle = episodeTitle;
- return this;
- }
-
- public Builder setStartTimeUtcMillis(long startTimeUtcMillis) {
- mStartTimeUtcMillis = startTimeUtcMillis;
- return this;
- }
-
- public Builder setEndTimeUtcMillis(long endTimeUtcMillis) {
- mEndTimeUtcMillis = endTimeUtcMillis;
- return this;
- }
-
- public Builder setBroadcastGenres(String broadcastGenres) {
- if (TextUtils.isEmpty(broadcastGenres)) {
- mBroadcastGenres = null;
- return this;
- }
- return setBroadcastGenres(TvContract.Programs.Genres.decode(broadcastGenres));
- }
-
- private Builder setBroadcastGenres(String[] broadcastGenres) {
- mBroadcastGenres = broadcastGenres;
- return this;
- }
-
- public Builder setCanonicalGenres(String canonicalGenres) {
- if (TextUtils.isEmpty(canonicalGenres)) {
- mCanonicalGenres = null;
- return this;
- }
- return setCanonicalGenres(TvContract.Programs.Genres.decode(canonicalGenres));
- }
-
- private Builder setCanonicalGenres(String[] canonicalGenres) {
- mCanonicalGenres = canonicalGenres;
- return this;
- }
-
- public Builder setShortDescription(String shortDescription) {
- mShortDescription = shortDescription;
- return this;
- }
-
- public Builder setLongDescription(String longDescription) {
- mLongDescription = longDescription;
- return this;
- }
-
- public Builder setVideoWidth(int videoWidth) {
- mVideoWidth = videoWidth;
- return this;
- }
-
- public Builder setVideoHeight(int videoHeight) {
- mVideoHeight = videoHeight;
- return this;
- }
-
- public Builder setAudioLanguage(String audioLanguage) {
- mAudioLanguage = audioLanguage;
- return this;
- }
-
- public Builder setContentRating(String contentRating) {
- mContentRating = contentRating;
- return this;
- }
-
- private Uri toUri(String uriString) {
- try {
- return uriString == null ? null : Uri.parse(uriString);
- } catch (Exception e) {
- return null;
- }
- }
-
- public Builder setPosterArtUri(String posterArtUri) {
- mPosterArtUri = posterArtUri;
- return this;
- }
-
- public Builder setThumbnailUri(String thumbnailUri) {
- mThumbnailUri = thumbnailUri;
- return this;
- }
-
- public Builder setSearchable(boolean searchable) {
- mSearchable = searchable;
- return this;
- }
-
- public Builder setDataUri(String dataUri) {
- return setDataUri(toUri(dataUri));
- }
-
- public Builder setDataUri(Uri dataUri) {
- mDataUri = dataUri;
- return this;
- }
-
- public Builder setDataBytes(long dataBytes) {
- mDataBytes = dataBytes;
- return this;
- }
-
- public Builder setDurationMillis(long durationMillis) {
- mDurationMillis = durationMillis;
- return this;
- }
-
- public Builder setExpireTimeUtcMillis(long expireTimeUtcMillis) {
- mExpireTimeUtcMillis = expireTimeUtcMillis;
- return this;
- }
-
- public Builder setInternalProviderFlag1(int internalProviderFlag1) {
- mInternalProviderFlag1 = internalProviderFlag1;
- return this;
- }
-
- public Builder setInternalProviderFlag2(int internalProviderFlag2) {
- mInternalProviderFlag2 = internalProviderFlag2;
- return this;
- }
-
- public Builder setInternalProviderFlag3(int internalProviderFlag3) {
- mInternalProviderFlag3 = internalProviderFlag3;
- return this;
- }
-
- public Builder setInternalProviderFlag4(int internalProviderFlag4) {
- mInternalProviderFlag4 = internalProviderFlag4;
- return this;
- }
-
- public Builder setVersionNumber(int versionNumber) {
- mVersionNumber = versionNumber;
- return this;
- }
-
- public RecordedProgram build() {
- // Generate the series ID for the episodic program of other TV input.
- if (TextUtils.isEmpty(mSeriesId)
- && !TextUtils.isEmpty(mEpisodeNumber)) {
- setSeriesId(BaseProgram.generateSeriesId(mPackageName, mTitle));
- }
- return new RecordedProgram(mId, mPackageName, mInputId, mChannelId, mTitle, mSeriesId,
- mSeasonNumber, mSeasonTitle, mEpisodeNumber, mEpisodeTitle, mStartTimeUtcMillis,
- mEndTimeUtcMillis, mBroadcastGenres, mCanonicalGenres, mShortDescription,
- mLongDescription, mVideoWidth, mVideoHeight, mAudioLanguage, mContentRating,
- mPosterArtUri, mThumbnailUri, mSearchable, mDataUri, mDataBytes,
- mDurationMillis, mExpireTimeUtcMillis, mInternalProviderFlag1,
- mInternalProviderFlag2, mInternalProviderFlag3, mInternalProviderFlag4,
- mVersionNumber);
- }
- }
-
- public static Builder builder() { return new Builder(); }
-
- public static Builder buildFrom(RecordedProgram orig) {
- return builder()
- .setId(orig.getId())
- .setPackageName(orig.getPackageName())
- .setInputId(orig.getInputId())
- .setChannelId(orig.getChannelId())
- .setTitle(orig.getTitle())
- .setSeriesId(orig.getSeriesId())
- .setSeasonNumber(orig.getSeasonNumber())
- .setSeasonTitle(orig.getSeasonTitle())
- .setEpisodeNumber(orig.getEpisodeNumber())
- .setEpisodeTitle(orig.getEpisodeTitle())
- .setStartTimeUtcMillis(orig.getStartTimeUtcMillis())
- .setEndTimeUtcMillis(orig.getEndTimeUtcMillis())
- .setBroadcastGenres(orig.getBroadcastGenres())
- .setCanonicalGenres(orig.getCanonicalGenres())
- .setShortDescription(orig.getDescription())
- .setLongDescription(orig.getLongDescription())
- .setVideoWidth(orig.getVideoWidth())
- .setVideoHeight(orig.getVideoHeight())
- .setAudioLanguage(orig.getAudioLanguage())
- .setContentRating(orig.getContentRating())
- .setPosterArtUri(orig.getPosterArtUri())
- .setThumbnailUri(orig.getThumbnailUri())
- .setSearchable(orig.isSearchable())
- .setInternalProviderFlag1(orig.getInternalProviderFlag1())
- .setInternalProviderFlag2(orig.getInternalProviderFlag2())
- .setInternalProviderFlag3(orig.getInternalProviderFlag3())
- .setInternalProviderFlag4(orig.getInternalProviderFlag4())
- .setVersionNumber(orig.getVersionNumber());
- }
-
- public static final Comparator<RecordedProgram> START_TIME_THEN_ID_COMPARATOR =
- new Comparator<RecordedProgram>() {
- @Override
- public int compare(RecordedProgram lhs, RecordedProgram rhs) {
- int res =
- Long.compare(lhs.getStartTimeUtcMillis(), rhs.getStartTimeUtcMillis());
- if (res != 0) {
- return res;
- }
- return Long.compare(lhs.mId, rhs.mId);
- }
- };
-
- private static final long CLIPPED_THRESHOLD_MS = TimeUnit.MINUTES.toMillis(5);
-
- private final long mId;
- private final String mPackageName;
- private final String mInputId;
- private final long mChannelId;
- private final String mTitle;
- private final String mSeriesId;
- private final String mSeasonNumber;
- private final String mSeasonTitle;
- private final String mEpisodeNumber;
- private final String mEpisodeTitle;
- private final long mStartTimeUtcMillis;
- private final long mEndTimeUtcMillis;
- private final String[] mBroadcastGenres;
- private final String[] mCanonicalGenres;
- private final String mShortDescription;
- private final String mLongDescription;
- private final int mVideoWidth;
- private final int mVideoHeight;
- private final String mAudioLanguage;
- private final String mContentRating;
- private final String mPosterArtUri;
- private final String mThumbnailUri;
- private final boolean mSearchable;
- private final Uri mDataUri;
- private final long mDataBytes;
- private final long mDurationMillis;
- private final long mExpireTimeUtcMillis;
- private final int mInternalProviderFlag1;
- private final int mInternalProviderFlag2;
- private final int mInternalProviderFlag3;
- private final int mInternalProviderFlag4;
- private final int mVersionNumber;
-
- private RecordedProgram(long id, String packageName, String inputId, long channelId,
- String title, String seriesId, String seasonNumber, String seasonTitle,
- String episodeNumber, String episodeTitle, long startTimeUtcMillis,
- long endTimeUtcMillis, String[] broadcastGenres, String[] canonicalGenres,
- String shortDescription, String longDescription, int videoWidth, int videoHeight,
- String audioLanguage, String contentRating, String posterArtUri, String thumbnailUri,
- boolean searchable, Uri dataUri, long dataBytes, long durationMillis,
- long expireTimeUtcMillis, int internalProviderFlag1, int internalProviderFlag2,
- int internalProviderFlag3, int internalProviderFlag4, int versionNumber) {
- mId = id;
- mPackageName = packageName;
- mInputId = inputId;
- mChannelId = channelId;
- mTitle = title;
- mSeriesId = seriesId;
- mSeasonNumber = seasonNumber;
- mSeasonTitle = seasonTitle;
- mEpisodeNumber = episodeNumber;
- mEpisodeTitle = episodeTitle;
- mStartTimeUtcMillis = startTimeUtcMillis;
- mEndTimeUtcMillis = endTimeUtcMillis;
- mBroadcastGenres = broadcastGenres;
- mCanonicalGenres = canonicalGenres;
- mShortDescription = shortDescription;
- mLongDescription = longDescription;
- mVideoWidth = videoWidth;
- mVideoHeight = videoHeight;
-
- mAudioLanguage = audioLanguage;
- mContentRating = contentRating;
- mPosterArtUri = posterArtUri;
- mThumbnailUri = thumbnailUri;
- mSearchable = searchable;
- mDataUri = dataUri;
- mDataBytes = dataBytes;
- mDurationMillis = durationMillis;
- mExpireTimeUtcMillis = expireTimeUtcMillis;
- mInternalProviderFlag1 = internalProviderFlag1;
- mInternalProviderFlag2 = internalProviderFlag2;
- mInternalProviderFlag3 = internalProviderFlag3;
- mInternalProviderFlag4 = internalProviderFlag4;
- mVersionNumber = versionNumber;
- }
-
- public String getAudioLanguage() {
- return mAudioLanguage;
- }
-
- public String[] getBroadcastGenres() {
- return mBroadcastGenres;
- }
-
- public String[] getCanonicalGenres() {
- return mCanonicalGenres;
- }
-
- /**
- * Returns array of canonical genre ID's for this recorded program.
- */
- @Override
- public int[] getCanonicalGenreIds() {
- if (mCanonicalGenres == null) {
- return null;
- }
- int[] genreIds = new int[mCanonicalGenres.length];
- for (int i = 0; i < mCanonicalGenres.length; i++) {
- genreIds[i] = GenreItems.getId(mCanonicalGenres[i]);
- }
- return genreIds;
- }
-
- @Override
- public long getChannelId() {
- return mChannelId;
- }
-
- public String getContentRating() {
- return mContentRating;
- }
-
- public Uri getDataUri() {
- return mDataUri;
- }
-
- public long getDataBytes() {
- return mDataBytes;
- }
-
- @Override
- public long getDurationMillis() {
- return mDurationMillis;
- }
-
- @Override
- public long getEndTimeUtcMillis() {
- return mEndTimeUtcMillis;
- }
-
- @Override
- public String getEpisodeNumber() {
- return mEpisodeNumber;
- }
-
- public String getEpisodeTitle() {
- return mEpisodeTitle;
- }
-
- @Override
- public String getEpisodeDisplayTitle(Context context) {
- if (!TextUtils.isEmpty(mEpisodeNumber)) {
- String episodeTitle = mEpisodeTitle == null ? "" : mEpisodeTitle;
- if (TextUtils.equals(mSeasonNumber, "0")) {
- // Do not show "S0: ".
- return String.format(context.getResources().getString(
- R.string.display_episode_title_format_no_season_number),
- mEpisodeNumber, episodeTitle);
- } else {
- return String.format(context.getResources().getString(
- R.string.display_episode_title_format),
- mSeasonNumber, mEpisodeNumber, episodeTitle);
- }
- }
- return mEpisodeTitle;
- }
-
- @Nullable
- @Override
- public String getTitleWithEpisodeNumber(Context context) {
- if (TextUtils.isEmpty(mTitle)) {
- return mTitle;
- }
- if (TextUtils.isEmpty(mSeasonNumber) || mSeasonNumber.equals("0")) {
- return TextUtils.isEmpty(mEpisodeNumber) ? mTitle : context.getString(
- R.string.program_title_with_episode_number_no_season, mTitle, mEpisodeNumber);
- } else {
- return context.getString(R.string.program_title_with_episode_number, mTitle,
- mSeasonNumber, mEpisodeNumber);
- }
- }
-
- @Nullable
- public String getEpisodeDisplayNumber(Context context) {
- if (!TextUtils.isEmpty(mEpisodeNumber)) {
- if (TextUtils.equals(mSeasonNumber, "0")) {
- // Do not show "S0: ".
- return String.format(context.getResources().getString(
- R.string.display_episode_number_format_no_season_number), mEpisodeNumber);
- } else {
- return String.format(context.getResources().getString(
- R.string.display_episode_number_format), mSeasonNumber, mEpisodeNumber);
- }
- }
- return null;
- }
-
- public long getExpireTimeUtcMillis() {
- return mExpireTimeUtcMillis;
- }
-
- public long getId() {
- return mId;
- }
-
- public String getPackageName() {
- return mPackageName;
- }
-
- public String getInputId() {
- return mInputId;
- }
-
- public int getInternalProviderFlag1() {
- return mInternalProviderFlag1;
- }
-
- public int getInternalProviderFlag2() {
- return mInternalProviderFlag2;
- }
-
- public int getInternalProviderFlag3() {
- return mInternalProviderFlag3;
- }
-
- public int getInternalProviderFlag4() {
- return mInternalProviderFlag4;
- }
-
- @Override
- public String getDescription() {
- return mShortDescription;
- }
-
- @Override
- public String getLongDescription() {
- return mLongDescription;
- }
-
- @Override
- public String getPosterArtUri() {
- return mPosterArtUri;
- }
-
- @Override
- public boolean isValid() {
- return true;
- }
-
- public boolean isSearchable() {
- return mSearchable;
- }
-
- @Override
- public String getSeriesId() {
- return mSeriesId;
- }
-
- @Override
- public String getSeasonNumber() {
- return mSeasonNumber;
- }
-
- public String getSeasonTitle() {
- return mSeasonTitle;
- }
-
- @Override
- public long getStartTimeUtcMillis() {
- return mStartTimeUtcMillis;
- }
-
- @Override
- public String getThumbnailUri() {
- return mThumbnailUri;
- }
-
- @Override
- public String getTitle() {
- return mTitle;
- }
-
- public Uri getUri() {
- return ContentUris.withAppendedId(RecordedPrograms.CONTENT_URI, mId);
- }
-
- public int getVersionNumber() {
- return mVersionNumber;
- }
-
- public int getVideoHeight() {
- return mVideoHeight;
- }
-
- public int getVideoWidth() {
- return mVideoWidth;
- }
-
- /**
- * Checks whether the recording has been clipped or not.
- */
- public boolean isClipped() {
- return mEndTimeUtcMillis - mStartTimeUtcMillis - mDurationMillis > CLIPPED_THRESHOLD_MS;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- RecordedProgram that = (RecordedProgram) o;
- return Objects.equals(mId, that.mId) &&
- Objects.equals(mChannelId, that.mChannelId) &&
- Objects.equals(mSeriesId, that.mSeriesId) &&
- Objects.equals(mSeasonNumber, that.mSeasonNumber) &&
- Objects.equals(mSeasonTitle, that.mSeasonTitle) &&
- Objects.equals(mEpisodeNumber, that.mEpisodeNumber) &&
- Objects.equals(mStartTimeUtcMillis, that.mStartTimeUtcMillis) &&
- Objects.equals(mEndTimeUtcMillis, that.mEndTimeUtcMillis) &&
- Objects.equals(mVideoWidth, that.mVideoWidth) &&
- Objects.equals(mVideoHeight, that.mVideoHeight) &&
- Objects.equals(mSearchable, that.mSearchable) &&
- Objects.equals(mDataBytes, that.mDataBytes) &&
- Objects.equals(mDurationMillis, that.mDurationMillis) &&
- Objects.equals(mExpireTimeUtcMillis, that.mExpireTimeUtcMillis) &&
- Objects.equals(mInternalProviderFlag1, that.mInternalProviderFlag1) &&
- Objects.equals(mInternalProviderFlag2, that.mInternalProviderFlag2) &&
- Objects.equals(mInternalProviderFlag3, that.mInternalProviderFlag3) &&
- Objects.equals(mInternalProviderFlag4, that.mInternalProviderFlag4) &&
- Objects.equals(mVersionNumber, that.mVersionNumber) &&
- Objects.equals(mTitle, that.mTitle) &&
- Objects.equals(mEpisodeTitle, that.mEpisodeTitle) &&
- Arrays.equals(mBroadcastGenres, that.mBroadcastGenres) &&
- Arrays.equals(mCanonicalGenres, that.mCanonicalGenres) &&
- Objects.equals(mShortDescription, that.mShortDescription) &&
- Objects.equals(mLongDescription, that.mLongDescription) &&
- Objects.equals(mAudioLanguage, that.mAudioLanguage) &&
- Objects.equals(mContentRating, that.mContentRating) &&
- Objects.equals(mPosterArtUri, that.mPosterArtUri) &&
- Objects.equals(mThumbnailUri, that.mThumbnailUri);
- }
-
- /**
- * Hashes based on the ID.
- */
- @Override
- public int hashCode() {
- return Objects.hash(mId);
- }
-
- @Override
- public String toString() {
- return "RecordedProgram"
- + "[" + mId +
- "]{ mPackageName=" + mPackageName +
- ", mInputId='" + mInputId + '\'' +
- ", mChannelId='" + mChannelId + '\'' +
- ", mTitle='" + mTitle + '\'' +
- ", mSeriesId='" + mSeriesId + '\'' +
- ", mEpisodeNumber=" + mEpisodeNumber +
- ", mEpisodeTitle='" + mEpisodeTitle + '\'' +
- ", mStartTimeUtcMillis=" + mStartTimeUtcMillis +
- ", mEndTimeUtcMillis=" + mEndTimeUtcMillis +
- ", mBroadcastGenres=" +
- (mBroadcastGenres != null ? Arrays.toString(mBroadcastGenres) : "null") +
- ", mCanonicalGenres=" +
- (mCanonicalGenres != null ? Arrays.toString(mCanonicalGenres) : "null") +
- ", mShortDescription='" + mShortDescription + '\'' +
- ", mLongDescription='" + mLongDescription + '\'' +
- ", mVideoHeight=" + mVideoHeight +
- ", mVideoWidth=" + mVideoWidth +
- ", mAudioLanguage='" + mAudioLanguage + '\'' +
- ", mContentRating='" + mContentRating + '\'' +
- ", mPosterArtUri=" + mPosterArtUri +
- ", mThumbnailUri=" + mThumbnailUri +
- ", mSearchable=" + mSearchable +
- ", mDataUri=" + mDataUri +
- ", mDataBytes=" + mDataBytes +
- ", mDurationMillis=" + mDurationMillis +
- ", mExpireTimeUtcMillis=" + mExpireTimeUtcMillis +
- ", mInternalProviderFlag1=" + mInternalProviderFlag1 +
- ", mInternalProviderFlag2=" + mInternalProviderFlag2 +
- ", mInternalProviderFlag3=" + mInternalProviderFlag3 +
- ", mInternalProviderFlag4=" + mInternalProviderFlag4 +
- ", mSeasonNumber=" + mSeasonNumber +
- ", mSeasonTitle=" + mSeasonTitle +
- ", mVersionNumber=" + mVersionNumber +
- '}';
- }
-
- @Nullable
- private static String safeToString(@Nullable Object o) {
- return o == null ? null : o.toString();
- }
-
- @Nullable
- private static String safeEncode(@Nullable String[] genres) {
- return genres == null ? null : TvContract.Programs.Genres.encode(genres);
- }
-
- /**
- * Returns an array containing all of the elements in the list.
- */
- public static RecordedProgram[] toArray(Collection<RecordedProgram> recordedPrograms) {
- return recordedPrograms.toArray(new RecordedProgram[recordedPrograms.size()]);
- }
-}
diff --git a/src/com/android/tv/dvr/RecordingTask.java b/src/com/android/tv/dvr/RecordingTask.java
deleted file mode 100644
index c3d236b0..00000000
--- a/src/com/android/tv/dvr/RecordingTask.java
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.media.tv.TvContract;
-import android.media.tv.TvInputManager;
-import android.media.tv.TvRecordingClient.RecordingCallback;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.support.annotation.VisibleForTesting;
-import android.support.annotation.WorkerThread;
-import android.util.Log;
-import android.widget.Toast;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.InputSessionManager.RecordingSession;
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.Channel;
-import com.android.tv.dvr.InputTaskScheduler.HandlerWrapper;
-import com.android.tv.util.Clock;
-import com.android.tv.util.Utils;
-
-import java.util.Comparator;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A Handler that actually starts and stop a recording at the right time.
- *
- * <p>This is run on the looper of thread named {@value DvrRecordingService#HANDLER_THREAD_NAME}.
- * There is only one looper so messages must be handled quickly or start a separate thread.
- */
-@WorkerThread
-@VisibleForTesting
-@TargetApi(Build.VERSION_CODES.N)
-public class RecordingTask extends RecordingCallback implements Handler.Callback,
- DvrManager.Listener {
- private static final String TAG = "RecordingTask";
- private static final boolean DEBUG = false;
-
- /**
- * Compares the end time in ascending order.
- */
- public static final Comparator<RecordingTask> END_TIME_COMPARATOR
- = new Comparator<RecordingTask>() {
- @Override
- public int compare(RecordingTask lhs, RecordingTask rhs) {
- return Long.compare(lhs.getEndTimeMs(), rhs.getEndTimeMs());
- }
- };
-
- /**
- * Compares ID in ascending order.
- */
- public static final Comparator<RecordingTask> ID_COMPARATOR
- = new Comparator<RecordingTask>() {
- @Override
- public int compare(RecordingTask lhs, RecordingTask rhs) {
- return Long.compare(lhs.getScheduleId(), rhs.getScheduleId());
- }
- };
-
- /**
- * Compares the priority in ascending order.
- */
- public static final Comparator<RecordingTask> PRIORITY_COMPARATOR
- = new Comparator<RecordingTask>() {
- @Override
- public int compare(RecordingTask lhs, RecordingTask rhs) {
- return Long.compare(lhs.getPriority(), rhs.getPriority());
- }
- };
-
- @VisibleForTesting
- static final int MSG_INITIALIZE = 1;
- @VisibleForTesting
- static final int MSG_START_RECORDING = 2;
- @VisibleForTesting
- static final int MSG_STOP_RECORDING = 3;
- /**
- * Message to update schedule.
- */
- public static final int MSG_UDPATE_SCHEDULE = 4;
-
- /**
- * The time when the start command will be sent before the recording starts.
- */
- public static final long RECORDING_EARLY_START_OFFSET_MS = TimeUnit.SECONDS.toMillis(3);
- /**
- * If the recording starts later than the scheduled start time or ends before the scheduled end
- * time, it's considered as clipped.
- */
- private static final long CLIPPED_THRESHOLD_MS = TimeUnit.MINUTES.toMillis(5);
-
- @VisibleForTesting
- enum State {
- NOT_STARTED,
- SESSION_ACQUIRED,
- CONNECTION_PENDING,
- CONNECTED,
- RECORDING_STARTED,
- RECORDING_STOP_REQUESTED,
- FINISHED,
- ERROR,
- RELEASED,
- }
- private final InputSessionManager mSessionManager;
- private final DvrManager mDvrManager;
- private final Context mContext;
-
- private final WritableDvrDataManager mDataManager;
- private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
- private RecordingSession mRecordingSession;
- private Handler mHandler;
- private ScheduledRecording mScheduledRecording;
- private final Channel mChannel;
- private State mState = State.NOT_STARTED;
- private final Clock mClock;
- private boolean mStartedWithClipping;
- private Uri mRecordedProgramUri;
- private boolean mCanceled;
-
- RecordingTask(Context context, ScheduledRecording scheduledRecording, Channel channel,
- DvrManager dvrManager, InputSessionManager sessionManager,
- WritableDvrDataManager dataManager, Clock clock) {
- mContext = context;
- mScheduledRecording = scheduledRecording;
- mChannel = channel;
- mSessionManager = sessionManager;
- mDataManager = dataManager;
- mClock = clock;
- mDvrManager = dvrManager;
-
- if (DEBUG) Log.d(TAG, "created recording task " + mScheduledRecording);
- }
-
- public void setHandler(Handler handler) {
- mHandler = handler;
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- if (DEBUG) Log.d(TAG, "handleMessage " + msg);
- SoftPreconditions.checkState(msg.what == HandlerWrapper.MESSAGE_REMOVE || mHandler != null,
- TAG, "Null handler trying to handle " + msg);
- try {
- switch (msg.what) {
- case MSG_INITIALIZE:
- handleInit();
- break;
- case MSG_START_RECORDING:
- handleStartRecording();
- break;
- case MSG_STOP_RECORDING:
- handleStopRecording();
- break;
- case MSG_UDPATE_SCHEDULE:
- handleUpdateSchedule((ScheduledRecording) msg.obj);
- break;
- case HandlerWrapper.MESSAGE_REMOVE:
- mHandler.removeCallbacksAndMessages(null);
- mHandler = null;
- release();
- return false;
- default:
- SoftPreconditions.checkArgument(false, TAG, "unexpected message type " + msg);
- break;
- }
- return true;
- } catch (Exception e) {
- Log.w(TAG, "Error processing message " + msg + " for " + mScheduledRecording, e);
- failAndQuit();
- }
- return false;
- }
-
- @Override
- public void onDisconnected(String inputId) {
- if (DEBUG) Log.d(TAG, "onDisconnected(" + inputId + ")");
- if (mRecordingSession != null && mState != State.FINISHED) {
- failAndQuit();
- }
- }
-
- @Override
- public void onConnectionFailed(String inputId) {
- if (DEBUG) Log.d(TAG, "onConnectionFailed(" + inputId + ")");
- if (mRecordingSession != null) {
- failAndQuit();
- }
- }
-
- @Override
- public void onTuned(Uri channelUri) {
- if (DEBUG) Log.d(TAG, "onTuned");
- if (mRecordingSession == null) {
- return;
- }
- mState = State.CONNECTED;
- if (mHandler == null || !sendEmptyMessageAtAbsoluteTime(MSG_START_RECORDING,
- mScheduledRecording.getStartTimeMs() - RECORDING_EARLY_START_OFFSET_MS)) {
- failAndQuit();
- }
- }
-
- @Override
- public void onRecordingStopped(Uri recordedProgramUri) {
- if (DEBUG) Log.d(TAG, "onRecordingStopped");
- if (mRecordingSession == null) {
- return;
- }
- mRecordedProgramUri = recordedProgramUri;
- mState = State.FINISHED;
- int state = ScheduledRecording.STATE_RECORDING_FINISHED;
- if (mStartedWithClipping || mScheduledRecording.getEndTimeMs() - CLIPPED_THRESHOLD_MS
- > mClock.currentTimeMillis()) {
- state = ScheduledRecording.STATE_RECORDING_CLIPPED;
- }
- updateRecordingState(state);
- sendRemove();
- if (mCanceled) {
- removeRecordedProgram();
- }
- }
-
- @Override
- public void onError(int reason) {
- if (DEBUG) Log.d(TAG, "onError reason " + reason);
- if (mRecordingSession == null) {
- return;
- }
- switch (reason) {
- case TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE:
- mMainThreadHandler.post(new Runnable() {
- @Override
- public void run() {
- if (TvApplication.getSingletons(mContext).getMainActivityWrapper()
- .isResumed()) {
- Toast.makeText(mContext.getApplicationContext(),
- R.string.dvr_error_insufficient_space_description,
- Toast.LENGTH_LONG)
- .show();
- } else {
- Utils.setRecordingFailedReason(mContext.getApplicationContext(),
- TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE);
- }
- }
- });
- // Pass through
- default:
- failAndQuit();
- break;
- }
- }
-
- private void handleInit() {
- if (DEBUG) Log.d(TAG, "handleInit " + mScheduledRecording);
- if (mScheduledRecording.getEndTimeMs() < mClock.currentTimeMillis()) {
- Log.w(TAG, "End time already past, not recording " + mScheduledRecording);
- failAndQuit();
- return;
- }
- if (mChannel == null) {
- Log.w(TAG, "Null channel for " + mScheduledRecording);
- failAndQuit();
- return;
- }
- if (mChannel.getId() != mScheduledRecording.getChannelId()) {
- Log.w(TAG, "Channel" + mChannel + " does not match scheduled recording "
- + mScheduledRecording);
- failAndQuit();
- return;
- }
-
- String inputId = mChannel.getInputId();
- mRecordingSession = mSessionManager.createRecordingSession(inputId,
- "recordingTask-" + mScheduledRecording.getId(), this,
- mHandler, mScheduledRecording.getEndTimeMs());
- mState = State.SESSION_ACQUIRED;
- mDvrManager.addListener(this, mHandler);
- mRecordingSession.tune(inputId, mChannel.getUri());
- mState = State.CONNECTION_PENDING;
- }
-
- private void failAndQuit() {
- if (DEBUG) Log.d(TAG, "failAndQuit");
- updateRecordingState(ScheduledRecording.STATE_RECORDING_FAILED);
- mState = State.ERROR;
- sendRemove();
- }
-
- private void sendRemove() {
- if (DEBUG) Log.d(TAG, "sendRemove");
- if (mHandler != null) {
- mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(
- HandlerWrapper.MESSAGE_REMOVE));
- }
- }
-
- private void handleStartRecording() {
- if (DEBUG) Log.d(TAG, "handleStartRecording " + mScheduledRecording);
- long programId = mScheduledRecording.getProgramId();
- mRecordingSession.startRecording(programId == ScheduledRecording.ID_NOT_SET ? null
- : TvContract.buildProgramUri(programId));
- updateRecordingState(ScheduledRecording.STATE_RECORDING_IN_PROGRESS);
- // If it starts late, it's clipped.
- if (mScheduledRecording.getStartTimeMs() + CLIPPED_THRESHOLD_MS
- < mClock.currentTimeMillis()) {
- mStartedWithClipping = true;
- }
- mState = State.RECORDING_STARTED;
-
- if (!sendEmptyMessageAtAbsoluteTime(MSG_STOP_RECORDING,
- mScheduledRecording.getEndTimeMs())) {
- failAndQuit();
- }
- }
-
- private void handleStopRecording() {
- if (DEBUG) Log.d(TAG, "handleStopRecording " + mScheduledRecording);
- mRecordingSession.stopRecording();
- mState = State.RECORDING_STOP_REQUESTED;
- }
-
- private void handleUpdateSchedule(ScheduledRecording schedule) {
- mScheduledRecording = schedule;
- // Check end time only. The start time is checked in InputTaskScheduler.
- if (schedule.getEndTimeMs() != mScheduledRecording.getEndTimeMs()) {
- if (mRecordingSession != null) {
- mRecordingSession.setEndTimeMs(schedule.getEndTimeMs());
- }
- if (mState == State.RECORDING_STARTED) {
- mHandler.removeMessages(MSG_STOP_RECORDING);
- if (!sendEmptyMessageAtAbsoluteTime(MSG_STOP_RECORDING, schedule.getEndTimeMs())) {
- failAndQuit();
- }
- }
- }
- }
-
- @VisibleForTesting
- State getState() {
- return mState;
- }
-
- private long getScheduleId() {
- return mScheduledRecording.getId();
- }
-
- /**
- * Returns the priority.
- */
- public long getPriority() {
- return mScheduledRecording.getPriority();
- }
-
- /**
- * Returns the start time of the recording.
- */
- public long getStartTimeMs() {
- return mScheduledRecording.getStartTimeMs();
- }
-
- /**
- * Returns the end time of the recording.
- */
- public long getEndTimeMs() {
- return mScheduledRecording.getEndTimeMs();
- }
-
- private void release() {
- if (mRecordingSession != null) {
- mSessionManager.releaseRecordingSession(mRecordingSession);
- mRecordingSession = null;
- }
- mDvrManager.removeListener(this);
- }
-
- private boolean sendEmptyMessageAtAbsoluteTime(int what, long when) {
- long now = mClock.currentTimeMillis();
- long delay = Math.max(0L, when - now);
- if (DEBUG) {
- Log.d(TAG, "Sending message " + what + " with a delay of " + delay / 1000
- + " seconds to arrive at " + Utils.toIsoDateTimeString(when));
- }
- return mHandler.sendEmptyMessageDelayed(what, delay);
- }
-
- private void updateRecordingState(@ScheduledRecording.RecordingState int state) {
- if (DEBUG) Log.d(TAG, "Updating the state of " + mScheduledRecording + " to " + state);
- mScheduledRecording = ScheduledRecording.buildFrom(mScheduledRecording).setState(state)
- .build();
- runOnMainThread(new Runnable() {
- @Override
- public void run() {
- ScheduledRecording schedule = mDataManager.getScheduledRecording(
- mScheduledRecording.getId());
- if (schedule == null) {
- // Schedule has been deleted. Delete the recorded program.
- removeRecordedProgram();
- } else {
- // Update the state based on the object in DataManager in case when it has been
- // updated. mScheduledRecording will be updated from
- // onScheduledRecordingStateChanged.
- mDataManager.updateScheduledRecording(ScheduledRecording.buildFrom(schedule)
- .setState(state).build());
- }
- }
- });
- }
-
- @Override
- public void onStopRecordingRequested(ScheduledRecording recording) {
- if (recording.getId() != mScheduledRecording.getId()) {
- return;
- }
- stop();
- }
-
- /**
- * Starts the task.
- */
- public void start() {
- mHandler.sendEmptyMessage(MSG_INITIALIZE);
- }
-
- /**
- * Stops the task.
- */
- public void stop() {
- if (DEBUG) Log.d(TAG, "stop");
- switch (mState) {
- case RECORDING_STARTED:
- mHandler.removeMessages(MSG_STOP_RECORDING);
- handleStopRecording();
- break;
- case RECORDING_STOP_REQUESTED:
- // Do nothing
- break;
- case NOT_STARTED:
- case SESSION_ACQUIRED:
- case CONNECTION_PENDING:
- case CONNECTED:
- case FINISHED:
- case ERROR:
- case RELEASED:
- default:
- sendRemove();
- break;
- }
- }
-
- /**
- * Cancels the task
- */
- public void cancel() {
- if (DEBUG) Log.d(TAG, "cancel");
- mCanceled = true;
- stop();
- removeRecordedProgram();
- }
-
- /**
- * Clean up the task.
- */
- public void cleanUp() {
- if (mState == State.RECORDING_STARTED || mState == State.RECORDING_STOP_REQUESTED) {
- updateRecordingState(ScheduledRecording.STATE_RECORDING_FAILED);
- }
- release();
- if (mHandler != null) {
- mHandler.removeCallbacksAndMessages(null);
- }
- }
-
- @Override
- public String toString() {
- return getClass().getName() + "(" + mScheduledRecording + ")";
- }
-
- private void removeRecordedProgram() {
- runOnMainThread(new Runnable() {
- @Override
- public void run() {
- if (mRecordedProgramUri != null) {
- mDvrManager.removeRecordedProgram(mRecordedProgramUri);
- }
- }
- });
- }
-
- private void runOnMainThread(Runnable runnable) {
- if (Looper.myLooper() == Looper.getMainLooper()) {
- runnable.run();
- } else {
- mMainThreadHandler.post(runnable);
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ScheduledProgramReaper.java b/src/com/android/tv/dvr/ScheduledProgramReaper.java
deleted file mode 100644
index cd79a631..00000000
--- a/src/com/android/tv/dvr/ScheduledProgramReaper.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.support.annotation.MainThread;
-import android.support.annotation.VisibleForTesting;
-
-import com.android.tv.util.Clock;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Deletes {@link ScheduledRecording} older than {@value @DAYS} days.
- */
-class ScheduledProgramReaper implements Runnable {
-
- @VisibleForTesting
- static final int DAYS = 2;
- private final WritableDvrDataManager mDvrDataManager;
- private final Clock mClock;
-
- ScheduledProgramReaper(WritableDvrDataManager dvrDataManager, Clock clock) {
- mDvrDataManager = dvrDataManager;
- mClock = clock;
- }
-
- @Override
- @MainThread
- public void run() {
- long cutoff = mClock.currentTimeMillis() - TimeUnit.DAYS.toMillis(DAYS);
- List<ScheduledRecording> toRemove = new ArrayList<>();
- for (ScheduledRecording r : mDvrDataManager.getAllScheduledRecordings()) {
- // Do not remove the schedules if it belongs to the series recording and was finished
- // successfully. The schedule is necessary for checking the scheduled episode of the
- // series recording.
- if (r.getEndTimeMs() < cutoff
- && (r.getSeriesRecordingId() == SeriesRecording.ID_NOT_SET
- || r.getState() != ScheduledRecording.STATE_RECORDING_FINISHED)) {
- toRemove.add(r);
- }
- }
- for (ScheduledRecording r : mDvrDataManager.getDeletedSchedules()) {
- if (r.getEndTimeMs() < cutoff) {
- toRemove.add(r);
- }
- }
- if (!toRemove.isEmpty()) {
- mDvrDataManager.removeScheduledRecording(ScheduledRecording.toArray(toRemove));
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ScheduledRecording.java b/src/com/android/tv/dvr/ScheduledRecording.java
deleted file mode 100644
index 2bda10ea..00000000
--- a/src/com/android/tv/dvr/ScheduledRecording.java
+++ /dev/null
@@ -1,887 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.support.annotation.IntDef;
-import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
-import android.util.Range;
-
-import com.android.tv.R;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.Channel;
-import com.android.tv.data.Program;
-import com.android.tv.dvr.provider.DvrContract.Schedules;
-import com.android.tv.util.CompositeComparator;
-import com.android.tv.util.Utils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Objects;
-
-/**
- * A data class for one recording contents.
- */
-@VisibleForTesting
-public final class ScheduledRecording implements Parcelable {
- private static final String TAG = "ScheduledRecording";
-
- /**
- * Indicates that the ID is not assigned yet.
- */
- public static final long ID_NOT_SET = 0;
-
- /**
- * The default priority of the recording.
- */
- public static final long DEFAULT_PRIORITY = Long.MAX_VALUE >> 1;
-
- /**
- * Compares the start time in ascending order.
- */
- public static final Comparator<ScheduledRecording> START_TIME_COMPARATOR
- = new Comparator<ScheduledRecording>() {
- @Override
- public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
- return Long.compare(lhs.mStartTimeMs, rhs.mStartTimeMs);
- }
- };
-
- /**
- * Compares the end time in ascending order.
- */
- public static final Comparator<ScheduledRecording> END_TIME_COMPARATOR
- = new Comparator<ScheduledRecording>() {
- @Override
- public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
- return Long.compare(lhs.mEndTimeMs, rhs.mEndTimeMs);
- }
- };
-
- /**
- * Compares ID in ascending order. The schedule with the larger ID was created later.
- */
- public static final Comparator<ScheduledRecording> ID_COMPARATOR
- = new Comparator<ScheduledRecording>() {
- @Override
- public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
- return Long.compare(lhs.mId, rhs.mId);
- }
- };
-
- /**
- * Compares the priority in ascending order.
- */
- public static final Comparator<ScheduledRecording> PRIORITY_COMPARATOR
- = new Comparator<ScheduledRecording>() {
- @Override
- public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
- return Long.compare(lhs.mPriority, rhs.mPriority);
- }
- };
-
- /**
- * Compares start time in ascending order and then priority in descending order and then ID in
- * descending order.
- */
- public static final Comparator<ScheduledRecording> START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR
- = new CompositeComparator<>(START_TIME_COMPARATOR, PRIORITY_COMPARATOR.reversed(),
- ID_COMPARATOR.reversed());
-
- /**
- * Builds scheduled recordings from programs.
- */
- public static Builder builder(String inputId, Program p) {
- return new Builder()
- .setInputId(inputId)
- .setChannelId(p.getChannelId())
- .setStartTimeMs(p.getStartTimeUtcMillis()).setEndTimeMs(p.getEndTimeUtcMillis())
- .setProgramId(p.getId())
- .setProgramTitle(p.getTitle())
- .setSeasonNumber(p.getSeasonNumber())
- .setEpisodeNumber(p.getEpisodeNumber())
- .setEpisodeTitle(p.getEpisodeTitle())
- .setProgramDescription(p.getDescription())
- .setProgramLongDescription(p.getLongDescription())
- .setProgramPosterArtUri(p.getPosterArtUri())
- .setProgramThumbnailUri(p.getThumbnailUri())
- .setType(TYPE_PROGRAM);
- }
-
- public static Builder builder(String inputId, long channelId, long startTime, long endTime) {
- return new Builder()
- .setInputId(inputId)
- .setChannelId(channelId)
- .setStartTimeMs(startTime)
- .setEndTimeMs(endTime)
- .setType(TYPE_TIMED);
- }
-
- /**
- * Creates a new Builder with the values set from the {@link RecordedProgram}.
- */
- @VisibleForTesting
- public static Builder builder(RecordedProgram p) {
- boolean isProgramRecording = !TextUtils.isEmpty(p.getTitle());
- return new Builder()
- .setInputId(p.getInputId())
- .setChannelId(p.getChannelId())
- .setType(isProgramRecording ? TYPE_PROGRAM : TYPE_TIMED)
- .setStartTimeMs(p.getStartTimeUtcMillis())
- .setEndTimeMs(p.getEndTimeUtcMillis())
- .setProgramTitle(p.getTitle())
- .setSeasonNumber(p.getSeasonNumber())
- .setEpisodeNumber(p.getEpisodeNumber())
- .setEpisodeTitle(p.getEpisodeTitle())
- .setProgramDescription(p.getDescription())
- .setProgramLongDescription(p.getLongDescription())
- .setProgramPosterArtUri(p.getPosterArtUri())
- .setProgramThumbnailUri(p.getThumbnailUri())
- .setState(STATE_RECORDING_FINISHED);
- }
-
- public static final class Builder {
- private long mId = ID_NOT_SET;
- private long mPriority = DvrScheduleManager.DEFAULT_PRIORITY;
- private String mInputId;
- private long mChannelId;
- private long mProgramId = ID_NOT_SET;
- private String mProgramTitle;
- private @RecordingType int mType;
- private long mStartTimeMs;
- private long mEndTimeMs;
- private String mSeasonNumber;
- private String mEpisodeNumber;
- private String mEpisodeTitle;
- private String mProgramDescription;
- private String mProgramLongDescription;
- private String mProgramPosterArtUri;
- private String mProgramThumbnailUri;
- private @RecordingState int mState;
- private long mSeriesRecordingId = ID_NOT_SET;
-
- private Builder() { }
-
- public Builder setId(long id) {
- mId = id;
- return this;
- }
-
- public Builder setPriority(long priority) {
- mPriority = priority;
- return this;
- }
-
- public Builder setInputId(String inputId) {
- mInputId = inputId;
- return this;
- }
-
- public Builder setChannelId(long channelId) {
- mChannelId = channelId;
- return this;
- }
-
- public Builder setProgramId(long programId) {
- mProgramId = programId;
- return this;
- }
-
- public Builder setProgramTitle(String programTitle) {
- mProgramTitle = programTitle;
- return this;
- }
-
- private Builder setType(@RecordingType int type) {
- mType = type;
- return this;
- }
-
- public Builder setStartTimeMs(long startTimeMs) {
- mStartTimeMs = startTimeMs;
- return this;
- }
-
- public Builder setEndTimeMs(long endTimeMs) {
- mEndTimeMs = endTimeMs;
- return this;
- }
-
- public Builder setSeasonNumber(String seasonNumber) {
- mSeasonNumber = seasonNumber;
- return this;
- }
-
- public Builder setEpisodeNumber(String episodeNumber) {
- mEpisodeNumber = episodeNumber;
- return this;
- }
-
- public Builder setEpisodeTitle(String episodeTitle) {
- mEpisodeTitle = episodeTitle;
- return this;
- }
-
- public Builder setProgramDescription(String description) {
- mProgramDescription = description;
- return this;
- }
-
- public Builder setProgramLongDescription(String longDescription) {
- mProgramLongDescription = longDescription;
- return this;
- }
-
- public Builder setProgramPosterArtUri(String programPosterArtUri) {
- mProgramPosterArtUri = programPosterArtUri;
- return this;
- }
-
- public Builder setProgramThumbnailUri(String programThumbnailUri) {
- mProgramThumbnailUri = programThumbnailUri;
- return this;
- }
-
- public Builder setState(@RecordingState int state) {
- mState = state;
- return this;
- }
-
- public Builder setSeriesRecordingId(long seriesRecordingId) {
- mSeriesRecordingId = seriesRecordingId;
- return this;
- }
-
- public ScheduledRecording build() {
- return new ScheduledRecording(mId, mPriority, mInputId, mChannelId, mProgramId,
- mProgramTitle, mType, mStartTimeMs, mEndTimeMs, mSeasonNumber, mEpisodeNumber,
- mEpisodeTitle, mProgramDescription, mProgramLongDescription,
- mProgramPosterArtUri, mProgramThumbnailUri, mState, mSeriesRecordingId);
- }
- }
-
- /**
- * Creates {@link Builder} object from the given original {@code Recording}.
- */
- public static Builder buildFrom(ScheduledRecording orig) {
- return new Builder()
- .setId(orig.mId)
- .setInputId(orig.mInputId)
- .setChannelId(orig.mChannelId)
- .setEndTimeMs(orig.mEndTimeMs)
- .setSeriesRecordingId(orig.mSeriesRecordingId)
- .setPriority(orig.mPriority)
- .setProgramId(orig.mProgramId)
- .setProgramTitle(orig.mProgramTitle)
- .setStartTimeMs(orig.mStartTimeMs)
- .setSeasonNumber(orig.getSeasonNumber())
- .setEpisodeNumber(orig.getEpisodeNumber())
- .setEpisodeTitle(orig.getEpisodeTitle())
- .setProgramDescription(orig.getProgramDescription())
- .setProgramLongDescription(orig.getProgramLongDescription())
- .setProgramPosterArtUri(orig.getProgramPosterArtUri())
- .setProgramThumbnailUri(orig.getProgramThumbnailUri())
- .setState(orig.mState).setType(orig.mType);
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({STATE_RECORDING_NOT_STARTED, STATE_RECORDING_IN_PROGRESS, STATE_RECORDING_FINISHED,
- STATE_RECORDING_FAILED, STATE_RECORDING_CLIPPED, STATE_RECORDING_DELETED,
- STATE_RECORDING_CANCELED})
- public @interface RecordingState {}
- public static final int STATE_RECORDING_NOT_STARTED = 0;
- public static final int STATE_RECORDING_IN_PROGRESS = 1;
- public static final int STATE_RECORDING_FINISHED = 2;
- public static final int STATE_RECORDING_FAILED = 3;
- public static final int STATE_RECORDING_CLIPPED = 4;
- public static final int STATE_RECORDING_DELETED = 5;
- public static final int STATE_RECORDING_CANCELED = 6;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({TYPE_TIMED, TYPE_PROGRAM})
- public @interface RecordingType {}
- /**
- * Record with given time range.
- */
- public static final int TYPE_TIMED = 1;
- /**
- * Record with a given program.
- */
- public static final int TYPE_PROGRAM = 2;
-
- @RecordingType private final int mType;
-
- /**
- * Use this projection if you want to create {@link ScheduledRecording} object using
- * {@link #fromCursor}.
- */
- public static final String[] PROJECTION = {
- // Columns must match what is read in #fromCursor
- Schedules._ID,
- Schedules.COLUMN_PRIORITY,
- Schedules.COLUMN_TYPE,
- Schedules.COLUMN_INPUT_ID,
- Schedules.COLUMN_CHANNEL_ID,
- Schedules.COLUMN_PROGRAM_ID,
- Schedules.COLUMN_PROGRAM_TITLE,
- Schedules.COLUMN_START_TIME_UTC_MILLIS,
- Schedules.COLUMN_END_TIME_UTC_MILLIS,
- Schedules.COLUMN_SEASON_NUMBER,
- Schedules.COLUMN_EPISODE_NUMBER,
- Schedules.COLUMN_EPISODE_TITLE,
- Schedules.COLUMN_PROGRAM_DESCRIPTION,
- Schedules.COLUMN_PROGRAM_LONG_DESCRIPTION,
- Schedules.COLUMN_PROGRAM_POST_ART_URI,
- Schedules.COLUMN_PROGRAM_THUMBNAIL_URI,
- Schedules.COLUMN_STATE,
- Schedules.COLUMN_SERIES_RECORDING_ID};
-
- /**
- * Creates {@link ScheduledRecording} object from the given {@link Cursor}.
- */
- public static ScheduledRecording fromCursor(Cursor c) {
- int index = -1;
- return new Builder()
- .setId(c.getLong(++index))
- .setPriority(c.getLong(++index))
- .setType(recordingType(c.getString(++index)))
- .setInputId(c.getString(++index))
- .setChannelId(c.getLong(++index))
- .setProgramId(c.getLong(++index))
- .setProgramTitle(c.getString(++index))
- .setStartTimeMs(c.getLong(++index))
- .setEndTimeMs(c.getLong(++index))
- .setSeasonNumber(c.getString(++index))
- .setEpisodeNumber(c.getString(++index))
- .setEpisodeTitle(c.getString(++index))
- .setProgramDescription(c.getString(++index))
- .setProgramLongDescription(c.getString(++index))
- .setProgramPosterArtUri(c.getString(++index))
- .setProgramThumbnailUri(c.getString(++index))
- .setState(recordingState(c.getString(++index)))
- .setSeriesRecordingId(c.getLong(++index))
- .build();
- }
-
- public static ContentValues toContentValues(ScheduledRecording r) {
- ContentValues values = new ContentValues();
- if (r.getId() != ID_NOT_SET) {
- values.put(Schedules._ID, r.getId());
- }
- values.put(Schedules.COLUMN_INPUT_ID, r.getInputId());
- values.put(Schedules.COLUMN_CHANNEL_ID, r.getChannelId());
- values.put(Schedules.COLUMN_PROGRAM_ID, r.getProgramId());
- values.put(Schedules.COLUMN_PROGRAM_TITLE, r.getProgramTitle());
- values.put(Schedules.COLUMN_PRIORITY, r.getPriority());
- values.put(Schedules.COLUMN_START_TIME_UTC_MILLIS, r.getStartTimeMs());
- values.put(Schedules.COLUMN_END_TIME_UTC_MILLIS, r.getEndTimeMs());
- values.put(Schedules.COLUMN_SEASON_NUMBER, r.getSeasonNumber());
- values.put(Schedules.COLUMN_EPISODE_NUMBER, r.getEpisodeNumber());
- values.put(Schedules.COLUMN_EPISODE_TITLE, r.getEpisodeTitle());
- values.put(Schedules.COLUMN_PROGRAM_DESCRIPTION, r.getProgramDescription());
- values.put(Schedules.COLUMN_PROGRAM_LONG_DESCRIPTION, r.getProgramLongDescription());
- values.put(Schedules.COLUMN_PROGRAM_POST_ART_URI, r.getProgramPosterArtUri());
- values.put(Schedules.COLUMN_PROGRAM_THUMBNAIL_URI, r.getProgramThumbnailUri());
- values.put(Schedules.COLUMN_STATE, recordingState(r.getState()));
- values.put(Schedules.COLUMN_TYPE, recordingType(r.getType()));
- if (r.getSeriesRecordingId() != ID_NOT_SET) {
- values.put(Schedules.COLUMN_SERIES_RECORDING_ID, r.getSeriesRecordingId());
- } else {
- values.putNull(Schedules.COLUMN_SERIES_RECORDING_ID);
- }
- return values;
- }
-
- public static ScheduledRecording fromParcel(Parcel in) {
- return new Builder()
- .setId(in.readLong())
- .setPriority(in.readLong())
- .setInputId(in.readString())
- .setChannelId(in.readLong())
- .setProgramId(in.readLong())
- .setProgramTitle(in.readString())
- .setType(in.readInt())
- .setStartTimeMs(in.readLong())
- .setEndTimeMs(in.readLong())
- .setSeasonNumber(in.readString())
- .setEpisodeNumber(in.readString())
- .setEpisodeTitle(in.readString())
- .setProgramDescription(in.readString())
- .setProgramLongDescription(in.readString())
- .setProgramPosterArtUri(in.readString())
- .setProgramThumbnailUri(in.readString())
- .setState(in.readInt())
- .setSeriesRecordingId(in.readLong())
- .build();
- }
-
- public static final Parcelable.Creator<ScheduledRecording> CREATOR =
- new Parcelable.Creator<ScheduledRecording>() {
- @Override
- public ScheduledRecording createFromParcel(Parcel in) {
- return ScheduledRecording.fromParcel(in);
- }
-
- @Override
- public ScheduledRecording[] newArray(int size) {
- return new ScheduledRecording[size];
- }
- };
-
- /**
- * The ID internal to Live TV
- */
- private long mId;
-
- /**
- * The priority of this recording.
- *
- * <p> The highest number is recorded first. If there is a tie in priority then the higher id
- * wins.
- */
- private final long mPriority;
-
- private final String mInputId;
- private final long mChannelId;
- /**
- * Optional id of the associated program.
- */
- private final long mProgramId;
- private final String mProgramTitle;
-
- private final long mStartTimeMs;
- private final long mEndTimeMs;
- private final String mSeasonNumber;
- private final String mEpisodeNumber;
- private final String mEpisodeTitle;
- private final String mProgramDescription;
- private final String mProgramLongDescription;
- private final String mProgramPosterArtUri;
- private final String mProgramThumbnailUri;
- @RecordingState private final int mState;
- private final long mSeriesRecordingId;
-
- private ScheduledRecording(long id, long priority, String inputId, long channelId, long programId,
- String programTitle, @RecordingType int type, long startTime, long endTime,
- String seasonNumber, String episodeNumber, String episodeTitle,
- String programDescription, String programLongDescription, String programPosterArtUri,
- String programThumbnailUri, @RecordingState int state, long seriesRecordingId) {
- mId = id;
- mPriority = priority;
- mInputId = inputId;
- mChannelId = channelId;
- mProgramId = programId;
- mProgramTitle = programTitle;
- mType = type;
- mStartTimeMs = startTime;
- mEndTimeMs = endTime;
- mSeasonNumber = seasonNumber;
- mEpisodeNumber = episodeNumber;
- mEpisodeTitle = episodeTitle;
- mProgramDescription = programDescription;
- mProgramLongDescription = programLongDescription;
- mProgramPosterArtUri = programPosterArtUri;
- mProgramThumbnailUri = programThumbnailUri;
- mState = state;
- mSeriesRecordingId = seriesRecordingId;
- }
-
- /**
- * Returns recording schedule type. The possible types are {@link #TYPE_PROGRAM} and
- * {@link #TYPE_TIMED}.
- */
- @RecordingType
- public int getType() {
- return mType;
- }
-
- /**
- * Returns schedules' input id.
- */
- public String getInputId() {
- return mInputId;
- }
-
- /**
- * Returns recorded {@link Channel}.
- */
- public long getChannelId() {
- return mChannelId;
- }
-
- /**
- * Return the optional program id
- */
- public long getProgramId() {
- return mProgramId;
- }
-
- /**
- * Return the optional program Title
- */
- public String getProgramTitle() {
- return mProgramTitle;
- }
-
- /**
- * Returns started time.
- */
- public long getStartTimeMs() {
- return mStartTimeMs;
- }
-
- /**
- * Returns ended time.
- */
- public long getEndTimeMs() {
- return mEndTimeMs;
- }
-
- /**
- * Returns the season number.
- */
- public String getSeasonNumber() {
- return mSeasonNumber;
- }
-
- /**
- * Returns the episode number.
- */
- public String getEpisodeNumber() {
- return mEpisodeNumber;
- }
-
- /**
- * Returns the episode title.
- */
- public String getEpisodeTitle() {
- return mEpisodeTitle;
- }
-
- /**
- * Returns the description of program.
- */
- public String getProgramDescription() {
- return mProgramDescription;
- }
-
- /**
- * Returns the long description of program.
- */
- public String getProgramLongDescription() {
- return mProgramLongDescription;
- }
-
- /**
- * Returns the poster uri of program.
- */
- public String getProgramPosterArtUri() {
- return mProgramPosterArtUri;
- }
-
- /**
- * Returns the thumb nail uri of program.
- */
- public String getProgramThumbnailUri() {
- return mProgramThumbnailUri;
- }
-
- /**
- * Returns duration.
- */
- public long getDuration() {
- return mEndTimeMs - mStartTimeMs;
- }
-
- /**
- * Returns the state. The possible states are {@link #STATE_RECORDING_NOT_STARTED},
- * {@link #STATE_RECORDING_IN_PROGRESS}, {@link #STATE_RECORDING_FINISHED},
- * {@link #STATE_RECORDING_FAILED}, {@link #STATE_RECORDING_CLIPPED} and
- * {@link #STATE_RECORDING_DELETED}.
- */
- @RecordingState public int getState() {
- return mState;
- }
-
- /**
- * Returns the ID of the {@link SeriesRecording} including this schedule.
- */
- public long getSeriesRecordingId() {
- return mSeriesRecordingId;
- }
-
- public long getId() {
- return mId;
- }
-
- /**
- * Sets the ID;
- */
- public void setId(long id) {
- mId = id;
- }
-
- public long getPriority() {
- return mPriority;
- }
-
- /**
- * Returns season number, episode number and episode title for display.
- */
- public String getEpisodeDisplayTitle(Context context) {
- if (!TextUtils.isEmpty(mEpisodeNumber)) {
- String episodeTitle = mEpisodeTitle == null ? "" : mEpisodeTitle;
- if (TextUtils.equals(mSeasonNumber, "0")) {
- // Do not show "S0: ".
- return String.format(context.getResources().getString(
- R.string.display_episode_title_format_no_season_number),
- mEpisodeNumber, episodeTitle);
- } else {
- return String.format(context.getResources().getString(
- R.string.display_episode_title_format),
- mSeasonNumber, mEpisodeNumber, episodeTitle);
- }
- }
- return mEpisodeTitle;
- }
-
- /**
- * Returns the program's title withe its season and episode number.
- */
- public String getProgramTitleWithEpisodeNumber(Context context) {
- if (TextUtils.isEmpty(mProgramTitle)) {
- return mProgramTitle;
- }
- if (TextUtils.isEmpty(mSeasonNumber) || mSeasonNumber.equals("0")) {
- return TextUtils.isEmpty(mEpisodeNumber) ? mProgramTitle : context.getString(
- R.string.program_title_with_episode_number_no_season, mProgramTitle,
- mEpisodeNumber);
- } else {
- return context.getString(R.string.program_title_with_episode_number, mProgramTitle,
- mSeasonNumber, mEpisodeNumber);
- }
- }
-
-
- /**
- * Converts a string to a @RecordingType int, defaulting to {@link #TYPE_TIMED}.
- */
- private static @RecordingType int recordingType(String type) {
- switch (type) {
- case Schedules.TYPE_TIMED:
- return TYPE_TIMED;
- case Schedules.TYPE_PROGRAM:
- return TYPE_PROGRAM;
- default:
- SoftPreconditions.checkArgument(false, TAG, "Unknown recording type " + type);
- return TYPE_TIMED;
- }
- }
-
- /**
- * Converts a @RecordingType int to a string, defaulting to {@link Schedules#TYPE_TIMED}.
- */
- private static String recordingType(@RecordingType int type) {
- switch (type) {
- case TYPE_TIMED:
- return Schedules.TYPE_TIMED;
- case TYPE_PROGRAM:
- return Schedules.TYPE_PROGRAM;
- default:
- SoftPreconditions.checkArgument(false, TAG, "Unknown recording type " + type);
- return Schedules.TYPE_TIMED;
- }
- }
-
- /**
- * Converts a string to a @RecordingState int, defaulting to
- * {@link #STATE_RECORDING_NOT_STARTED}.
- */
- private static @RecordingState int recordingState(String state) {
- switch (state) {
- case Schedules.STATE_RECORDING_NOT_STARTED:
- return STATE_RECORDING_NOT_STARTED;
- case Schedules.STATE_RECORDING_IN_PROGRESS:
- return STATE_RECORDING_IN_PROGRESS;
- case Schedules.STATE_RECORDING_FINISHED:
- return STATE_RECORDING_FINISHED;
- case Schedules.STATE_RECORDING_FAILED:
- return STATE_RECORDING_FAILED;
- case Schedules.STATE_RECORDING_CLIPPED:
- return STATE_RECORDING_CLIPPED;
- case Schedules.STATE_RECORDING_DELETED:
- return STATE_RECORDING_DELETED;
- case Schedules.STATE_RECORDING_CANCELED:
- return STATE_RECORDING_CANCELED;
- default:
- SoftPreconditions.checkArgument(false, TAG, "Unknown recording state" + state);
- return STATE_RECORDING_NOT_STARTED;
- }
- }
-
- /**
- * Converts a @RecordingState int to string, defaulting to
- * {@link Schedules#STATE_RECORDING_NOT_STARTED}.
- */
- private static String recordingState(@RecordingState int state) {
- switch (state) {
- case STATE_RECORDING_NOT_STARTED:
- return Schedules.STATE_RECORDING_NOT_STARTED;
- case STATE_RECORDING_IN_PROGRESS:
- return Schedules.STATE_RECORDING_IN_PROGRESS;
- case STATE_RECORDING_FINISHED:
- return Schedules.STATE_RECORDING_FINISHED;
- case STATE_RECORDING_FAILED:
- return Schedules.STATE_RECORDING_FAILED;
- case STATE_RECORDING_CLIPPED:
- return Schedules.STATE_RECORDING_CLIPPED;
- case STATE_RECORDING_DELETED:
- return Schedules.STATE_RECORDING_DELETED;
- case STATE_RECORDING_CANCELED:
- return Schedules.STATE_RECORDING_CANCELED;
- default:
- SoftPreconditions.checkArgument(false, TAG, "Unknown recording state" + state);
- return Schedules.STATE_RECORDING_NOT_STARTED;
- }
- }
-
- /**
- * Checks if the {@code period} overlaps with the recording time.
- */
- public boolean isOverLapping(Range<Long> period) {
- return mStartTimeMs < period.getUpper() && mEndTimeMs > period.getLower();
- }
-
- /**
- * Checks if the {@code schedule} overlaps with this schedule.
- */
- public boolean isOverLapping(ScheduledRecording schedule) {
- return mStartTimeMs < schedule.getEndTimeMs() && mEndTimeMs > schedule.getStartTimeMs();
- }
-
- @Override
- public String toString() {
- return "ScheduledRecording[" + mId
- + "]"
- + "(inputId=" + mInputId
- + ",channelId=" + mChannelId
- + ",programId=" + mProgramId
- + ",programTitle=" + mProgramTitle
- + ",type=" + mType
- + ",startTime=" + Utils.toIsoDateTimeString(mStartTimeMs) + "(" + mStartTimeMs + ")"
- + ",endTime=" + Utils.toIsoDateTimeString(mEndTimeMs) + "(" + mEndTimeMs + ")"
- + ",seasonNumber=" + mSeasonNumber
- + ",episodeNumber=" + mEpisodeNumber
- + ",episodeTitle=" + mEpisodeTitle
- + ",programDescription=" + mProgramDescription
- + ",programLongDescription=" + mProgramLongDescription
- + ",programPosterArtUri=" + mProgramPosterArtUri
- + ",programThumbnailUri=" + mProgramThumbnailUri
- + ",state=" + mState
- + ",priority=" + mPriority
- + ",seriesRecordingId=" + mSeriesRecordingId
- + ")";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int paramInt) {
- out.writeLong(mId);
- out.writeLong(mPriority);
- out.writeString(mInputId);
- out.writeLong(mChannelId);
- out.writeLong(mProgramId);
- out.writeString(mProgramTitle);
- out.writeInt(mType);
- out.writeLong(mStartTimeMs);
- out.writeLong(mEndTimeMs);
- out.writeString(mSeasonNumber);
- out.writeString(mEpisodeNumber);
- out.writeString(mEpisodeTitle);
- out.writeString(mProgramDescription);
- out.writeString(mProgramLongDescription);
- out.writeString(mProgramPosterArtUri);
- out.writeString(mProgramThumbnailUri);
- out.writeInt(mState);
- out.writeLong(mSeriesRecordingId);
- }
-
- /**
- * Returns {@code true} if the recording is not started yet, otherwise @{code false}.
- */
- public boolean isNotStarted() {
- return mState == STATE_RECORDING_NOT_STARTED;
- }
-
- /**
- * Returns {@code true} if the recording is in progress, otherwise @{code false}.
- */
- public boolean isInProgress() {
- return mState == STATE_RECORDING_IN_PROGRESS;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof ScheduledRecording)) {
- return false;
- }
- ScheduledRecording r = (ScheduledRecording) obj;
- return mId == r.mId
- && mPriority == r.mPriority
- && mChannelId == r.mChannelId
- && mProgramId == r.mProgramId
- && Objects.equals(mProgramTitle, r.mProgramTitle)
- && mType == r.mType
- && mStartTimeMs == r.mStartTimeMs
- && mEndTimeMs == r.mEndTimeMs
- && Objects.equals(mSeasonNumber, r.mSeasonNumber)
- && Objects.equals(mEpisodeNumber, r.mEpisodeNumber)
- && Objects.equals(mEpisodeTitle, r.mEpisodeTitle)
- && Objects.equals(mProgramDescription, r.getProgramDescription())
- && Objects.equals(mProgramLongDescription, r.getProgramLongDescription())
- && Objects.equals(mProgramPosterArtUri, r.getProgramPosterArtUri())
- && Objects.equals(mProgramThumbnailUri, r.getProgramThumbnailUri())
- && mState == r.mState
- && mSeriesRecordingId == r.mSeriesRecordingId;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mId, mPriority, mChannelId, mProgramId, mProgramTitle, mType,
- mStartTimeMs, mEndTimeMs, mSeasonNumber, mEpisodeNumber, mEpisodeTitle,
- mProgramDescription, mProgramLongDescription, mProgramPosterArtUri,
- mProgramThumbnailUri, mState, mSeriesRecordingId);
- }
-
- /**
- * Returns an array containing all of the elements in the list.
- */
- public static ScheduledRecording[] toArray(Collection<ScheduledRecording> schedules) {
- return schedules.toArray(new ScheduledRecording[schedules.size()]);
- }
-}
diff --git a/src/com/android/tv/dvr/Scheduler.java b/src/com/android/tv/dvr/Scheduler.java
deleted file mode 100644
index ce78e1be..00000000
--- a/src/com/android/tv/dvr/Scheduler.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.media.tv.TvInputInfo;
-import android.media.tv.TvInputManager.TvInputCallback;
-import android.os.Looper;
-import android.support.annotation.MainThread;
-import android.support.annotation.VisibleForTesting;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Range;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.ChannelDataManager.Listener;
-import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener;
-import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
-import com.android.tv.util.Clock;
-import com.android.tv.util.TvInputManagerHelper;
-import com.android.tv.util.Utils;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * The core class to manage schedule and run actual recording.
- */
-@MainThread
-public class Scheduler extends TvInputCallback implements ScheduledRecordingListener {
- private static final String TAG = "Scheduler";
- private static final boolean DEBUG = false;
-
- private final static long SOON_DURATION_IN_MS = TimeUnit.MINUTES.toMillis(5);
- @VisibleForTesting final static long MS_TO_WAKE_BEFORE_START = TimeUnit.MINUTES.toMillis(1);
-
- private final Looper mLooper;
- private final InputSessionManager mSessionManager;
- private final WritableDvrDataManager mDataManager;
- private final DvrManager mDvrManager;
- private final ChannelDataManager mChannelDataManager;
- private final TvInputManagerHelper mInputManager;
- private final Context mContext;
- private final Clock mClock;
- private final AlarmManager mAlarmManager;
-
- private final Map<String, InputTaskScheduler> mInputSchedulerMap = new ArrayMap<>();
- private long mLastStartTimePendingMs;
-
- public Scheduler(Looper looper, DvrManager dvrManager, InputSessionManager sessionManager,
- WritableDvrDataManager dataManager, ChannelDataManager channelDataManager,
- TvInputManagerHelper inputManager, Context context, Clock clock,
- AlarmManager alarmManager) {
- mLooper = looper;
- mDvrManager = dvrManager;
- mSessionManager = sessionManager;
- mDataManager = dataManager;
- mChannelDataManager = channelDataManager;
- mInputManager = inputManager;
- mContext = context;
- mClock = clock;
- mAlarmManager = alarmManager;
- }
-
- /**
- * Starts the scheduler.
- */
- public void start() {
- mDataManager.addScheduledRecordingListener(this);
- mInputManager.addCallback(this);
- if (mDataManager.isDvrScheduleLoadFinished() && mChannelDataManager.isDbLoadFinished()) {
- updateInternal();
- } else {
- if (!mDataManager.isDvrScheduleLoadFinished()) {
- mDataManager.addDvrScheduleLoadFinishedListener(
- new OnDvrScheduleLoadFinishedListener() {
- @Override
- public void onDvrScheduleLoadFinished() {
- mDataManager.removeDvrScheduleLoadFinishedListener(this);
- updateInternal();
- }
- });
- }
- if (!mChannelDataManager.isDbLoadFinished()) {
- mChannelDataManager.addListener(new Listener() {
- @Override
- public void onLoadFinished() {
- mChannelDataManager.removeListener(this);
- updateInternal();
- }
-
- @Override
- public void onChannelListUpdated() { }
-
- @Override
- public void onChannelBrowsableChanged() { }
- });
- }
- }
- }
-
- /**
- * Stops the scheduler.
- */
- public void stop() {
- for (InputTaskScheduler inputTaskScheduler : mInputSchedulerMap.values()) {
- inputTaskScheduler.stop();
- }
- mInputManager.removeCallback(this);
- mDataManager.removeScheduledRecordingListener(this);
- }
-
- private void updatePendingRecordings() {
- List<ScheduledRecording> scheduledRecordings = mDataManager
- .getScheduledRecordings(new Range<>(mLastStartTimePendingMs,
- mClock.currentTimeMillis() + SOON_DURATION_IN_MS),
- ScheduledRecording.STATE_RECORDING_NOT_STARTED);
- for (ScheduledRecording r : scheduledRecordings) {
- scheduleRecordingSoon(r);
- }
- }
-
- /**
- * Start recording that will happen soon, and set the next alarm time.
- */
- public void update() {
- if (DEBUG) Log.d(TAG, "update");
- updateInternal();
- }
-
- private void updateInternal() {
- if (isInitialized()) {
- updatePendingRecordings();
- updateNextAlarm();
- }
- }
-
- private boolean isInitialized() {
- return mDataManager.isDvrScheduleLoadFinished() && mChannelDataManager.isDbLoadFinished();
- }
-
- @Override
- public void onScheduledRecordingAdded(ScheduledRecording... schedules) {
- if (DEBUG) Log.d(TAG, "added " + Arrays.asList(schedules));
- if (!isInitialized()) {
- return;
- }
- handleScheduleChange(schedules);
- }
-
- @Override
- public void onScheduledRecordingRemoved(ScheduledRecording... schedules) {
- if (DEBUG) Log.d(TAG, "removed " + Arrays.asList(schedules));
- if (!isInitialized()) {
- return;
- }
- boolean needToUpdateAlarm = false;
- for (ScheduledRecording schedule : schedules) {
- InputTaskScheduler scheduler = mInputSchedulerMap.get(schedule.getInputId());
- if (scheduler != null) {
- scheduler.removeSchedule(schedule);
- needToUpdateAlarm = true;
- }
- }
- if (needToUpdateAlarm) {
- updateNextAlarm();
- }
- }
-
- @Override
- public void onScheduledRecordingStatusChanged(ScheduledRecording... schedules) {
- if (DEBUG) Log.d(TAG, "state changed " + Arrays.asList(schedules));
- if (!isInitialized()) {
- return;
- }
- // Update the recordings.
- for (ScheduledRecording schedule : schedules) {
- InputTaskScheduler scheduler = mInputSchedulerMap.get(schedule.getInputId());
- if (scheduler != null) {
- scheduler.updateSchedule(schedule);
- }
- }
- handleScheduleChange(schedules);
- }
-
- private void handleScheduleChange(ScheduledRecording... schedules) {
- boolean needToUpdateAlarm = false;
- for (ScheduledRecording schedule : schedules) {
- if (schedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED) {
- if (startsWithin(schedule, SOON_DURATION_IN_MS)) {
- scheduleRecordingSoon(schedule);
- } else {
- needToUpdateAlarm = true;
- }
- }
- }
- if (needToUpdateAlarm) {
- updateNextAlarm();
- }
- }
-
- private void scheduleRecordingSoon(ScheduledRecording schedule) {
- TvInputInfo input = Utils.getTvInputInfoForInputId(mContext, schedule.getInputId());
- if (input == null) {
- Log.e(TAG, "Can't find input for " + schedule);
- mDataManager.changeState(schedule, ScheduledRecording.STATE_RECORDING_FAILED);
- return;
- }
- if (!input.canRecord() || input.getTunerCount() <= 0) {
- Log.e(TAG, "TV input doesn't support recording: " + input);
- mDataManager.changeState(schedule, ScheduledRecording.STATE_RECORDING_FAILED);
- return;
- }
- InputTaskScheduler scheduler = mInputSchedulerMap.get(input.getId());
- if (scheduler == null) {
- scheduler = new InputTaskScheduler(mContext, input, mLooper, mChannelDataManager,
- mDvrManager, mDataManager, mSessionManager, mClock);
- mInputSchedulerMap.put(input.getId(), scheduler);
- }
- scheduler.addSchedule(schedule);
- if (mLastStartTimePendingMs < schedule.getStartTimeMs()) {
- mLastStartTimePendingMs = schedule.getStartTimeMs();
- }
- }
-
- private void updateNextAlarm() {
- long nextStartTime = mDataManager.getNextScheduledStartTimeAfter(
- Math.max(mLastStartTimePendingMs, mClock.currentTimeMillis()));
- if (nextStartTime != DvrDataManager.NEXT_START_TIME_NOT_FOUND) {
- long wakeAt = nextStartTime - MS_TO_WAKE_BEFORE_START;
- if (DEBUG) Log.d(TAG, "Set alarm to record at " + wakeAt);
- Intent intent = new Intent(mContext, DvrStartRecordingReceiver.class);
- PendingIntent alarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
- // This will cancel the previous alarm.
- mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, wakeAt, alarmIntent);
- } else {
- if (DEBUG) Log.d(TAG, "No future recording, alarm not set");
- }
- }
-
- @VisibleForTesting
- boolean startsWithin(ScheduledRecording scheduledRecording, long durationInMs) {
- return mClock.currentTimeMillis() >= scheduledRecording.getStartTimeMs() - durationInMs;
- }
-
- // No need to remove input task scheduler when the input is removed. If the input is removed
- // temporarily, the scheduler should keep the non-started schedules.
- @Override
- public void onInputUpdated(String inputId) {
- InputTaskScheduler scheduler = mInputSchedulerMap.get(inputId);
- if (scheduler != null) {
- scheduler.updateTvInputInfo(Utils.getTvInputInfoForInputId(mContext, inputId));
- }
- }
-
- @Override
- public void onTvInputInfoUpdated(TvInputInfo input) {
- InputTaskScheduler scheduler = mInputSchedulerMap.get(input.getId());
- if (scheduler != null) {
- scheduler.updateTvInputInfo(input);
- }
- }
-}
diff --git a/src/com/android/tv/dvr/SeriesInfo.java b/src/com/android/tv/dvr/SeriesInfo.java
deleted file mode 100644
index 30256dc5..00000000
--- a/src/com/android/tv/dvr/SeriesInfo.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-/**
- * Series information.
- */
-public class SeriesInfo {
- private final String mId;
- private final String mTitle;
- private final String mDescription;
- private final String mLongDescription;
- private final int[] mCanonicalGenreIds;
- private final String mPosterUri;
- private final String mPhotoUri;
-
- public SeriesInfo(String id, String title, String description, String longDescription,
- int[] canonicalGenreIds, String posterUri, String photoUri) {
- this.mId = id;
- this.mTitle = title;
- this.mDescription = description;
- this.mLongDescription = longDescription;
- this.mCanonicalGenreIds = canonicalGenreIds;
- this.mPosterUri = posterUri;
- this.mPhotoUri = photoUri;
- }
-
- /** Returns the ID. **/
- public String getId() {
- return mId;
- }
-
- /** Returns the title. **/
- public String getTitle() {
- return mTitle;
- }
-
- /** Returns the description. **/
- public String getDescription() {
- return mDescription;
- }
-
- /** Returns the description. **/
- public String getLongDescription() {
- return mLongDescription;
- }
-
- /** Returns the canonical genre IDs. **/
- public int[] getCanonicalGenreIds() {
- return mCanonicalGenreIds;
- }
-
- /** Returns the poster URI. **/
- public String getPosterUri() {
- return mPosterUri;
- }
-
- /** Returns the photo URI. **/
- public String getPhotoUri() {
- return mPhotoUri;
- }
-}
diff --git a/src/com/android/tv/dvr/SeriesRecording.java b/src/com/android/tv/dvr/SeriesRecording.java
deleted file mode 100644
index f0690f5f..00000000
--- a/src/com/android/tv/dvr/SeriesRecording.java
+++ /dev/null
@@ -1,755 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.support.annotation.IntDef;
-import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
-
-import com.android.tv.data.BaseProgram;
-import com.android.tv.data.Program;
-import com.android.tv.dvr.provider.DvrContract.SeriesRecordings;
-import com.android.tv.util.Utils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Objects;
-
-/**
- * Schedules the recording of a Series of Programs.
- *
- * <p>
- * Contains the data needed to create new ScheduleRecordings as the programs become available in
- * the EPG.
- */
-public class SeriesRecording implements Parcelable {
- /**
- * Indicates that the ID is not assigned yet.
- */
- public static final long ID_NOT_SET = 0;
-
- /**
- * The default priority of this recording.
- */
- public static final long DEFAULT_PRIORITY = Long.MAX_VALUE >> 1;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true,
- value = {OPTION_CHANNEL_ONE, OPTION_CHANNEL_ALL})
- public @interface ChannelOption {}
- /**
- * An option which indicates that the episodes in one channel are recorded.
- */
- public static final int OPTION_CHANNEL_ONE = 0;
- /**
- * An option which indicates that the episodes in all the channels are recorded.
- */
- public static final int OPTION_CHANNEL_ALL = 1;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true,
- value = {STATE_SERIES_NORMAL, STATE_SERIES_STOPPED})
- public @interface SeriesState {}
-
- /**
- * The state indicates that the series recording is a normal one.
- */
- public static final int STATE_SERIES_NORMAL = 0;
-
- /**
- * The state indicates that the series recording is stopped.
- */
- public static final int STATE_SERIES_STOPPED = 1;
-
- /**
- * Compare priority in descending order.
- */
- public static final Comparator<SeriesRecording> PRIORITY_COMPARATOR =
- new Comparator<SeriesRecording>() {
- @Override
- public int compare(SeriesRecording lhs, SeriesRecording rhs) {
- int value = Long.compare(rhs.mPriority, lhs.mPriority);
- if (value == 0) {
- // New recording has the higher priority.
- value = Long.compare(rhs.mId, lhs.mId);
- }
- return value;
- }
- };
-
- /**
- * Compare ID in ascending order.
- */
- public static final Comparator<SeriesRecording> ID_COMPARATOR =
- new Comparator<SeriesRecording>() {
- @Override
- public int compare(SeriesRecording lhs, SeriesRecording rhs) {
- return Long.compare(lhs.mId, rhs.mId);
- }
- };
-
- /**
- * Creates a new Builder with the values set from the series information of {@link BaseProgram}.
- */
- public static Builder builder(String inputId, BaseProgram p) {
- return new Builder()
- .setInputId(inputId)
- .setSeriesId(p.getSeriesId())
- .setChannelId(p.getChannelId())
- .setTitle(p.getTitle())
- .setDescription(p.getDescription())
- .setLongDescription(p.getLongDescription())
- .setCanonicalGenreIds(p.getCanonicalGenreIds())
- .setPosterUri(p.getPosterArtUri())
- .setPhotoUri(p.getThumbnailUri());
- }
-
- /**
- * Creates a new Builder with the values set from an existing {@link SeriesRecording}.
- */
- @VisibleForTesting
- public static Builder buildFrom(SeriesRecording r) {
- return new Builder()
- .setId(r.mId)
- .setInputId(r.getInputId())
- .setChannelId(r.getChannelId())
- .setPriority(r.getPriority())
- .setTitle(r.getTitle())
- .setDescription(r.getDescription())
- .setLongDescription(r.getLongDescription())
- .setSeriesId(r.getSeriesId())
- .setStartFromEpisode(r.getStartFromEpisode())
- .setStartFromSeason(r.getStartFromSeason())
- .setChannelOption(r.getChannelOption())
- .setCanonicalGenreIds(r.getCanonicalGenreIds())
- .setPosterUri(r.getPosterUri())
- .setPhotoUri(r.getPhotoUri())
- .setState(r.getState());
- }
-
- /**
- * Use this projection if you want to create {@link SeriesRecording} object using
- * {@link #fromCursor}.
- */
- public static final String[] PROJECTION = {
- // Columns must match what is read in fromCursor()
- SeriesRecordings._ID,
- SeriesRecordings.COLUMN_INPUT_ID,
- SeriesRecordings.COLUMN_CHANNEL_ID,
- SeriesRecordings.COLUMN_PRIORITY,
- SeriesRecordings.COLUMN_TITLE,
- SeriesRecordings.COLUMN_SHORT_DESCRIPTION,
- SeriesRecordings.COLUMN_LONG_DESCRIPTION,
- SeriesRecordings.COLUMN_SERIES_ID,
- SeriesRecordings.COLUMN_START_FROM_EPISODE,
- SeriesRecordings.COLUMN_START_FROM_SEASON,
- SeriesRecordings.COLUMN_CHANNEL_OPTION,
- SeriesRecordings.COLUMN_CANONICAL_GENRE,
- SeriesRecordings.COLUMN_POSTER_URI,
- SeriesRecordings.COLUMN_PHOTO_URI,
- SeriesRecordings.COLUMN_STATE
- };
- /**
- * Creates {@link SeriesRecording} object from the given {@link Cursor}.
- */
- public static SeriesRecording fromCursor(Cursor c) {
- int index = -1;
- return new Builder()
- .setId(c.getLong(++index))
- .setInputId(c.getString(++index))
- .setChannelId(c.getLong(++index))
- .setPriority(c.getLong(++index))
- .setTitle(c.getString(++index))
- .setDescription(c.getString(++index))
- .setLongDescription(c.getString(++index))
- .setSeriesId(c.getString(++index))
- .setStartFromEpisode(c.getInt(++index))
- .setStartFromSeason(c.getInt(++index))
- .setChannelOption(channelOption(c.getString(++index)))
- .setCanonicalGenreIds(c.getString(++index))
- .setPosterUri(c.getString(++index))
- .setPhotoUri(c.getString(++index))
- .setState(seriesRecordingState(c.getString(++index)))
- .build();
- }
-
- /**
- * Returns the ContentValues with keys as the columns specified in {@link SeriesRecordings}
- * and the values from {@code r}.
- */
- public static ContentValues toContentValues(SeriesRecording r) {
- ContentValues values = new ContentValues();
- if (r.getId() != ID_NOT_SET) {
- values.put(SeriesRecordings._ID, r.getId());
- } else {
- values.putNull(SeriesRecordings._ID);
- }
- values.put(SeriesRecordings.COLUMN_INPUT_ID, r.getInputId());
- values.put(SeriesRecordings.COLUMN_CHANNEL_ID, r.getChannelId());
- values.put(SeriesRecordings.COLUMN_PRIORITY, r.getPriority());
- values.put(SeriesRecordings.COLUMN_TITLE, r.getTitle());
- values.put(SeriesRecordings.COLUMN_SHORT_DESCRIPTION, r.getDescription());
- values.put(SeriesRecordings.COLUMN_LONG_DESCRIPTION, r.getLongDescription());
- values.put(SeriesRecordings.COLUMN_SERIES_ID, r.getSeriesId());
- values.put(SeriesRecordings.COLUMN_START_FROM_EPISODE, r.getStartFromEpisode());
- values.put(SeriesRecordings.COLUMN_START_FROM_SEASON, r.getStartFromSeason());
- values.put(SeriesRecordings.COLUMN_CHANNEL_OPTION,
- channelOption(r.getChannelOption()));
- values.put(SeriesRecordings.COLUMN_CANONICAL_GENRE,
- Utils.getCanonicalGenre(r.getCanonicalGenreIds()));
- values.put(SeriesRecordings.COLUMN_POSTER_URI, r.getPosterUri());
- values.put(SeriesRecordings.COLUMN_PHOTO_URI, r.getPhotoUri());
- values.put(SeriesRecordings.COLUMN_STATE, seriesRecordingState(r.getState()));
- return values;
- }
-
- private static String channelOption(@ChannelOption int option) {
- switch (option) {
- case OPTION_CHANNEL_ONE:
- return SeriesRecordings.OPTION_CHANNEL_ONE;
- case OPTION_CHANNEL_ALL:
- return SeriesRecordings.OPTION_CHANNEL_ALL;
- }
- return SeriesRecordings.OPTION_CHANNEL_ONE;
- }
-
- @ChannelOption private static int channelOption(String option) {
- switch (option) {
- case SeriesRecordings.OPTION_CHANNEL_ONE:
- return OPTION_CHANNEL_ONE;
- case SeriesRecordings.OPTION_CHANNEL_ALL:
- return OPTION_CHANNEL_ALL;
- }
- return OPTION_CHANNEL_ONE;
- }
-
- private static String seriesRecordingState(@SeriesState int state) {
- switch (state) {
- case STATE_SERIES_NORMAL:
- return SeriesRecordings.STATE_SERIES_NORMAL;
- case STATE_SERIES_STOPPED:
- return SeriesRecordings.STATE_SERIES_STOPPED;
- }
- return SeriesRecordings.STATE_SERIES_NORMAL;
- }
-
- @SeriesState private static int seriesRecordingState(String state) {
- switch (state) {
- case SeriesRecordings.STATE_SERIES_NORMAL:
- return STATE_SERIES_NORMAL;
- case SeriesRecordings.STATE_SERIES_STOPPED:
- return STATE_SERIES_STOPPED;
- }
- return STATE_SERIES_NORMAL;
- }
-
- /**
- * Builder for {@link SeriesRecording}.
- */
- public static class Builder {
- private long mId = ID_NOT_SET;
- private long mPriority = DvrScheduleManager.DEFAULT_SERIES_PRIORITY;
- private String mTitle;
- private String mDescription;
- private String mLongDescription;
- private String mInputId;
- private long mChannelId;
- private String mSeriesId;
- private int mStartFromSeason = SeriesRecordings.THE_BEGINNING;
- private int mStartFromEpisode = SeriesRecordings.THE_BEGINNING;
- private int mChannelOption = OPTION_CHANNEL_ONE;
- private int[] mCanonicalGenreIds;
- private String mPosterUri;
- private String mPhotoUri;
- private int mState = SeriesRecording.STATE_SERIES_NORMAL;
-
- /**
- * @see #getId()
- */
- public Builder setId(long id) {
- mId = id;
- return this;
- }
-
- /**
- * @see #getPriority() ()
- */
- public Builder setPriority(long priority) {
- mPriority = priority;
- return this;
- }
-
- /**
- * @see #getTitle()
- */
- public Builder setTitle(String title) {
- mTitle = title;
- return this;
- }
-
- /**
- * @see #getDescription()
- */
- public Builder setDescription(String description) {
- mDescription = description;
- return this;
- }
-
- /**
- * @see #getLongDescription()
- */
- public Builder setLongDescription(String longDescription) {
- mLongDescription = longDescription;
- return this;
- }
-
- /**
- * @see #getInputId()
- */
- public Builder setInputId(String inputId) {
- mInputId = inputId;
- return this;
- }
-
- /**
- * @see #getChannelId()
- */
- public Builder setChannelId(long channelId) {
- mChannelId = channelId;
- return this;
- }
-
- /**
- * @see #getSeriesId()
- */
- public Builder setSeriesId(String seriesId) {
- mSeriesId = seriesId;
- return this;
- }
-
- /**
- * @see #getStartFromSeason()
- */
- public Builder setStartFromSeason(int startFromSeason) {
- mStartFromSeason = startFromSeason;
- return this;
- }
-
- /**
- * @see #getChannelOption()
- */
- public Builder setChannelOption(@ChannelOption int option) {
- mChannelOption = option;
- return this;
- }
-
- /**
- * @see #getStartFromEpisode()
- */
- public Builder setStartFromEpisode(int startFromEpisode) {
- mStartFromEpisode = startFromEpisode;
- return this;
- }
-
- /**
- * @see #getCanonicalGenreIds()
- */
- public Builder setCanonicalGenreIds(String genres) {
- mCanonicalGenreIds = Utils.getCanonicalGenreIds(genres);
- return this;
- }
-
- /**
- * @see #getCanonicalGenreIds()
- */
- public Builder setCanonicalGenreIds(int[] canonicalGenreIds) {
- mCanonicalGenreIds = canonicalGenreIds;
- return this;
- }
-
- /**
- * @see #getPosterUri()
- */
- public Builder setPosterUri(String posterUri) {
- mPosterUri = posterUri;
- return this;
- }
-
- /**
- * @see #getPhotoUri()
- */
- public Builder setPhotoUri(String photoUri) {
- mPhotoUri = photoUri;
- return this;
- }
-
- /**
- * @see #getState()
- */
- public Builder setState(@SeriesState int state) {
- mState = state;
- return this;
- }
-
- /**
- * Creates a new {@link SeriesRecording}.
- */
- public SeriesRecording build() {
- return new SeriesRecording(mId, mPriority, mTitle, mDescription, mLongDescription,
- mInputId, mChannelId, mSeriesId, mStartFromSeason, mStartFromEpisode,
- mChannelOption, mCanonicalGenreIds, mPosterUri, mPhotoUri, mState);
- }
- }
-
- public static SeriesRecording fromParcel(Parcel in) {
- return new Builder()
- .setId(in.readLong())
- .setPriority(in.readLong())
- .setTitle(in.readString())
- .setDescription(in.readString())
- .setLongDescription(in.readString())
- .setInputId(in.readString())
- .setChannelId(in.readLong())
- .setSeriesId(in.readString())
- .setStartFromSeason(in.readInt())
- .setStartFromEpisode(in.readInt())
- .setChannelOption(in.readInt())
- .setCanonicalGenreIds(in.createIntArray())
- .setPosterUri(in.readString())
- .setPhotoUri(in.readString())
- .setState(in.readInt())
- .build();
- }
-
- public static final Parcelable.Creator<SeriesRecording> CREATOR =
- new Parcelable.Creator<SeriesRecording>() {
- @Override
- public SeriesRecording createFromParcel(Parcel in) {
- return SeriesRecording.fromParcel(in);
- }
-
- @Override
- public SeriesRecording[] newArray(int size) {
- return new SeriesRecording[size];
- }
- };
-
- private long mId;
- private final long mPriority;
- private final String mTitle;
- private final String mDescription;
- private final String mLongDescription;
- private final String mInputId;
- private final long mChannelId;
- private final String mSeriesId;
- private final int mStartFromSeason;
- private final int mStartFromEpisode;
- @ChannelOption private final int mChannelOption;
- private final int[] mCanonicalGenreIds;
- private final String mPosterUri;
- private final String mPhotoUri;
- @SeriesState private int mState;
-
- /**
- * The input id of this SeriesRecording.
- */
- public String getInputId() {
- return mInputId;
- }
-
- /**
- * The channelId to match. The channel ID might not be valid when the channel option is "ALL".
- */
- public long getChannelId() {
- return mChannelId;
- }
-
- /**
- * The id of this SeriesRecording.
- */
- public long getId() {
- return mId;
- }
-
- /**
- * Sets the ID.
- */
- public void setId(long id) {
- mId = id;
- }
-
- /**
- * The priority of this recording.
- *
- * <p> The highest number is recorded first. If there is a tie in mPriority then the higher mId
- * wins.
- */
- public long getPriority() {
- return mPriority;
- }
-
- /**
- * The series title.
- */
- public String getTitle() {
- return mTitle;
- }
-
- /**
- * The series description.
- */
- public String getDescription() {
- return mDescription;
- }
-
- /**
- * The long series description.
- */
- public String getLongDescription() {
- return mLongDescription;
- }
-
- /**
- * SeriesId when not null is used to match programs instead of using title and channelId.
- *
- * <p>SeriesId is an opaque but stable string.
- */
- public String getSeriesId() {
- return mSeriesId;
- }
-
- /**
- * If not == {@link SeriesRecordings#THE_BEGINNING} and seasonNumber == startFromSeason then
- * only record episodes with a episodeNumber >= this
- */
- public int getStartFromEpisode() {
- return mStartFromEpisode;
- }
-
- /**
- * If not == {@link SeriesRecordings#THE_BEGINNING} then only record episodes with a
- * seasonNumber >= this
- */
- public int getStartFromSeason() {
- return mStartFromSeason;
- }
-
- /**
- * Returns the channel recording option.
- */
- @ChannelOption public int getChannelOption() {
- return mChannelOption;
- }
-
- /**
- * Returns the canonical genre ID's.
- */
- public int[] getCanonicalGenreIds() {
- return mCanonicalGenreIds;
- }
-
- /**
- * Returns the poster URI.
- */
- public String getPosterUri() {
- return mPosterUri;
- }
-
- /**
- * Returns the photo URI.
- */
- public String getPhotoUri() {
- return mPhotoUri;
- }
-
- /**
- * Returns the state of series recording.
- */
- @SeriesState public int getState() {
- return mState;
- }
-
- /**
- * Checks whether the series recording is stopped or not.
- */
- public boolean isStopped() {
- return mState == STATE_SERIES_STOPPED;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof SeriesRecording)) return false;
- SeriesRecording that = (SeriesRecording) o;
- return mPriority == that.mPriority
- && mChannelId == that.mChannelId
- && mStartFromSeason == that.mStartFromSeason
- && mStartFromEpisode == that.mStartFromEpisode
- && Objects.equals(mId, that.mId)
- && Objects.equals(mTitle, that.mTitle)
- && Objects.equals(mDescription, that.mDescription)
- && Objects.equals(mLongDescription, that.mLongDescription)
- && Objects.equals(mSeriesId, that.mSeriesId)
- && mChannelOption == that.mChannelOption
- && Arrays.equals(mCanonicalGenreIds, that.mCanonicalGenreIds)
- && Objects.equals(mPosterUri, that.mPosterUri)
- && Objects.equals(mPhotoUri, that.mPhotoUri)
- && mState == that.mState;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mPriority, mChannelId, mStartFromSeason, mStartFromEpisode, mId,
- mTitle, mDescription, mLongDescription, mSeriesId, mChannelOption,
- mCanonicalGenreIds, mPosterUri, mPhotoUri, mState);
- }
-
- @Override
- public String toString() {
- return "SeriesRecording{" +
- "inputId=" + mInputId +
- ", channelId=" + mChannelId +
- ", id='" + mId + '\'' +
- ", priority=" + mPriority +
- ", title='" + mTitle + '\'' +
- ", description='" + mDescription + '\'' +
- ", longDescription='" + mLongDescription + '\'' +
- ", startFromSeason=" + mStartFromSeason +
- ", startFromEpisode=" + mStartFromEpisode +
- ", channelOption=" + mChannelOption +
- ", canonicalGenreIds=" + Arrays.toString(mCanonicalGenreIds) +
- ", posterUri=" + mPosterUri +
- ", photoUri=" + mPhotoUri +
- ", state=" + mState +
- '}';
- }
-
- private SeriesRecording(long id, long priority, String title, String description,
- String longDescription, String inputId, long channelId, String seriesId,
- int startFromSeason, int startFromEpisode, int channelOption, int[] canonicalGenreIds,
- String posterUri, String photoUri, int state) {
- this.mId = id;
- this.mPriority = priority;
- this.mTitle = title;
- this.mDescription = description;
- this.mLongDescription = longDescription;
- this.mInputId = inputId;
- this.mChannelId = channelId;
- this.mSeriesId = seriesId;
- this.mStartFromSeason = startFromSeason;
- this.mStartFromEpisode = startFromEpisode;
- this.mChannelOption = channelOption;
- this.mCanonicalGenreIds = canonicalGenreIds;
- this.mPosterUri = posterUri;
- this.mPhotoUri = photoUri;
- this.mState = state;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int paramInt) {
- out.writeLong(mId);
- out.writeLong(mPriority);
- out.writeString(mTitle);
- out.writeString(mDescription);
- out.writeString(mLongDescription);
- out.writeString(mInputId);
- out.writeLong(mChannelId);
- out.writeString(mSeriesId);
- out.writeInt(mStartFromSeason);
- out.writeInt(mStartFromEpisode);
- out.writeInt(mChannelOption);
- out.writeIntArray(mCanonicalGenreIds);
- out.writeString(mPosterUri);
- out.writeString(mPhotoUri);
- out.writeInt(mState);
- }
-
- /**
- * Returns an array containing all of the elements in the list.
- */
- public static SeriesRecording[] toArray(Collection<SeriesRecording> series) {
- return series.toArray(new SeriesRecording[series.size()]);
- }
-
- /**
- * Returns {@code true} if the {@code program} is part of the series and meets the season and
- * episode constraints.
- */
- public boolean matchProgram(Program program) {
- return matchProgram(program, mChannelOption);
- }
-
- /**
- * Returns {@code true} if the {@code program} is part of the series and meets the season and
- * episode constraints. It checks the channel option only if {@code checkChannelOption} is
- * {@code true}.
- */
- public boolean matchProgram(Program program, @ChannelOption int channelOption) {
- String seriesId = program.getSeriesId();
- long channelId = program.getChannelId();
- String seasonNumber = program.getSeasonNumber();
- String episodeNumber = program.getEpisodeNumber();
- if (!mSeriesId.equals(seriesId) || (channelOption == SeriesRecording.OPTION_CHANNEL_ONE
- && mChannelId != channelId)) {
- return false;
- }
- // Season number and episode number matches if
- // start_season_number < program_season_number
- // || (start_season_number == program_season_number
- // && start_episode_number <= program_episode_number).
- if (mStartFromSeason == SeriesRecordings.THE_BEGINNING
- || TextUtils.isEmpty(seasonNumber)) {
- return true;
- } else {
- int intSeasonNumber;
- try {
- intSeasonNumber = Integer.valueOf(seasonNumber);
- } catch (NumberFormatException e) {
- return true;
- }
- if (intSeasonNumber > mStartFromSeason) {
- return true;
- } else if (intSeasonNumber < mStartFromSeason) {
- return false;
- }
- }
- if (mStartFromEpisode == SeriesRecordings.THE_BEGINNING
- || TextUtils.isEmpty(episodeNumber)) {
- return true;
- } else {
- int intEpisodeNumber;
- try {
- intEpisodeNumber = Integer.valueOf(episodeNumber);
- } catch (NumberFormatException e) {
- return true;
- }
- return intEpisodeNumber >= mStartFromEpisode;
- }
- }
-}
diff --git a/src/com/android/tv/dvr/SeriesRecordingScheduler.java b/src/com/android/tv/dvr/SeriesRecordingScheduler.java
deleted file mode 100644
index 5ed12ce8..00000000
--- a/src/com/android/tv/dvr/SeriesRecordingScheduler.java
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.support.annotation.MainThread;
-import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.LongSparseArray;
-
-import com.android.tv.ApplicationSingletons;
-import com.android.tv.TvApplication;
-import com.android.tv.common.CollectionUtils;
-import com.android.tv.common.SharedPreferencesUtils;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.data.Program;
-import com.android.tv.data.epg.EpgFetcher;
-import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
-import com.android.tv.dvr.DvrDataManager.SeriesRecordingListener;
-import com.android.tv.dvr.EpisodicProgramLoadTask.ScheduledEpisode;
-import com.android.tv.experiments.Experiments;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.Set;
-
-/**
- * Creates the {@link ScheduledRecording}s for the {@link SeriesRecording}.
- * <p>
- * The current implementation assumes that the series recordings are scheduled only for one channel.
- */
-@TargetApi(Build.VERSION_CODES.N)
-public class SeriesRecordingScheduler {
- private static final String TAG = "SeriesRecordingSchd";
- private static final boolean DEBUG = false;
-
- private static final String KEY_FETCHED_SERIES_IDS =
- "SeriesRecordingScheduler.fetched_series_ids";
-
- @SuppressLint("StaticFieldLeak")
- private static SeriesRecordingScheduler sInstance;
-
- /**
- * Creates and returns the {@link SeriesRecordingScheduler}.
- */
- public static synchronized SeriesRecordingScheduler getInstance(Context context) {
- if (sInstance == null) {
- sInstance = new SeriesRecordingScheduler(context);
- }
- return sInstance;
- }
-
- private final Context mContext;
- private final DvrManager mDvrManager;
- private final WritableDvrDataManager mDataManager;
- private final List<SeriesRecordingUpdateTask> mScheduleTasks = new ArrayList<>();
- private final List<FetchSeriesInfoTask> mFetchSeriesInfoTasks = new ArrayList<>();
- private final Set<String> mFetchedSeriesIds = new ArraySet<>();
- private final SharedPreferences mSharedPreferences;
- private boolean mStarted;
- private boolean mPaused;
- private final Set<Long> mPendingSeriesRecordings = new ArraySet<>();
- private final Set<OnSeriesRecordingUpdatedListener> mOnSeriesRecordingUpdatedListeners =
- new CopyOnWriteArraySet<>();
-
-
- private final SeriesRecordingListener mSeriesRecordingListener = new SeriesRecordingListener() {
- @Override
- public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) {
- for (SeriesRecording seriesRecording : seriesRecordings) {
- executeFetchSeriesInfoTask(seriesRecording);
- }
- }
-
- @Override
- public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) {
- // Cancel the update.
- for (Iterator<SeriesRecordingUpdateTask> iter = mScheduleTasks.iterator();
- iter.hasNext(); ) {
- SeriesRecordingUpdateTask task = iter.next();
- if (CollectionUtils.subtract(task.getSeriesRecordings(), seriesRecordings,
- SeriesRecording.ID_COMPARATOR).isEmpty()) {
- task.cancel(true);
- iter.remove();
- }
- }
- }
-
- @Override
- public void onSeriesRecordingChanged(SeriesRecording... seriesRecordings) {
- List<SeriesRecording> stopped = new ArrayList<>();
- List<SeriesRecording> normal = new ArrayList<>();
- for (SeriesRecording r : seriesRecordings) {
- if (r.isStopped()) {
- stopped.add(r);
- } else {
- normal.add(r);
- }
- }
- if (!stopped.isEmpty()) {
- onSeriesRecordingRemoved(SeriesRecording.toArray(stopped));
- }
- if (!normal.isEmpty()) {
- updateSchedules(normal);
- }
- }
- };
-
- private final ScheduledRecordingListener mScheduledRecordingListener =
- new ScheduledRecordingListener() {
- @Override
- public void onScheduledRecordingAdded(ScheduledRecording... schedules) {
- // No need to update series recordings when the new schedule is added.
- }
-
- @Override
- public void onScheduledRecordingRemoved(ScheduledRecording... schedules) {
- handleScheduledRecordingChange(Arrays.asList(schedules));
- }
-
- @Override
- public void onScheduledRecordingStatusChanged(ScheduledRecording... schedules) {
- List<ScheduledRecording> schedulesForUpdate = new ArrayList<>();
- for (ScheduledRecording r : schedules) {
- if ((r.getState() == ScheduledRecording.STATE_RECORDING_FAILED
- || r.getState() == ScheduledRecording.STATE_RECORDING_CLIPPED)
- && r.getSeriesRecordingId() != SeriesRecording.ID_NOT_SET
- && !TextUtils.isEmpty(r.getSeasonNumber())
- && !TextUtils.isEmpty(r.getEpisodeNumber())) {
- schedulesForUpdate.add(r);
- }
- }
- if (!schedulesForUpdate.isEmpty()) {
- handleScheduledRecordingChange(schedulesForUpdate);
- }
- }
-
- private void handleScheduledRecordingChange(List<ScheduledRecording> schedules) {
- if (schedules.isEmpty()) {
- return;
- }
- Set<Long> seriesRecordingIds = new HashSet<>();
- for (ScheduledRecording r : schedules) {
- if (r.getSeriesRecordingId() != SeriesRecording.ID_NOT_SET) {
- seriesRecordingIds.add(r.getSeriesRecordingId());
- }
- }
- if (!seriesRecordingIds.isEmpty()) {
- List<SeriesRecording> seriesRecordings = new ArrayList<>();
- for (Long id : seriesRecordingIds) {
- SeriesRecording seriesRecording = mDataManager.getSeriesRecording(id);
- if (seriesRecording != null) {
- seriesRecordings.add(seriesRecording);
- }
- }
- if (!seriesRecordings.isEmpty()) {
- updateSchedules(seriesRecordings);
- }
- }
- }
- };
-
- private SeriesRecordingScheduler(Context context) {
- mContext = context.getApplicationContext();
- ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
- mDvrManager = appSingletons.getDvrManager();
- mDataManager = (WritableDvrDataManager) appSingletons.getDvrDataManager();
- mSharedPreferences = context.getSharedPreferences(
- SharedPreferencesUtils.SHARED_PREF_SERIES_RECORDINGS, Context.MODE_PRIVATE);
- mFetchedSeriesIds.addAll(mSharedPreferences.getStringSet(KEY_FETCHED_SERIES_IDS,
- Collections.emptySet()));
- }
-
- /**
- * Starts the scheduler.
- */
- @MainThread
- public void start() {
- SoftPreconditions.checkState(mDataManager.isInitialized());
- if (mStarted) {
- return;
- }
- if (DEBUG) Log.d(TAG, "start");
- mStarted = true;
- mDataManager.addSeriesRecordingListener(mSeriesRecordingListener);
- mDataManager.addScheduledRecordingListener(mScheduledRecordingListener);
- startFetchingSeriesInfo();
- updateSchedules(mDataManager.getSeriesRecordings());
- }
-
- @MainThread
- public void stop() {
- if (!mStarted) {
- return;
- }
- if (DEBUG) Log.d(TAG, "stop");
- mStarted = false;
- for (FetchSeriesInfoTask task : mFetchSeriesInfoTasks) {
- task.cancel(true);
- }
- mFetchSeriesInfoTasks.clear();
- for (SeriesRecordingUpdateTask task : mScheduleTasks) {
- task.cancel(true);
- }
- mScheduleTasks.clear();
- mDataManager.removeScheduledRecordingListener(mScheduledRecordingListener);
- mDataManager.removeSeriesRecordingListener(mSeriesRecordingListener);
- }
-
- private void startFetchingSeriesInfo() {
- for (SeriesRecording seriesRecording : mDataManager.getSeriesRecordings()) {
- if (!mFetchedSeriesIds.contains(seriesRecording.getSeriesId())) {
- executeFetchSeriesInfoTask(seriesRecording);
- }
- }
- }
-
- private void executeFetchSeriesInfoTask(SeriesRecording seriesRecording) {
- if (Experiments.CLOUD_EPG.get()) {
- FetchSeriesInfoTask task = new FetchSeriesInfoTask(seriesRecording);
- task.execute();
- mFetchSeriesInfoTasks.add(task);
- }
- }
-
- /**
- * Pauses the updates of the series recordings.
- */
- public void pauseUpdate() {
- if (DEBUG) Log.d(TAG, "Schedule paused");
- if (mPaused) {
- return;
- }
- mPaused = true;
- if (!mStarted) {
- return;
- }
- for (SeriesRecordingUpdateTask task : mScheduleTasks) {
- for (SeriesRecording r : task.getSeriesRecordings()) {
- mPendingSeriesRecordings.add(r.getId());
- }
- task.cancel(true);
- }
- }
-
- /**
- * Resumes the updates of the series recordings.
- */
- public void resumeUpdate() {
- if (DEBUG) Log.d(TAG, "Schedule resumed");
- if (!mPaused) {
- return;
- }
- mPaused = false;
- if (!mStarted) {
- return;
- }
- if (!mPendingSeriesRecordings.isEmpty()) {
- List<SeriesRecording> seriesRecordings = new ArrayList<>();
- for (long seriesRecordingId : mPendingSeriesRecordings) {
- SeriesRecording seriesRecording =
- mDataManager.getSeriesRecording(seriesRecordingId);
- if (seriesRecording != null) {
- seriesRecordings.add(seriesRecording);
- }
- }
- if (!seriesRecordings.isEmpty()) {
- updateSchedules(seriesRecordings);
- }
- }
- }
-
- /**
- * Update schedules for the given series recordings. If it's paused, the update will be done
- * after it's resumed.
- */
- public void updateSchedules(Collection<SeriesRecording> seriesRecordings) {
- if (DEBUG) Log.d(TAG, "updateSchedules:" + seriesRecordings);
- if (!mStarted) {
- if (DEBUG) Log.d(TAG, "Not started yet.");
- return;
- }
- if (mPaused) {
- for (SeriesRecording r : seriesRecordings) {
- mPendingSeriesRecordings.add(r.getId());
- }
- if (DEBUG) {
- Log.d(TAG, "The scheduler has been paused. Adding to the pending list. size="
- + mPendingSeriesRecordings.size());
- }
- return;
- }
- Set<SeriesRecording> previousSeriesRecordings = new HashSet<>();
- for (Iterator<SeriesRecordingUpdateTask> iter = mScheduleTasks.iterator();
- iter.hasNext(); ) {
- SeriesRecordingUpdateTask task = iter.next();
- if (CollectionUtils.containsAny(task.getSeriesRecordings(), seriesRecordings,
- SeriesRecording.ID_COMPARATOR)) {
- // The task is affected by the seriesRecordings
- task.cancel(true);
- previousSeriesRecordings.addAll(task.getSeriesRecordings());
- iter.remove();
- }
- }
- List<SeriesRecording> seriesRecordingsToUpdate = CollectionUtils.union(seriesRecordings,
- previousSeriesRecordings, SeriesRecording.ID_COMPARATOR);
- for (Iterator<SeriesRecording> iter = seriesRecordingsToUpdate.iterator();
- iter.hasNext(); ) {
- SeriesRecording seriesRecording = mDataManager.getSeriesRecording(iter.next().getId());
- if (seriesRecording == null || seriesRecording.isStopped()) {
- // Series recording has been removed or stopped.
- iter.remove();
- }
- }
- if (seriesRecordingsToUpdate.isEmpty()) {
- return;
- }
- if (needToReadAllChannels(seriesRecordingsToUpdate)) {
- SeriesRecordingUpdateTask task =
- new SeriesRecordingUpdateTask(seriesRecordingsToUpdate);
- mScheduleTasks.add(task);
- if (DEBUG) Log.d(TAG, "Added schedule task: " + task);
- task.execute();
- } else {
- for (SeriesRecording seriesRecording : seriesRecordingsToUpdate) {
- SeriesRecordingUpdateTask task = new SeriesRecordingUpdateTask(
- Collections.singletonList(seriesRecording));
- mScheduleTasks.add(task);
- if (DEBUG) Log.d(TAG, "Added schedule task: " + task);
- task.execute();
- }
- }
- }
-
- /**
- * Adds {@link OnSeriesRecordingUpdatedListener}.
- */
- public void addOnSeriesRecordingUpdatedListener(OnSeriesRecordingUpdatedListener listener) {
- mOnSeriesRecordingUpdatedListeners.add(listener);
- }
-
- /**
- * Removes {@link OnSeriesRecordingUpdatedListener}.
- */
- public void removeOnSeriesRecordingUpdatedListener(OnSeriesRecordingUpdatedListener listener) {
- mOnSeriesRecordingUpdatedListeners.remove(listener);
- }
-
- private boolean needToReadAllChannels(List<SeriesRecording> seriesRecordingsToUpdate) {
- for (SeriesRecording seriesRecording : seriesRecordingsToUpdate) {
- if (seriesRecording.getChannelOption() == SeriesRecording.OPTION_CHANNEL_ALL) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Pick one program per an episode.
- *
- * <p>Note that the programs which has been already scheduled have the highest priority, and all
- * of them are added even though they are the same episodes. That's because the schedules
- * should be added to the series recording.
- * <p>If there are no existing schedules for an episode, one program which starts earlier is
- * picked.
- */
- private LongSparseArray<List<Program>> pickOneProgramPerEpisode(
- List<SeriesRecording> seriesRecordings, List<Program> programs) {
- return pickOneProgramPerEpisode(mDataManager, seriesRecordings, programs);
- }
-
- /**
- * @see #pickOneProgramPerEpisode(List, List)
- */
- @VisibleForTesting
- static LongSparseArray<List<Program>> pickOneProgramPerEpisode(
- DvrDataManager dataManager, List<SeriesRecording> seriesRecordings,
- List<Program> programs) {
- // Initialize.
- LongSparseArray<List<Program>> result = new LongSparseArray<>();
- Map<String, Long> seriesRecordingIds = new HashMap<>();
- for (SeriesRecording seriesRecording : seriesRecordings) {
- result.put(seriesRecording.getId(), new ArrayList<>());
- seriesRecordingIds.put(seriesRecording.getSeriesId(), seriesRecording.getId());
- }
- // Group programs by the episode.
- Map<ScheduledEpisode, List<Program>> programsForEpisodeMap = new HashMap<>();
- for (Program program : programs) {
- long seriesRecordingId = seriesRecordingIds.get(program.getSeriesId());
- if (TextUtils.isEmpty(program.getSeasonNumber())
- || TextUtils.isEmpty(program.getEpisodeNumber())) {
- // Add all the programs if it doesn't have season number or episode number.
- result.get(seriesRecordingId).add(program);
- continue;
- }
- ScheduledEpisode episode = new ScheduledEpisode(seriesRecordingId,
- program.getSeasonNumber(), program.getEpisodeNumber());
- List<Program> programsForEpisode = programsForEpisodeMap.get(episode);
- if (programsForEpisode == null) {
- programsForEpisode = new ArrayList<>();
- programsForEpisodeMap.put(episode, programsForEpisode);
- }
- programsForEpisode.add(program);
- }
- // Pick one program.
- for (Entry<ScheduledEpisode, List<Program>> entry : programsForEpisodeMap.entrySet()) {
- List<Program> programsForEpisode = entry.getValue();
- Collections.sort(programsForEpisode, new Comparator<Program>() {
- @Override
- public int compare(Program lhs, Program rhs) {
- // Place the existing schedule first.
- boolean lhsScheduled = isProgramScheduled(dataManager, lhs);
- boolean rhsScheduled = isProgramScheduled(dataManager, rhs);
- if (lhsScheduled && !rhsScheduled) {
- return -1;
- }
- if (!lhsScheduled && rhsScheduled) {
- return 1;
- }
- // Sort by the start time in ascending order.
- return lhs.compareTo(rhs);
- }
- });
- boolean added = false;
- // Add all the scheduled programs
- List<Program> programsForSeries = result.get(entry.getKey().seriesRecordingId);
- for (Program program : programsForEpisode) {
- if (isProgramScheduled(dataManager, program)) {
- programsForSeries.add(program);
- added = true;
- } else if (!added) {
- programsForSeries.add(program);
- break;
- }
- }
- }
- return result;
- }
-
- private static boolean isProgramScheduled(DvrDataManager dataManager, Program program) {
- ScheduledRecording schedule =
- dataManager.getScheduledRecordingForProgramId(program.getId());
- return schedule != null && schedule.getState()
- == ScheduledRecording.STATE_RECORDING_NOT_STARTED;
- }
-
- private void updateFetchedSeries() {
- mSharedPreferences.edit().putStringSet(KEY_FETCHED_SERIES_IDS, mFetchedSeriesIds).apply();
- }
-
- /**
- * This works only for the existing series recordings. Do not use this task for the
- * "adding series recording" UI.
- */
- private class SeriesRecordingUpdateTask extends EpisodicProgramLoadTask {
- SeriesRecordingUpdateTask(List<SeriesRecording> seriesRecordings) {
- super(mContext, seriesRecordings);
- }
-
- @Override
- protected void onPostExecute(List<Program> programs) {
- if (DEBUG) Log.d(TAG, "onPostExecute: updating schedules with programs:" + programs);
- mScheduleTasks.remove(this);
- if (programs == null) {
- Log.e(TAG, "Creating schedules for series recording failed: "
- + getSeriesRecordings());
- return;
- }
- LongSparseArray<List<Program>> seriesProgramMap = pickOneProgramPerEpisode(
- getSeriesRecordings(), programs);
- for (SeriesRecording seriesRecording : getSeriesRecordings()) {
- // Check the series recording is still valid.
- SeriesRecording actualSeriesRecording = mDataManager.getSeriesRecording(
- seriesRecording.getId());
- if (actualSeriesRecording == null || actualSeriesRecording.isStopped()) {
- continue;
- }
- List<Program> programsToSchedule = seriesProgramMap.get(seriesRecording.getId());
- if (mDataManager.getSeriesRecording(seriesRecording.getId()) != null
- && !programsToSchedule.isEmpty()) {
- mDvrManager.addScheduleToSeriesRecording(seriesRecording, programsToSchedule);
- }
- }
- if (!mOnSeriesRecordingUpdatedListeners.isEmpty()) {
- for (OnSeriesRecordingUpdatedListener listener
- : mOnSeriesRecordingUpdatedListeners) {
- listener.onSeriesRecordingUpdated(
- SeriesRecording.toArray(getSeriesRecordings()));
- }
- }
- }
-
- @Override
- protected void onCancelled(List<Program> programs) {
- mScheduleTasks.remove(this);
- }
-
- @Override
- public String toString() {
- return "SeriesRecordingUpdateTask:{"
- + "series_recordings=" + getSeriesRecordings()
- + "}";
- }
- }
-
- private class FetchSeriesInfoTask extends AsyncTask<Void, Void, SeriesInfo> {
- private SeriesRecording mSeriesRecording;
-
- FetchSeriesInfoTask(SeriesRecording seriesRecording) {
- mSeriesRecording = seriesRecording;
- }
-
- @Override
- protected SeriesInfo doInBackground(Void... voids) {
- return EpgFetcher.createEpgReader(mContext)
- .getSeriesInfo(mSeriesRecording.getSeriesId());
- }
-
- @Override
- protected void onPostExecute(SeriesInfo seriesInfo) {
- if (seriesInfo != null) {
- mDataManager.updateSeriesRecording(SeriesRecording.buildFrom(mSeriesRecording)
- .setTitle(seriesInfo.getTitle())
- .setDescription(seriesInfo.getDescription())
- .setLongDescription(seriesInfo.getLongDescription())
- .setCanonicalGenreIds(seriesInfo.getCanonicalGenreIds())
- .setPosterUri(seriesInfo.getPosterUri())
- .setPhotoUri(seriesInfo.getPhotoUri())
- .build());
- mFetchedSeriesIds.add(seriesInfo.getId());
- updateFetchedSeries();
- }
- mFetchSeriesInfoTasks.remove(this);
- }
-
- @Override
- protected void onCancelled(SeriesInfo seriesInfo) {
- mFetchSeriesInfoTasks.remove(this);
- }
- }
-
- /**
- * A listener to notify when series recording are updated.
- */
- public interface OnSeriesRecordingUpdatedListener {
- void onSeriesRecordingUpdated(SeriesRecording... seriesRecordings);
- }
-}
diff --git a/src/com/android/tv/dvr/WritableDvrDataManager.java b/src/com/android/tv/dvr/WritableDvrDataManager.java
index bf72d912..129ba153 100644
--- a/src/com/android/tv/dvr/WritableDvrDataManager.java
+++ b/src/com/android/tv/dvr/WritableDvrDataManager.java
@@ -18,7 +18,9 @@ package com.android.tv.dvr;
import android.support.annotation.MainThread;
-import com.android.tv.dvr.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.data.SeriesRecording;
/**
* Full data manager.
@@ -27,7 +29,7 @@ import com.android.tv.dvr.ScheduledRecording.RecordingState;
* for internal use only. Do not call them from UI directly.
*/
@MainThread
-interface WritableDvrDataManager extends DvrDataManager {
+public interface WritableDvrDataManager extends DvrDataManager {
/**
* Adds new recordings.
*/
diff --git a/src/com/android/tv/dvr/data/IdGenerator.java b/src/com/android/tv/dvr/data/IdGenerator.java
new file mode 100644
index 00000000..2ade1dad
--- /dev/null
+++ b/src/com/android/tv/dvr/data/IdGenerator.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.data;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * A class which generate the ID which increases sequentially.
+ */
+public class IdGenerator {
+ /**
+ * ID generator for the scheduled recording.
+ */
+ public static final IdGenerator SCHEDULED_RECORDING = new IdGenerator();
+
+ /**
+ * ID generator for the series recording.
+ */
+ public static final IdGenerator SERIES_RECORDING = new IdGenerator();
+
+ private final AtomicLong mMaxId = new AtomicLong(0);
+
+ /**
+ * Sets the new maximum ID.
+ */
+ public void setMaxId(long maxId) {
+ mMaxId.set(maxId);
+ }
+
+ /**
+ * Returns the new ID which is greater than the existing maximum ID by 1.
+ */
+ public long newId() {
+ return mMaxId.incrementAndGet();
+ }
+}
diff --git a/src/com/android/tv/dvr/data/RecordedProgram.java b/src/com/android/tv/dvr/data/RecordedProgram.java
new file mode 100644
index 00000000..2e953a52
--- /dev/null
+++ b/src/com/android/tv/dvr/data/RecordedProgram.java
@@ -0,0 +1,845 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.data;
+
+import android.annotation.TargetApi;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.media.tv.TvContentRating;
+import android.media.tv.TvContract;
+import android.media.tv.TvContract.RecordedPrograms;
+import android.net.Uri;
+import android.os.Build;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+
+import com.android.tv.common.R;
+import com.android.tv.common.TvContentRatingCache;
+import com.android.tv.data.BaseProgram;
+import com.android.tv.data.GenreItems;
+import com.android.tv.data.InternalDataUtils;
+import com.android.tv.util.Utils;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Immutable instance of {@link android.media.tv.TvContract.RecordedPrograms}.
+ */
+@TargetApi(Build.VERSION_CODES.N)
+public class RecordedProgram extends BaseProgram {
+ public static final int ID_NOT_SET = -1;
+
+ public final static String[] PROJECTION = {
+ // These are in exactly the order listed in RecordedPrograms
+ RecordedPrograms._ID,
+ RecordedPrograms.COLUMN_PACKAGE_NAME,
+ RecordedPrograms.COLUMN_INPUT_ID,
+ RecordedPrograms.COLUMN_CHANNEL_ID,
+ RecordedPrograms.COLUMN_TITLE,
+ RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER,
+ RecordedPrograms.COLUMN_SEASON_TITLE,
+ RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER,
+ RecordedPrograms.COLUMN_EPISODE_TITLE,
+ RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS,
+ RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS,
+ RecordedPrograms.COLUMN_BROADCAST_GENRE,
+ RecordedPrograms.COLUMN_CANONICAL_GENRE,
+ RecordedPrograms.COLUMN_SHORT_DESCRIPTION,
+ RecordedPrograms.COLUMN_LONG_DESCRIPTION,
+ RecordedPrograms.COLUMN_VIDEO_WIDTH,
+ RecordedPrograms.COLUMN_VIDEO_HEIGHT,
+ RecordedPrograms.COLUMN_AUDIO_LANGUAGE,
+ RecordedPrograms.COLUMN_CONTENT_RATING,
+ RecordedPrograms.COLUMN_POSTER_ART_URI,
+ RecordedPrograms.COLUMN_THUMBNAIL_URI,
+ RecordedPrograms.COLUMN_SEARCHABLE,
+ RecordedPrograms.COLUMN_RECORDING_DATA_URI,
+ RecordedPrograms.COLUMN_RECORDING_DATA_BYTES,
+ RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS,
+ RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS,
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1,
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2,
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3,
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4,
+ RecordedPrograms.COLUMN_VERSION_NUMBER,
+ RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
+ };
+
+ public static RecordedProgram fromCursor(Cursor cursor) {
+ int index = 0;
+ Builder builder = builder()
+ .setId(cursor.getLong(index++))
+ .setPackageName(cursor.getString(index++))
+ .setInputId(cursor.getString(index++))
+ .setChannelId(cursor.getLong(index++))
+ .setTitle(cursor.getString(index++))
+ .setSeasonNumber(cursor.getString(index++))
+ .setSeasonTitle(cursor.getString(index++))
+ .setEpisodeNumber(cursor.getString(index++))
+ .setEpisodeTitle(cursor.getString(index++))
+ .setStartTimeUtcMillis(cursor.getLong(index++))
+ .setEndTimeUtcMillis(cursor.getLong(index++))
+ .setBroadcastGenres(cursor.getString(index++))
+ .setCanonicalGenres(cursor.getString(index++))
+ .setShortDescription(cursor.getString(index++))
+ .setLongDescription(cursor.getString(index++))
+ .setVideoWidth(cursor.getInt(index++))
+ .setVideoHeight(cursor.getInt(index++))
+ .setAudioLanguage(cursor.getString(index++))
+ .setContentRatings(
+ TvContentRatingCache.getInstance().getRatings(cursor.getString(index++)))
+ .setPosterArtUri(cursor.getString(index++))
+ .setThumbnailUri(cursor.getString(index++))
+ .setSearchable(cursor.getInt(index++) == 1)
+ .setDataUri(cursor.getString(index++))
+ .setDataBytes(cursor.getLong(index++))
+ .setDurationMillis(cursor.getLong(index++))
+ .setExpireTimeUtcMillis(cursor.getLong(index++))
+ .setInternalProviderFlag1(cursor.getInt(index++))
+ .setInternalProviderFlag2(cursor.getInt(index++))
+ .setInternalProviderFlag3(cursor.getInt(index++))
+ .setInternalProviderFlag4(cursor.getInt(index++))
+ .setVersionNumber(cursor.getInt(index++));
+ if (Utils.isInBundledPackageSet(builder.mPackageName)) {
+ InternalDataUtils.deserializeInternalProviderData(cursor.getBlob(index), builder);
+ }
+ return builder.build();
+ }
+
+ public static ContentValues toValues(RecordedProgram recordedProgram) {
+ ContentValues values = new ContentValues();
+ if (recordedProgram.mId != ID_NOT_SET) {
+ values.put(RecordedPrograms._ID, recordedProgram.mId);
+ }
+ values.put(RecordedPrograms.COLUMN_INPUT_ID, recordedProgram.mInputId);
+ values.put(RecordedPrograms.COLUMN_CHANNEL_ID, recordedProgram.mChannelId);
+ values.put(RecordedPrograms.COLUMN_TITLE, recordedProgram.mTitle);
+ values.put(RecordedPrograms.COLUMN_SEASON_DISPLAY_NUMBER, recordedProgram.mSeasonNumber);
+ values.put(RecordedPrograms.COLUMN_SEASON_TITLE, recordedProgram.mSeasonTitle);
+ values.put(RecordedPrograms.COLUMN_EPISODE_DISPLAY_NUMBER, recordedProgram.mEpisodeNumber);
+ values.put(RecordedPrograms.COLUMN_EPISODE_TITLE, recordedProgram.mTitle);
+ values.put(RecordedPrograms.COLUMN_START_TIME_UTC_MILLIS,
+ recordedProgram.mStartTimeUtcMillis);
+ values.put(RecordedPrograms.COLUMN_END_TIME_UTC_MILLIS, recordedProgram.mEndTimeUtcMillis);
+ values.put(RecordedPrograms.COLUMN_BROADCAST_GENRE,
+ safeEncode(recordedProgram.mBroadcastGenres));
+ values.put(RecordedPrograms.COLUMN_CANONICAL_GENRE,
+ safeEncode(recordedProgram.mCanonicalGenres));
+ values.put(RecordedPrograms.COLUMN_SHORT_DESCRIPTION, recordedProgram.mShortDescription);
+ values.put(RecordedPrograms.COLUMN_LONG_DESCRIPTION, recordedProgram.mLongDescription);
+ if (recordedProgram.mVideoWidth == 0) {
+ values.putNull(RecordedPrograms.COLUMN_VIDEO_WIDTH);
+ } else {
+ values.put(RecordedPrograms.COLUMN_VIDEO_WIDTH, recordedProgram.mVideoWidth);
+ }
+ if (recordedProgram.mVideoHeight == 0) {
+ values.putNull(RecordedPrograms.COLUMN_VIDEO_HEIGHT);
+ } else {
+ values.put(RecordedPrograms.COLUMN_VIDEO_HEIGHT, recordedProgram.mVideoHeight);
+ }
+ values.put(RecordedPrograms.COLUMN_AUDIO_LANGUAGE, recordedProgram.mAudioLanguage);
+ values.put(RecordedPrograms.COLUMN_CONTENT_RATING,
+ TvContentRatingCache.contentRatingsToString(recordedProgram.mContentRatings));
+ values.put(RecordedPrograms.COLUMN_POSTER_ART_URI, recordedProgram.mPosterArtUri);
+ values.put(RecordedPrograms.COLUMN_THUMBNAIL_URI, recordedProgram.mThumbnailUri);
+ values.put(RecordedPrograms.COLUMN_SEARCHABLE, recordedProgram.mSearchable ? 1 : 0);
+ values.put(RecordedPrograms.COLUMN_RECORDING_DATA_URI,
+ safeToString(recordedProgram.mDataUri));
+ values.put(RecordedPrograms.COLUMN_RECORDING_DATA_BYTES, recordedProgram.mDataBytes);
+ values.put(RecordedPrograms.COLUMN_RECORDING_DURATION_MILLIS,
+ recordedProgram.mDurationMillis);
+ values.put(RecordedPrograms.COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS,
+ recordedProgram.mExpireTimeUtcMillis);
+ values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_DATA,
+ InternalDataUtils.serializeInternalProviderData(recordedProgram));
+ values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG1,
+ recordedProgram.mInternalProviderFlag1);
+ values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG2,
+ recordedProgram.mInternalProviderFlag2);
+ values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG3,
+ recordedProgram.mInternalProviderFlag3);
+ values.put(RecordedPrograms.COLUMN_INTERNAL_PROVIDER_FLAG4,
+ recordedProgram.mInternalProviderFlag4);
+ values.put(RecordedPrograms.COLUMN_VERSION_NUMBER, recordedProgram.mVersionNumber);
+ return values;
+ }
+
+ public static class Builder{
+ private long mId = ID_NOT_SET;
+ private String mPackageName;
+ private String mInputId;
+ private long mChannelId;
+ private String mTitle;
+ private String mSeriesId;
+ private String mSeasonNumber;
+ private String mSeasonTitle;
+ private String mEpisodeNumber;
+ private String mEpisodeTitle;
+ private long mStartTimeUtcMillis;
+ private long mEndTimeUtcMillis;
+ private String[] mBroadcastGenres;
+ private String[] mCanonicalGenres;
+ private String mShortDescription;
+ private String mLongDescription;
+ private int mVideoWidth;
+ private int mVideoHeight;
+ private String mAudioLanguage;
+ private TvContentRating[] mContentRatings;
+ private String mPosterArtUri;
+ private String mThumbnailUri;
+ private boolean mSearchable = true;
+ private Uri mDataUri;
+ private long mDataBytes;
+ private long mDurationMillis;
+ private long mExpireTimeUtcMillis;
+ private int mInternalProviderFlag1;
+ private int mInternalProviderFlag2;
+ private int mInternalProviderFlag3;
+ private int mInternalProviderFlag4;
+ private int mVersionNumber;
+
+ public Builder setId(long id) {
+ mId = id;
+ return this;
+ }
+
+ public Builder setPackageName(String packageName) {
+ mPackageName = packageName;
+ return this;
+ }
+
+ public Builder setInputId(String inputId) {
+ mInputId = inputId;
+ return this;
+ }
+
+ public Builder setChannelId(long channelId) {
+ mChannelId = channelId;
+ return this;
+ }
+
+ public Builder setTitle(String title) {
+ mTitle = title;
+ return this;
+ }
+
+ public Builder setSeriesId(String seriesId) {
+ mSeriesId = seriesId;
+ return this;
+ }
+
+ public Builder setSeasonNumber(String seasonNumber) {
+ mSeasonNumber = seasonNumber;
+ return this;
+ }
+
+ public Builder setSeasonTitle(String seasonTitle) {
+ mSeasonTitle = seasonTitle;
+ return this;
+ }
+
+ public Builder setEpisodeNumber(String episodeNumber) {
+ mEpisodeNumber = episodeNumber;
+ return this;
+ }
+
+ public Builder setEpisodeTitle(String episodeTitle) {
+ mEpisodeTitle = episodeTitle;
+ return this;
+ }
+
+ public Builder setStartTimeUtcMillis(long startTimeUtcMillis) {
+ mStartTimeUtcMillis = startTimeUtcMillis;
+ return this;
+ }
+
+ public Builder setEndTimeUtcMillis(long endTimeUtcMillis) {
+ mEndTimeUtcMillis = endTimeUtcMillis;
+ return this;
+ }
+
+ public Builder setBroadcastGenres(String broadcastGenres) {
+ if (TextUtils.isEmpty(broadcastGenres)) {
+ mBroadcastGenres = null;
+ return this;
+ }
+ return setBroadcastGenres(TvContract.Programs.Genres.decode(broadcastGenres));
+ }
+
+ private Builder setBroadcastGenres(String[] broadcastGenres) {
+ mBroadcastGenres = broadcastGenres;
+ return this;
+ }
+
+ public Builder setCanonicalGenres(String canonicalGenres) {
+ if (TextUtils.isEmpty(canonicalGenres)) {
+ mCanonicalGenres = null;
+ return this;
+ }
+ return setCanonicalGenres(TvContract.Programs.Genres.decode(canonicalGenres));
+ }
+
+ private Builder setCanonicalGenres(String[] canonicalGenres) {
+ mCanonicalGenres = canonicalGenres;
+ return this;
+ }
+
+ public Builder setShortDescription(String shortDescription) {
+ mShortDescription = shortDescription;
+ return this;
+ }
+
+ public Builder setLongDescription(String longDescription) {
+ mLongDescription = longDescription;
+ return this;
+ }
+
+ public Builder setVideoWidth(int videoWidth) {
+ mVideoWidth = videoWidth;
+ return this;
+ }
+
+ public Builder setVideoHeight(int videoHeight) {
+ mVideoHeight = videoHeight;
+ return this;
+ }
+
+ public Builder setAudioLanguage(String audioLanguage) {
+ mAudioLanguage = audioLanguage;
+ return this;
+ }
+
+ public Builder setContentRatings(TvContentRating[] contentRatings) {
+ mContentRatings = contentRatings;
+ return this;
+ }
+
+ private Uri toUri(String uriString) {
+ try {
+ return uriString == null ? null : Uri.parse(uriString);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public Builder setPosterArtUri(String posterArtUri) {
+ mPosterArtUri = posterArtUri;
+ return this;
+ }
+
+ public Builder setThumbnailUri(String thumbnailUri) {
+ mThumbnailUri = thumbnailUri;
+ return this;
+ }
+
+ public Builder setSearchable(boolean searchable) {
+ mSearchable = searchable;
+ return this;
+ }
+
+ public Builder setDataUri(String dataUri) {
+ return setDataUri(toUri(dataUri));
+ }
+
+ public Builder setDataUri(Uri dataUri) {
+ mDataUri = dataUri;
+ return this;
+ }
+
+ public Builder setDataBytes(long dataBytes) {
+ mDataBytes = dataBytes;
+ return this;
+ }
+
+ public Builder setDurationMillis(long durationMillis) {
+ mDurationMillis = durationMillis;
+ return this;
+ }
+
+ public Builder setExpireTimeUtcMillis(long expireTimeUtcMillis) {
+ mExpireTimeUtcMillis = expireTimeUtcMillis;
+ return this;
+ }
+
+ public Builder setInternalProviderFlag1(int internalProviderFlag1) {
+ mInternalProviderFlag1 = internalProviderFlag1;
+ return this;
+ }
+
+ public Builder setInternalProviderFlag2(int internalProviderFlag2) {
+ mInternalProviderFlag2 = internalProviderFlag2;
+ return this;
+ }
+
+ public Builder setInternalProviderFlag3(int internalProviderFlag3) {
+ mInternalProviderFlag3 = internalProviderFlag3;
+ return this;
+ }
+
+ public Builder setInternalProviderFlag4(int internalProviderFlag4) {
+ mInternalProviderFlag4 = internalProviderFlag4;
+ return this;
+ }
+
+ public Builder setVersionNumber(int versionNumber) {
+ mVersionNumber = versionNumber;
+ return this;
+ }
+
+ public RecordedProgram build() {
+ if (TextUtils.isEmpty(mTitle)) {
+ // If title is null, series cannot be generated for this program.
+ setSeriesId(null);
+ } else if (TextUtils.isEmpty(mSeriesId) && !TextUtils.isEmpty(mEpisodeNumber)) {
+ // If series ID is not set, generate it for the episodic program of other TV input.
+ setSeriesId(BaseProgram.generateSeriesId(mPackageName, mTitle));
+ }
+ return new RecordedProgram(mId, mPackageName, mInputId, mChannelId, mTitle, mSeriesId,
+ mSeasonNumber, mSeasonTitle, mEpisodeNumber, mEpisodeTitle, mStartTimeUtcMillis,
+ mEndTimeUtcMillis, mBroadcastGenres, mCanonicalGenres, mShortDescription,
+ mLongDescription, mVideoWidth, mVideoHeight, mAudioLanguage, mContentRatings,
+ mPosterArtUri, mThumbnailUri, mSearchable, mDataUri, mDataBytes,
+ mDurationMillis, mExpireTimeUtcMillis, mInternalProviderFlag1,
+ mInternalProviderFlag2, mInternalProviderFlag3, mInternalProviderFlag4,
+ mVersionNumber);
+ }
+ }
+
+ public static Builder builder() { return new Builder(); }
+
+ public static Builder buildFrom(RecordedProgram orig) {
+ return builder()
+ .setId(orig.getId())
+ .setPackageName(orig.getPackageName())
+ .setInputId(orig.getInputId())
+ .setChannelId(orig.getChannelId())
+ .setTitle(orig.getTitle())
+ .setSeriesId(orig.getSeriesId())
+ .setSeasonNumber(orig.getSeasonNumber())
+ .setSeasonTitle(orig.getSeasonTitle())
+ .setEpisodeNumber(orig.getEpisodeNumber())
+ .setEpisodeTitle(orig.getEpisodeTitle())
+ .setStartTimeUtcMillis(orig.getStartTimeUtcMillis())
+ .setEndTimeUtcMillis(orig.getEndTimeUtcMillis())
+ .setBroadcastGenres(orig.getBroadcastGenres())
+ .setCanonicalGenres(orig.getCanonicalGenres())
+ .setShortDescription(orig.getDescription())
+ .setLongDescription(orig.getLongDescription())
+ .setVideoWidth(orig.getVideoWidth())
+ .setVideoHeight(orig.getVideoHeight())
+ .setAudioLanguage(orig.getAudioLanguage())
+ .setContentRatings(orig.getContentRatings())
+ .setPosterArtUri(orig.getPosterArtUri())
+ .setThumbnailUri(orig.getThumbnailUri())
+ .setSearchable(orig.isSearchable())
+ .setInternalProviderFlag1(orig.getInternalProviderFlag1())
+ .setInternalProviderFlag2(orig.getInternalProviderFlag2())
+ .setInternalProviderFlag3(orig.getInternalProviderFlag3())
+ .setInternalProviderFlag4(orig.getInternalProviderFlag4())
+ .setVersionNumber(orig.getVersionNumber());
+ }
+
+ public static final Comparator<RecordedProgram> START_TIME_THEN_ID_COMPARATOR =
+ new Comparator<RecordedProgram>() {
+ @Override
+ public int compare(RecordedProgram lhs, RecordedProgram rhs) {
+ int res =
+ Long.compare(lhs.getStartTimeUtcMillis(), rhs.getStartTimeUtcMillis());
+ if (res != 0) {
+ return res;
+ }
+ return Long.compare(lhs.mId, rhs.mId);
+ }
+ };
+
+ private static final long CLIPPED_THRESHOLD_MS = TimeUnit.MINUTES.toMillis(5);
+
+ private final long mId;
+ private final String mPackageName;
+ private final String mInputId;
+ private final long mChannelId;
+ private final String mTitle;
+ private final String mSeriesId;
+ private final String mSeasonNumber;
+ private final String mSeasonTitle;
+ private final String mEpisodeNumber;
+ private final String mEpisodeTitle;
+ private final long mStartTimeUtcMillis;
+ private final long mEndTimeUtcMillis;
+ private final String[] mBroadcastGenres;
+ private final String[] mCanonicalGenres;
+ private final String mShortDescription;
+ private final String mLongDescription;
+ private final int mVideoWidth;
+ private final int mVideoHeight;
+ private final String mAudioLanguage;
+ private final TvContentRating[] mContentRatings;
+ private final String mPosterArtUri;
+ private final String mThumbnailUri;
+ private final boolean mSearchable;
+ private final Uri mDataUri;
+ private final long mDataBytes;
+ private final long mDurationMillis;
+ private final long mExpireTimeUtcMillis;
+ private final int mInternalProviderFlag1;
+ private final int mInternalProviderFlag2;
+ private final int mInternalProviderFlag3;
+ private final int mInternalProviderFlag4;
+ private final int mVersionNumber;
+
+ private RecordedProgram(long id, String packageName, String inputId, long channelId,
+ String title, String seriesId, String seasonNumber, String seasonTitle,
+ String episodeNumber, String episodeTitle, long startTimeUtcMillis,
+ long endTimeUtcMillis, String[] broadcastGenres, String[] canonicalGenres,
+ String shortDescription, String longDescription, int videoWidth, int videoHeight,
+ String audioLanguage, TvContentRating[] contentRatings, String posterArtUri,
+ String thumbnailUri, boolean searchable, Uri dataUri, long dataBytes,
+ long durationMillis, long expireTimeUtcMillis, int internalProviderFlag1,
+ int internalProviderFlag2, int internalProviderFlag3, int internalProviderFlag4,
+ int versionNumber) {
+ mId = id;
+ mPackageName = packageName;
+ mInputId = inputId;
+ mChannelId = channelId;
+ mTitle = title;
+ mSeriesId = seriesId;
+ mSeasonNumber = seasonNumber;
+ mSeasonTitle = seasonTitle;
+ mEpisodeNumber = episodeNumber;
+ mEpisodeTitle = episodeTitle;
+ mStartTimeUtcMillis = startTimeUtcMillis;
+ mEndTimeUtcMillis = endTimeUtcMillis;
+ mBroadcastGenres = broadcastGenres;
+ mCanonicalGenres = canonicalGenres;
+ mShortDescription = shortDescription;
+ mLongDescription = longDescription;
+ mVideoWidth = videoWidth;
+ mVideoHeight = videoHeight;
+
+ mAudioLanguage = audioLanguage;
+ mContentRatings = contentRatings;
+ mPosterArtUri = posterArtUri;
+ mThumbnailUri = thumbnailUri;
+ mSearchable = searchable;
+ mDataUri = dataUri;
+ mDataBytes = dataBytes;
+ mDurationMillis = durationMillis;
+ mExpireTimeUtcMillis = expireTimeUtcMillis;
+ mInternalProviderFlag1 = internalProviderFlag1;
+ mInternalProviderFlag2 = internalProviderFlag2;
+ mInternalProviderFlag3 = internalProviderFlag3;
+ mInternalProviderFlag4 = internalProviderFlag4;
+ mVersionNumber = versionNumber;
+ }
+
+ public String getAudioLanguage() {
+ return mAudioLanguage;
+ }
+
+ public String[] getBroadcastGenres() {
+ return mBroadcastGenres;
+ }
+
+ public String[] getCanonicalGenres() {
+ return mCanonicalGenres;
+ }
+
+ /**
+ * Returns array of canonical genre ID's for this recorded program.
+ */
+ @Override
+ public int[] getCanonicalGenreIds() {
+ if (mCanonicalGenres == null) {
+ return null;
+ }
+ int[] genreIds = new int[mCanonicalGenres.length];
+ for (int i = 0; i < mCanonicalGenres.length; i++) {
+ genreIds[i] = GenreItems.getId(mCanonicalGenres[i]);
+ }
+ return genreIds;
+ }
+
+ @Override
+ public long getChannelId() {
+ return mChannelId;
+ }
+
+ @Nullable
+ @Override
+ public TvContentRating[] getContentRatings() {
+ return mContentRatings;
+ }
+
+ public Uri getDataUri() {
+ return mDataUri;
+ }
+
+ public long getDataBytes() {
+ return mDataBytes;
+ }
+
+ @Override
+ public long getDurationMillis() {
+ return mDurationMillis;
+ }
+
+ @Override
+ public long getEndTimeUtcMillis() {
+ return mEndTimeUtcMillis;
+ }
+
+ @Override
+ public String getEpisodeNumber() {
+ return mEpisodeNumber;
+ }
+
+ @Override
+ public String getEpisodeTitle() {
+ return mEpisodeTitle;
+ }
+
+ @Nullable
+ public String getEpisodeDisplayNumber(Context context) {
+ if (!TextUtils.isEmpty(mEpisodeNumber)) {
+ if (TextUtils.equals(mSeasonNumber, "0")) {
+ // Do not show "S0: ".
+ return String.format(context.getResources().getString(
+ R.string.display_episode_number_format_no_season_number), mEpisodeNumber);
+ } else {
+ return String.format(context.getResources().getString(
+ R.string.display_episode_number_format), mSeasonNumber, mEpisodeNumber);
+ }
+ }
+ return null;
+ }
+
+ public long getExpireTimeUtcMillis() {
+ return mExpireTimeUtcMillis;
+ }
+
+ public long getId() {
+ return mId;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public String getInputId() {
+ return mInputId;
+ }
+
+ public int getInternalProviderFlag1() {
+ return mInternalProviderFlag1;
+ }
+
+ public int getInternalProviderFlag2() {
+ return mInternalProviderFlag2;
+ }
+
+ public int getInternalProviderFlag3() {
+ return mInternalProviderFlag3;
+ }
+
+ public int getInternalProviderFlag4() {
+ return mInternalProviderFlag4;
+ }
+
+ @Override
+ public String getDescription() {
+ return mShortDescription;
+ }
+
+ @Override
+ public String getLongDescription() {
+ return mLongDescription;
+ }
+
+ @Override
+ public String getPosterArtUri() {
+ return mPosterArtUri;
+ }
+
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ public boolean isSearchable() {
+ return mSearchable;
+ }
+
+ @Override
+ public String getSeriesId() {
+ return mSeriesId;
+ }
+
+ @Override
+ public String getSeasonNumber() {
+ return mSeasonNumber;
+ }
+
+ public String getSeasonTitle() {
+ return mSeasonTitle;
+ }
+
+ @Override
+ public long getStartTimeUtcMillis() {
+ return mStartTimeUtcMillis;
+ }
+
+ @Override
+ public String getThumbnailUri() {
+ return mThumbnailUri;
+ }
+
+ @Override
+ public String getTitle() {
+ return mTitle;
+ }
+
+ public Uri getUri() {
+ return ContentUris.withAppendedId(RecordedPrograms.CONTENT_URI, mId);
+ }
+
+ public int getVersionNumber() {
+ return mVersionNumber;
+ }
+
+ public int getVideoHeight() {
+ return mVideoHeight;
+ }
+
+ public int getVideoWidth() {
+ return mVideoWidth;
+ }
+
+ /**
+ * Checks whether the recording has been clipped or not.
+ */
+ public boolean isClipped() {
+ return mEndTimeUtcMillis - mStartTimeUtcMillis - mDurationMillis > CLIPPED_THRESHOLD_MS;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ RecordedProgram that = (RecordedProgram) o;
+ return Objects.equals(mId, that.mId) &&
+ Objects.equals(mChannelId, that.mChannelId) &&
+ Objects.equals(mSeriesId, that.mSeriesId) &&
+ Objects.equals(mSeasonNumber, that.mSeasonNumber) &&
+ Objects.equals(mSeasonTitle, that.mSeasonTitle) &&
+ Objects.equals(mEpisodeNumber, that.mEpisodeNumber) &&
+ Objects.equals(mStartTimeUtcMillis, that.mStartTimeUtcMillis) &&
+ Objects.equals(mEndTimeUtcMillis, that.mEndTimeUtcMillis) &&
+ Objects.equals(mVideoWidth, that.mVideoWidth) &&
+ Objects.equals(mVideoHeight, that.mVideoHeight) &&
+ Objects.equals(mSearchable, that.mSearchable) &&
+ Objects.equals(mDataBytes, that.mDataBytes) &&
+ Objects.equals(mDurationMillis, that.mDurationMillis) &&
+ Objects.equals(mExpireTimeUtcMillis, that.mExpireTimeUtcMillis) &&
+ Objects.equals(mInternalProviderFlag1, that.mInternalProviderFlag1) &&
+ Objects.equals(mInternalProviderFlag2, that.mInternalProviderFlag2) &&
+ Objects.equals(mInternalProviderFlag3, that.mInternalProviderFlag3) &&
+ Objects.equals(mInternalProviderFlag4, that.mInternalProviderFlag4) &&
+ Objects.equals(mVersionNumber, that.mVersionNumber) &&
+ Objects.equals(mTitle, that.mTitle) &&
+ Objects.equals(mEpisodeTitle, that.mEpisodeTitle) &&
+ Arrays.equals(mBroadcastGenres, that.mBroadcastGenres) &&
+ Arrays.equals(mCanonicalGenres, that.mCanonicalGenres) &&
+ Objects.equals(mShortDescription, that.mShortDescription) &&
+ Objects.equals(mLongDescription, that.mLongDescription) &&
+ Objects.equals(mAudioLanguage, that.mAudioLanguage) &&
+ Arrays.equals(mContentRatings, that.mContentRatings) &&
+ Objects.equals(mPosterArtUri, that.mPosterArtUri) &&
+ Objects.equals(mThumbnailUri, that.mThumbnailUri);
+ }
+
+ /**
+ * Hashes based on the ID.
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId);
+ }
+
+ @Override
+ public String toString() {
+ return "RecordedProgram"
+ + "[" + mId +
+ "]{ mPackageName=" + mPackageName +
+ ", mInputId='" + mInputId + '\'' +
+ ", mChannelId='" + mChannelId + '\'' +
+ ", mTitle='" + mTitle + '\'' +
+ ", mSeriesId='" + mSeriesId + '\'' +
+ ", mEpisodeNumber=" + mEpisodeNumber +
+ ", mEpisodeTitle='" + mEpisodeTitle + '\'' +
+ ", mStartTimeUtcMillis=" + mStartTimeUtcMillis +
+ ", mEndTimeUtcMillis=" + mEndTimeUtcMillis +
+ ", mBroadcastGenres=" +
+ (mBroadcastGenres != null ? Arrays.toString(mBroadcastGenres) : "null") +
+ ", mCanonicalGenres=" +
+ (mCanonicalGenres != null ? Arrays.toString(mCanonicalGenres) : "null") +
+ ", mShortDescription='" + mShortDescription + '\'' +
+ ", mLongDescription='" + mLongDescription + '\'' +
+ ", mVideoHeight=" + mVideoHeight +
+ ", mVideoWidth=" + mVideoWidth +
+ ", mAudioLanguage='" + mAudioLanguage + '\'' +
+ ", mContentRatings='" +
+ TvContentRatingCache.contentRatingsToString(mContentRatings) + '\'' +
+ ", mPosterArtUri=" + mPosterArtUri +
+ ", mThumbnailUri=" + mThumbnailUri +
+ ", mSearchable=" + mSearchable +
+ ", mDataUri=" + mDataUri +
+ ", mDataBytes=" + mDataBytes +
+ ", mDurationMillis=" + mDurationMillis +
+ ", mExpireTimeUtcMillis=" + mExpireTimeUtcMillis +
+ ", mInternalProviderFlag1=" + mInternalProviderFlag1 +
+ ", mInternalProviderFlag2=" + mInternalProviderFlag2 +
+ ", mInternalProviderFlag3=" + mInternalProviderFlag3 +
+ ", mInternalProviderFlag4=" + mInternalProviderFlag4 +
+ ", mSeasonNumber=" + mSeasonNumber +
+ ", mSeasonTitle=" + mSeasonTitle +
+ ", mVersionNumber=" + mVersionNumber +
+ '}';
+ }
+
+ @Nullable
+ private static String safeToString(@Nullable Object o) {
+ return o == null ? null : o.toString();
+ }
+
+ @Nullable
+ private static String safeEncode(@Nullable String[] genres) {
+ return genres == null ? null : TvContract.Programs.Genres.encode(genres);
+ }
+
+ /**
+ * Returns an array containing all of the elements in the list.
+ */
+ public static RecordedProgram[] toArray(Collection<RecordedProgram> recordedPrograms) {
+ return recordedPrograms.toArray(new RecordedProgram[recordedPrograms.size()]);
+ }
+}
diff --git a/src/com/android/tv/dvr/data/ScheduledRecording.java b/src/com/android/tv/dvr/data/ScheduledRecording.java
new file mode 100644
index 00000000..5d11c0f3
--- /dev/null
+++ b/src/com/android/tv/dvr/data/ScheduledRecording.java
@@ -0,0 +1,882 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.data;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.IntDef;
+import android.text.TextUtils;
+import android.util.Range;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.data.Channel;
+import com.android.tv.data.Program;
+import com.android.tv.dvr.DvrScheduleManager;
+import com.android.tv.dvr.provider.DvrContract.Schedules;
+import com.android.tv.util.CompositeComparator;
+import com.android.tv.util.Utils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Objects;
+
+/**
+ * A data class for one recording contents.
+ */
+public final class ScheduledRecording implements Parcelable {
+ private static final String TAG = "ScheduledRecording";
+
+ /**
+ * Indicates that the ID is not assigned yet.
+ */
+ public static final long ID_NOT_SET = 0;
+
+ /**
+ * The default priority of the recording.
+ */
+ public static final long DEFAULT_PRIORITY = Long.MAX_VALUE >> 1;
+
+ /**
+ * Compares the start time in ascending order.
+ */
+ public static final Comparator<ScheduledRecording> START_TIME_COMPARATOR
+ = new Comparator<ScheduledRecording>() {
+ @Override
+ public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
+ return Long.compare(lhs.mStartTimeMs, rhs.mStartTimeMs);
+ }
+ };
+
+ /**
+ * Compares the end time in ascending order.
+ */
+ public static final Comparator<ScheduledRecording> END_TIME_COMPARATOR
+ = new Comparator<ScheduledRecording>() {
+ @Override
+ public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
+ return Long.compare(lhs.mEndTimeMs, rhs.mEndTimeMs);
+ }
+ };
+
+ /**
+ * Compares ID in ascending order. The schedule with the larger ID was created later.
+ */
+ public static final Comparator<ScheduledRecording> ID_COMPARATOR
+ = new Comparator<ScheduledRecording>() {
+ @Override
+ public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
+ return Long.compare(lhs.mId, rhs.mId);
+ }
+ };
+
+ /**
+ * Compares the priority in ascending order.
+ */
+ public static final Comparator<ScheduledRecording> PRIORITY_COMPARATOR
+ = new Comparator<ScheduledRecording>() {
+ @Override
+ public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
+ return Long.compare(lhs.mPriority, rhs.mPriority);
+ }
+ };
+
+ /**
+ * Compares start time in ascending order and then priority in descending order and then ID in
+ * descending order.
+ */
+ public static final Comparator<ScheduledRecording> START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR
+ = new CompositeComparator<>(START_TIME_COMPARATOR, PRIORITY_COMPARATOR.reversed(),
+ ID_COMPARATOR.reversed());
+
+ /**
+ * Builds scheduled recordings from programs.
+ */
+ public static Builder builder(String inputId, Program p) {
+ return new Builder()
+ .setInputId(inputId)
+ .setChannelId(p.getChannelId())
+ .setStartTimeMs(p.getStartTimeUtcMillis()).setEndTimeMs(p.getEndTimeUtcMillis())
+ .setProgramId(p.getId())
+ .setProgramTitle(p.getTitle())
+ .setSeasonNumber(p.getSeasonNumber())
+ .setEpisodeNumber(p.getEpisodeNumber())
+ .setEpisodeTitle(p.getEpisodeTitle())
+ .setProgramDescription(p.getDescription())
+ .setProgramLongDescription(p.getLongDescription())
+ .setProgramPosterArtUri(p.getPosterArtUri())
+ .setProgramThumbnailUri(p.getThumbnailUri())
+ .setType(TYPE_PROGRAM);
+ }
+
+ public static Builder builder(String inputId, long channelId, long startTime, long endTime) {
+ return new Builder()
+ .setInputId(inputId)
+ .setChannelId(channelId)
+ .setStartTimeMs(startTime)
+ .setEndTimeMs(endTime)
+ .setType(TYPE_TIMED);
+ }
+
+ /**
+ * Creates a new Builder with the values set from the {@link RecordedProgram}.
+ */
+ public static Builder builder(RecordedProgram p) {
+ boolean isProgramRecording = !TextUtils.isEmpty(p.getTitle());
+ return new Builder()
+ .setInputId(p.getInputId())
+ .setChannelId(p.getChannelId())
+ .setType(isProgramRecording ? TYPE_PROGRAM : TYPE_TIMED)
+ .setStartTimeMs(p.getStartTimeUtcMillis())
+ .setEndTimeMs(p.getEndTimeUtcMillis())
+ .setProgramTitle(p.getTitle())
+ .setSeasonNumber(p.getSeasonNumber())
+ .setEpisodeNumber(p.getEpisodeNumber())
+ .setEpisodeTitle(p.getEpisodeTitle())
+ .setProgramDescription(p.getDescription())
+ .setProgramLongDescription(p.getLongDescription())
+ .setProgramPosterArtUri(p.getPosterArtUri())
+ .setProgramThumbnailUri(p.getThumbnailUri())
+ .setState(STATE_RECORDING_FINISHED);
+ }
+
+ public static final class Builder {
+ private long mId = ID_NOT_SET;
+ private long mPriority = DvrScheduleManager.DEFAULT_PRIORITY;
+ private String mInputId;
+ private long mChannelId;
+ private long mProgramId = ID_NOT_SET;
+ private String mProgramTitle;
+ private @RecordingType int mType;
+ private long mStartTimeMs;
+ private long mEndTimeMs;
+ private String mSeasonNumber;
+ private String mEpisodeNumber;
+ private String mEpisodeTitle;
+ private String mProgramDescription;
+ private String mProgramLongDescription;
+ private String mProgramPosterArtUri;
+ private String mProgramThumbnailUri;
+ private @RecordingState int mState;
+ private long mSeriesRecordingId = ID_NOT_SET;
+
+ private Builder() { }
+
+ public Builder setId(long id) {
+ mId = id;
+ return this;
+ }
+
+ public Builder setPriority(long priority) {
+ mPriority = priority;
+ return this;
+ }
+
+ public Builder setInputId(String inputId) {
+ mInputId = inputId;
+ return this;
+ }
+
+ public Builder setChannelId(long channelId) {
+ mChannelId = channelId;
+ return this;
+ }
+
+ public Builder setProgramId(long programId) {
+ mProgramId = programId;
+ return this;
+ }
+
+ public Builder setProgramTitle(String programTitle) {
+ mProgramTitle = programTitle;
+ return this;
+ }
+
+ private Builder setType(@RecordingType int type) {
+ mType = type;
+ return this;
+ }
+
+ public Builder setStartTimeMs(long startTimeMs) {
+ mStartTimeMs = startTimeMs;
+ return this;
+ }
+
+ public Builder setEndTimeMs(long endTimeMs) {
+ mEndTimeMs = endTimeMs;
+ return this;
+ }
+
+ public Builder setSeasonNumber(String seasonNumber) {
+ mSeasonNumber = seasonNumber;
+ return this;
+ }
+
+ public Builder setEpisodeNumber(String episodeNumber) {
+ mEpisodeNumber = episodeNumber;
+ return this;
+ }
+
+ public Builder setEpisodeTitle(String episodeTitle) {
+ mEpisodeTitle = episodeTitle;
+ return this;
+ }
+
+ public Builder setProgramDescription(String description) {
+ mProgramDescription = description;
+ return this;
+ }
+
+ public Builder setProgramLongDescription(String longDescription) {
+ mProgramLongDescription = longDescription;
+ return this;
+ }
+
+ public Builder setProgramPosterArtUri(String programPosterArtUri) {
+ mProgramPosterArtUri = programPosterArtUri;
+ return this;
+ }
+
+ public Builder setProgramThumbnailUri(String programThumbnailUri) {
+ mProgramThumbnailUri = programThumbnailUri;
+ return this;
+ }
+
+ public Builder setState(@RecordingState int state) {
+ mState = state;
+ return this;
+ }
+
+ public Builder setSeriesRecordingId(long seriesRecordingId) {
+ mSeriesRecordingId = seriesRecordingId;
+ return this;
+ }
+
+ public ScheduledRecording build() {
+ return new ScheduledRecording(mId, mPriority, mInputId, mChannelId, mProgramId,
+ mProgramTitle, mType, mStartTimeMs, mEndTimeMs, mSeasonNumber, mEpisodeNumber,
+ mEpisodeTitle, mProgramDescription, mProgramLongDescription,
+ mProgramPosterArtUri, mProgramThumbnailUri, mState, mSeriesRecordingId);
+ }
+ }
+
+ /**
+ * Creates {@link Builder} object from the given original {@code Recording}.
+ */
+ public static Builder buildFrom(ScheduledRecording orig) {
+ return new Builder()
+ .setId(orig.mId)
+ .setInputId(orig.mInputId)
+ .setChannelId(orig.mChannelId)
+ .setEndTimeMs(orig.mEndTimeMs)
+ .setSeriesRecordingId(orig.mSeriesRecordingId)
+ .setPriority(orig.mPriority)
+ .setProgramId(orig.mProgramId)
+ .setProgramTitle(orig.mProgramTitle)
+ .setStartTimeMs(orig.mStartTimeMs)
+ .setSeasonNumber(orig.getSeasonNumber())
+ .setEpisodeNumber(orig.getEpisodeNumber())
+ .setEpisodeTitle(orig.getEpisodeTitle())
+ .setProgramDescription(orig.getProgramDescription())
+ .setProgramLongDescription(orig.getProgramLongDescription())
+ .setProgramPosterArtUri(orig.getProgramPosterArtUri())
+ .setProgramThumbnailUri(orig.getProgramThumbnailUri())
+ .setState(orig.mState).setType(orig.mType);
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({STATE_RECORDING_NOT_STARTED, STATE_RECORDING_IN_PROGRESS, STATE_RECORDING_FINISHED,
+ STATE_RECORDING_FAILED, STATE_RECORDING_CLIPPED, STATE_RECORDING_DELETED,
+ STATE_RECORDING_CANCELED})
+ public @interface RecordingState {}
+ public static final int STATE_RECORDING_NOT_STARTED = 0;
+ public static final int STATE_RECORDING_IN_PROGRESS = 1;
+ public static final int STATE_RECORDING_FINISHED = 2;
+ public static final int STATE_RECORDING_FAILED = 3;
+ public static final int STATE_RECORDING_CLIPPED = 4;
+ public static final int STATE_RECORDING_DELETED = 5;
+ public static final int STATE_RECORDING_CANCELED = 6;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({TYPE_TIMED, TYPE_PROGRAM})
+ public @interface RecordingType {}
+ /**
+ * Record with given time range.
+ */
+ public static final int TYPE_TIMED = 1;
+ /**
+ * Record with a given program.
+ */
+ public static final int TYPE_PROGRAM = 2;
+
+ @RecordingType private final int mType;
+
+ /**
+ * Use this projection if you want to create {@link ScheduledRecording} object using
+ * {@link #fromCursor}.
+ */
+ public static final String[] PROJECTION = {
+ // Columns must match what is read in #fromCursor
+ Schedules._ID,
+ Schedules.COLUMN_PRIORITY,
+ Schedules.COLUMN_TYPE,
+ Schedules.COLUMN_INPUT_ID,
+ Schedules.COLUMN_CHANNEL_ID,
+ Schedules.COLUMN_PROGRAM_ID,
+ Schedules.COLUMN_PROGRAM_TITLE,
+ Schedules.COLUMN_START_TIME_UTC_MILLIS,
+ Schedules.COLUMN_END_TIME_UTC_MILLIS,
+ Schedules.COLUMN_SEASON_NUMBER,
+ Schedules.COLUMN_EPISODE_NUMBER,
+ Schedules.COLUMN_EPISODE_TITLE,
+ Schedules.COLUMN_PROGRAM_DESCRIPTION,
+ Schedules.COLUMN_PROGRAM_LONG_DESCRIPTION,
+ Schedules.COLUMN_PROGRAM_POST_ART_URI,
+ Schedules.COLUMN_PROGRAM_THUMBNAIL_URI,
+ Schedules.COLUMN_STATE,
+ Schedules.COLUMN_SERIES_RECORDING_ID};
+
+ /**
+ * Creates {@link ScheduledRecording} object from the given {@link Cursor}.
+ */
+ public static ScheduledRecording fromCursor(Cursor c) {
+ int index = -1;
+ return new Builder()
+ .setId(c.getLong(++index))
+ .setPriority(c.getLong(++index))
+ .setType(recordingType(c.getString(++index)))
+ .setInputId(c.getString(++index))
+ .setChannelId(c.getLong(++index))
+ .setProgramId(c.getLong(++index))
+ .setProgramTitle(c.getString(++index))
+ .setStartTimeMs(c.getLong(++index))
+ .setEndTimeMs(c.getLong(++index))
+ .setSeasonNumber(c.getString(++index))
+ .setEpisodeNumber(c.getString(++index))
+ .setEpisodeTitle(c.getString(++index))
+ .setProgramDescription(c.getString(++index))
+ .setProgramLongDescription(c.getString(++index))
+ .setProgramPosterArtUri(c.getString(++index))
+ .setProgramThumbnailUri(c.getString(++index))
+ .setState(recordingState(c.getString(++index)))
+ .setSeriesRecordingId(c.getLong(++index))
+ .build();
+ }
+
+ public static ContentValues toContentValues(ScheduledRecording r) {
+ ContentValues values = new ContentValues();
+ if (r.getId() != ID_NOT_SET) {
+ values.put(Schedules._ID, r.getId());
+ }
+ values.put(Schedules.COLUMN_INPUT_ID, r.getInputId());
+ values.put(Schedules.COLUMN_CHANNEL_ID, r.getChannelId());
+ values.put(Schedules.COLUMN_PROGRAM_ID, r.getProgramId());
+ values.put(Schedules.COLUMN_PROGRAM_TITLE, r.getProgramTitle());
+ values.put(Schedules.COLUMN_PRIORITY, r.getPriority());
+ values.put(Schedules.COLUMN_START_TIME_UTC_MILLIS, r.getStartTimeMs());
+ values.put(Schedules.COLUMN_END_TIME_UTC_MILLIS, r.getEndTimeMs());
+ values.put(Schedules.COLUMN_SEASON_NUMBER, r.getSeasonNumber());
+ values.put(Schedules.COLUMN_EPISODE_NUMBER, r.getEpisodeNumber());
+ values.put(Schedules.COLUMN_EPISODE_TITLE, r.getEpisodeTitle());
+ values.put(Schedules.COLUMN_PROGRAM_DESCRIPTION, r.getProgramDescription());
+ values.put(Schedules.COLUMN_PROGRAM_LONG_DESCRIPTION, r.getProgramLongDescription());
+ values.put(Schedules.COLUMN_PROGRAM_POST_ART_URI, r.getProgramPosterArtUri());
+ values.put(Schedules.COLUMN_PROGRAM_THUMBNAIL_URI, r.getProgramThumbnailUri());
+ values.put(Schedules.COLUMN_STATE, recordingState(r.getState()));
+ values.put(Schedules.COLUMN_TYPE, recordingType(r.getType()));
+ if (r.getSeriesRecordingId() != ID_NOT_SET) {
+ values.put(Schedules.COLUMN_SERIES_RECORDING_ID, r.getSeriesRecordingId());
+ } else {
+ values.putNull(Schedules.COLUMN_SERIES_RECORDING_ID);
+ }
+ return values;
+ }
+
+ public static ScheduledRecording fromParcel(Parcel in) {
+ return new Builder()
+ .setId(in.readLong())
+ .setPriority(in.readLong())
+ .setInputId(in.readString())
+ .setChannelId(in.readLong())
+ .setProgramId(in.readLong())
+ .setProgramTitle(in.readString())
+ .setType(in.readInt())
+ .setStartTimeMs(in.readLong())
+ .setEndTimeMs(in.readLong())
+ .setSeasonNumber(in.readString())
+ .setEpisodeNumber(in.readString())
+ .setEpisodeTitle(in.readString())
+ .setProgramDescription(in.readString())
+ .setProgramLongDescription(in.readString())
+ .setProgramPosterArtUri(in.readString())
+ .setProgramThumbnailUri(in.readString())
+ .setState(in.readInt())
+ .setSeriesRecordingId(in.readLong())
+ .build();
+ }
+
+ public static final Parcelable.Creator<ScheduledRecording> CREATOR =
+ new Parcelable.Creator<ScheduledRecording>() {
+ @Override
+ public ScheduledRecording createFromParcel(Parcel in) {
+ return ScheduledRecording.fromParcel(in);
+ }
+
+ @Override
+ public ScheduledRecording[] newArray(int size) {
+ return new ScheduledRecording[size];
+ }
+ };
+
+ /**
+ * The ID internal to Live TV
+ */
+ private long mId;
+
+ /**
+ * The priority of this recording.
+ *
+ * <p> The highest number is recorded first. If there is a tie in priority then the higher id
+ * wins.
+ */
+ private final long mPriority;
+
+ private final String mInputId;
+ private final long mChannelId;
+ /**
+ * Optional id of the associated program.
+ */
+ private final long mProgramId;
+ private final String mProgramTitle;
+
+ private final long mStartTimeMs;
+ private final long mEndTimeMs;
+ private final String mSeasonNumber;
+ private final String mEpisodeNumber;
+ private final String mEpisodeTitle;
+ private final String mProgramDescription;
+ private final String mProgramLongDescription;
+ private final String mProgramPosterArtUri;
+ private final String mProgramThumbnailUri;
+ @RecordingState private final int mState;
+ private final long mSeriesRecordingId;
+
+ private ScheduledRecording(long id, long priority, String inputId, long channelId, long programId,
+ String programTitle, @RecordingType int type, long startTime, long endTime,
+ String seasonNumber, String episodeNumber, String episodeTitle,
+ String programDescription, String programLongDescription, String programPosterArtUri,
+ String programThumbnailUri, @RecordingState int state, long seriesRecordingId) {
+ mId = id;
+ mPriority = priority;
+ mInputId = inputId;
+ mChannelId = channelId;
+ mProgramId = programId;
+ mProgramTitle = programTitle;
+ mType = type;
+ mStartTimeMs = startTime;
+ mEndTimeMs = endTime;
+ mSeasonNumber = seasonNumber;
+ mEpisodeNumber = episodeNumber;
+ mEpisodeTitle = episodeTitle;
+ mProgramDescription = programDescription;
+ mProgramLongDescription = programLongDescription;
+ mProgramPosterArtUri = programPosterArtUri;
+ mProgramThumbnailUri = programThumbnailUri;
+ mState = state;
+ mSeriesRecordingId = seriesRecordingId;
+ }
+
+ /**
+ * Returns recording schedule type. The possible types are {@link #TYPE_PROGRAM} and
+ * {@link #TYPE_TIMED}.
+ */
+ @RecordingType
+ public int getType() {
+ return mType;
+ }
+
+ /**
+ * Returns schedules' input id.
+ */
+ public String getInputId() {
+ return mInputId;
+ }
+
+ /**
+ * Returns recorded {@link Channel}.
+ */
+ public long getChannelId() {
+ return mChannelId;
+ }
+
+ /**
+ * Return the optional program id
+ */
+ public long getProgramId() {
+ return mProgramId;
+ }
+
+ /**
+ * Return the optional program Title
+ */
+ public String getProgramTitle() {
+ return mProgramTitle;
+ }
+
+ /**
+ * Returns started time.
+ */
+ public long getStartTimeMs() {
+ return mStartTimeMs;
+ }
+
+ /**
+ * Returns ended time.
+ */
+ public long getEndTimeMs() {
+ return mEndTimeMs;
+ }
+
+ /**
+ * Returns the season number.
+ */
+ public String getSeasonNumber() {
+ return mSeasonNumber;
+ }
+
+ /**
+ * Returns the episode number.
+ */
+ public String getEpisodeNumber() {
+ return mEpisodeNumber;
+ }
+
+ /**
+ * Returns the episode title.
+ */
+ public String getEpisodeTitle() {
+ return mEpisodeTitle;
+ }
+
+ /**
+ * Returns the description of program.
+ */
+ public String getProgramDescription() {
+ return mProgramDescription;
+ }
+
+ /**
+ * Returns the long description of program.
+ */
+ public String getProgramLongDescription() {
+ return mProgramLongDescription;
+ }
+
+ /**
+ * Returns the poster uri of program.
+ */
+ public String getProgramPosterArtUri() {
+ return mProgramPosterArtUri;
+ }
+
+ /**
+ * Returns the thumb nail uri of program.
+ */
+ public String getProgramThumbnailUri() {
+ return mProgramThumbnailUri;
+ }
+
+ /**
+ * Returns duration.
+ */
+ public long getDuration() {
+ return mEndTimeMs - mStartTimeMs;
+ }
+
+ /**
+ * Returns the state. The possible states are {@link #STATE_RECORDING_NOT_STARTED},
+ * {@link #STATE_RECORDING_IN_PROGRESS}, {@link #STATE_RECORDING_FINISHED},
+ * {@link #STATE_RECORDING_FAILED}, {@link #STATE_RECORDING_CLIPPED} and
+ * {@link #STATE_RECORDING_DELETED}.
+ */
+ @RecordingState public int getState() {
+ return mState;
+ }
+
+ /**
+ * Returns the ID of the {@link SeriesRecording} including this schedule.
+ */
+ public long getSeriesRecordingId() {
+ return mSeriesRecordingId;
+ }
+
+ public long getId() {
+ return mId;
+ }
+
+ /**
+ * Sets the ID;
+ */
+ public void setId(long id) {
+ mId = id;
+ }
+
+ public long getPriority() {
+ return mPriority;
+ }
+
+ /**
+ * Returns season number, episode number and episode title for display.
+ */
+ public String getEpisodeDisplayTitle(Context context) {
+ if (!TextUtils.isEmpty(mEpisodeNumber)) {
+ String episodeTitle = mEpisodeTitle == null ? "" : mEpisodeTitle;
+ if (TextUtils.equals(mSeasonNumber, "0")) {
+ // Do not show "S0: ".
+ return String.format(context.getResources().getString(
+ R.string.display_episode_title_format_no_season_number),
+ mEpisodeNumber, episodeTitle);
+ } else {
+ return String.format(context.getResources().getString(
+ R.string.display_episode_title_format),
+ mSeasonNumber, mEpisodeNumber, episodeTitle);
+ }
+ }
+ return mEpisodeTitle;
+ }
+
+ /**
+ * Returns the program's display title, if the program title is not null, returns program title.
+ * Otherwise returns the channel name.
+ */
+ public String getProgramDisplayTitle(Context context) {
+ if (!TextUtils.isEmpty(mProgramTitle)) {
+ return mProgramTitle;
+ }
+ Channel channel = TvApplication.getSingletons(context).getChannelDataManager()
+ .getChannel(mChannelId);
+ return channel != null ? channel.getDisplayName()
+ : context.getString(R.string.no_program_information);
+ }
+
+ /**
+ * Converts a string to a @RecordingType int, defaulting to {@link #TYPE_TIMED}.
+ */
+ private static @RecordingType int recordingType(String type) {
+ switch (type) {
+ case Schedules.TYPE_TIMED:
+ return TYPE_TIMED;
+ case Schedules.TYPE_PROGRAM:
+ return TYPE_PROGRAM;
+ default:
+ SoftPreconditions.checkArgument(false, TAG, "Unknown recording type " + type);
+ return TYPE_TIMED;
+ }
+ }
+
+ /**
+ * Converts a @RecordingType int to a string, defaulting to {@link Schedules#TYPE_TIMED}.
+ */
+ private static String recordingType(@RecordingType int type) {
+ switch (type) {
+ case TYPE_TIMED:
+ return Schedules.TYPE_TIMED;
+ case TYPE_PROGRAM:
+ return Schedules.TYPE_PROGRAM;
+ default:
+ SoftPreconditions.checkArgument(false, TAG, "Unknown recording type " + type);
+ return Schedules.TYPE_TIMED;
+ }
+ }
+
+ /**
+ * Converts a string to a @RecordingState int, defaulting to
+ * {@link #STATE_RECORDING_NOT_STARTED}.
+ */
+ private static @RecordingState int recordingState(String state) {
+ switch (state) {
+ case Schedules.STATE_RECORDING_NOT_STARTED:
+ return STATE_RECORDING_NOT_STARTED;
+ case Schedules.STATE_RECORDING_IN_PROGRESS:
+ return STATE_RECORDING_IN_PROGRESS;
+ case Schedules.STATE_RECORDING_FINISHED:
+ return STATE_RECORDING_FINISHED;
+ case Schedules.STATE_RECORDING_FAILED:
+ return STATE_RECORDING_FAILED;
+ case Schedules.STATE_RECORDING_CLIPPED:
+ return STATE_RECORDING_CLIPPED;
+ case Schedules.STATE_RECORDING_DELETED:
+ return STATE_RECORDING_DELETED;
+ case Schedules.STATE_RECORDING_CANCELED:
+ return STATE_RECORDING_CANCELED;
+ default:
+ SoftPreconditions.checkArgument(false, TAG, "Unknown recording state" + state);
+ return STATE_RECORDING_NOT_STARTED;
+ }
+ }
+
+ /**
+ * Converts a @RecordingState int to string, defaulting to
+ * {@link Schedules#STATE_RECORDING_NOT_STARTED}.
+ */
+ private static String recordingState(@RecordingState int state) {
+ switch (state) {
+ case STATE_RECORDING_NOT_STARTED:
+ return Schedules.STATE_RECORDING_NOT_STARTED;
+ case STATE_RECORDING_IN_PROGRESS:
+ return Schedules.STATE_RECORDING_IN_PROGRESS;
+ case STATE_RECORDING_FINISHED:
+ return Schedules.STATE_RECORDING_FINISHED;
+ case STATE_RECORDING_FAILED:
+ return Schedules.STATE_RECORDING_FAILED;
+ case STATE_RECORDING_CLIPPED:
+ return Schedules.STATE_RECORDING_CLIPPED;
+ case STATE_RECORDING_DELETED:
+ return Schedules.STATE_RECORDING_DELETED;
+ case STATE_RECORDING_CANCELED:
+ return Schedules.STATE_RECORDING_CANCELED;
+ default:
+ SoftPreconditions.checkArgument(false, TAG, "Unknown recording state" + state);
+ return Schedules.STATE_RECORDING_NOT_STARTED;
+ }
+ }
+
+ /**
+ * Checks if the {@code period} overlaps with the recording time.
+ */
+ public boolean isOverLapping(Range<Long> period) {
+ return mStartTimeMs < period.getUpper() && mEndTimeMs > period.getLower();
+ }
+
+ /**
+ * Checks if the {@code schedule} overlaps with this schedule.
+ */
+ public boolean isOverLapping(ScheduledRecording schedule) {
+ return mStartTimeMs < schedule.getEndTimeMs() && mEndTimeMs > schedule.getStartTimeMs();
+ }
+
+ @Override
+ public String toString() {
+ return "ScheduledRecording[" + mId
+ + "]"
+ + "(inputId=" + mInputId
+ + ",channelId=" + mChannelId
+ + ",programId=" + mProgramId
+ + ",programTitle=" + mProgramTitle
+ + ",type=" + mType
+ + ",startTime=" + Utils.toIsoDateTimeString(mStartTimeMs) + "(" + mStartTimeMs + ")"
+ + ",endTime=" + Utils.toIsoDateTimeString(mEndTimeMs) + "(" + mEndTimeMs + ")"
+ + ",seasonNumber=" + mSeasonNumber
+ + ",episodeNumber=" + mEpisodeNumber
+ + ",episodeTitle=" + mEpisodeTitle
+ + ",programDescription=" + mProgramDescription
+ + ",programLongDescription=" + mProgramLongDescription
+ + ",programPosterArtUri=" + mProgramPosterArtUri
+ + ",programThumbnailUri=" + mProgramThumbnailUri
+ + ",state=" + mState
+ + ",priority=" + mPriority
+ + ",seriesRecordingId=" + mSeriesRecordingId
+ + ")";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int paramInt) {
+ out.writeLong(mId);
+ out.writeLong(mPriority);
+ out.writeString(mInputId);
+ out.writeLong(mChannelId);
+ out.writeLong(mProgramId);
+ out.writeString(mProgramTitle);
+ out.writeInt(mType);
+ out.writeLong(mStartTimeMs);
+ out.writeLong(mEndTimeMs);
+ out.writeString(mSeasonNumber);
+ out.writeString(mEpisodeNumber);
+ out.writeString(mEpisodeTitle);
+ out.writeString(mProgramDescription);
+ out.writeString(mProgramLongDescription);
+ out.writeString(mProgramPosterArtUri);
+ out.writeString(mProgramThumbnailUri);
+ out.writeInt(mState);
+ out.writeLong(mSeriesRecordingId);
+ }
+
+ /**
+ * Returns {@code true} if the recording is not started yet, otherwise @{code false}.
+ */
+ public boolean isNotStarted() {
+ return mState == STATE_RECORDING_NOT_STARTED;
+ }
+
+ /**
+ * Returns {@code true} if the recording is in progress, otherwise @{code false}.
+ */
+ public boolean isInProgress() {
+ return mState == STATE_RECORDING_IN_PROGRESS;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ScheduledRecording)) {
+ return false;
+ }
+ ScheduledRecording r = (ScheduledRecording) obj;
+ return mId == r.mId
+ && mPriority == r.mPriority
+ && mChannelId == r.mChannelId
+ && mProgramId == r.mProgramId
+ && Objects.equals(mProgramTitle, r.mProgramTitle)
+ && mType == r.mType
+ && mStartTimeMs == r.mStartTimeMs
+ && mEndTimeMs == r.mEndTimeMs
+ && Objects.equals(mSeasonNumber, r.mSeasonNumber)
+ && Objects.equals(mEpisodeNumber, r.mEpisodeNumber)
+ && Objects.equals(mEpisodeTitle, r.mEpisodeTitle)
+ && Objects.equals(mProgramDescription, r.getProgramDescription())
+ && Objects.equals(mProgramLongDescription, r.getProgramLongDescription())
+ && Objects.equals(mProgramPosterArtUri, r.getProgramPosterArtUri())
+ && Objects.equals(mProgramThumbnailUri, r.getProgramThumbnailUri())
+ && mState == r.mState
+ && mSeriesRecordingId == r.mSeriesRecordingId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId, mPriority, mChannelId, mProgramId, mProgramTitle, mType,
+ mStartTimeMs, mEndTimeMs, mSeasonNumber, mEpisodeNumber, mEpisodeTitle,
+ mProgramDescription, mProgramLongDescription, mProgramPosterArtUri,
+ mProgramThumbnailUri, mState, mSeriesRecordingId);
+ }
+
+ /**
+ * Returns an array containing all of the elements in the list.
+ */
+ public static ScheduledRecording[] toArray(Collection<ScheduledRecording> schedules) {
+ return schedules.toArray(new ScheduledRecording[schedules.size()]);
+ }
+}
diff --git a/src/com/android/tv/dvr/data/SeasonEpisodeNumber.java b/src/com/android/tv/dvr/data/SeasonEpisodeNumber.java
new file mode 100644
index 00000000..89533dbb
--- /dev/null
+++ b/src/com/android/tv/dvr/data/SeasonEpisodeNumber.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.data;
+
+import android.text.TextUtils;
+
+import java.util.Objects;
+
+/**
+ * A plain java object which includes the season/episode number for the series recording.
+ */
+public class SeasonEpisodeNumber {
+ public final long seriesRecordingId;
+ public final String seasonNumber;
+ public final String episodeNumber;
+
+ /**
+ * Creates a new Builder with the values set from an existing {@link ScheduledRecording}.
+ */
+ public SeasonEpisodeNumber(ScheduledRecording r) {
+ this(r.getSeriesRecordingId(), r.getSeasonNumber(), r.getEpisodeNumber());
+ }
+
+ public SeasonEpisodeNumber(long seriesRecordingId, String seasonNumber, String episodeNumber) {
+ this.seriesRecordingId = seriesRecordingId;
+ this.seasonNumber = seasonNumber;
+ this.episodeNumber = episodeNumber;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SeasonEpisodeNumber)
+ || TextUtils.isEmpty(seasonNumber) || TextUtils.isEmpty(episodeNumber)) {
+ return false;
+ }
+ SeasonEpisodeNumber that = (SeasonEpisodeNumber) o;
+ return seriesRecordingId == that.seriesRecordingId
+ && Objects.equals(seasonNumber, that.seasonNumber)
+ && Objects.equals(episodeNumber, that.episodeNumber);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(seriesRecordingId, seasonNumber, episodeNumber);
+ }
+
+ @Override
+ public String toString() {
+ return "SeasonEpisodeNumber{" +
+ "seriesRecordingId=" + seriesRecordingId +
+ ", seasonNumber='" + seasonNumber +
+ ", episodeNumber=" + episodeNumber +
+ '}';
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/data/SeriesInfo.java b/src/com/android/tv/dvr/data/SeriesInfo.java
new file mode 100644
index 00000000..a0dec4a4
--- /dev/null
+++ b/src/com/android/tv/dvr/data/SeriesInfo.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.data;
+
+/**
+ * Series information.
+ */
+public class SeriesInfo {
+ private final String mId;
+ private final String mTitle;
+ private final String mDescription;
+ private final String mLongDescription;
+ private final int[] mCanonicalGenreIds;
+ private final String mPosterUri;
+ private final String mPhotoUri;
+
+ public SeriesInfo(String id, String title, String description, String longDescription,
+ int[] canonicalGenreIds, String posterUri, String photoUri) {
+ this.mId = id;
+ this.mTitle = title;
+ this.mDescription = description;
+ this.mLongDescription = longDescription;
+ this.mCanonicalGenreIds = canonicalGenreIds;
+ this.mPosterUri = posterUri;
+ this.mPhotoUri = photoUri;
+ }
+
+ /** Returns the ID. **/
+ public String getId() {
+ return mId;
+ }
+
+ /** Returns the title. **/
+ public String getTitle() {
+ return mTitle;
+ }
+
+ /** Returns the description. **/
+ public String getDescription() {
+ return mDescription;
+ }
+
+ /** Returns the description. **/
+ public String getLongDescription() {
+ return mLongDescription;
+ }
+
+ /** Returns the canonical genre IDs. **/
+ public int[] getCanonicalGenreIds() {
+ return mCanonicalGenreIds;
+ }
+
+ /** Returns the poster URI. **/
+ public String getPosterUri() {
+ return mPosterUri;
+ }
+
+ /** Returns the photo URI. **/
+ public String getPhotoUri() {
+ return mPhotoUri;
+ }
+}
diff --git a/src/com/android/tv/dvr/data/SeriesRecording.java b/src/com/android/tv/dvr/data/SeriesRecording.java
new file mode 100644
index 00000000..822e7320
--- /dev/null
+++ b/src/com/android/tv/dvr/data/SeriesRecording.java
@@ -0,0 +1,755 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.data;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.IntDef;
+import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
+
+import com.android.tv.data.BaseProgram;
+import com.android.tv.data.Program;
+import com.android.tv.dvr.DvrScheduleManager;
+import com.android.tv.dvr.provider.DvrContract.SeriesRecordings;
+import com.android.tv.util.Utils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Objects;
+
+/**
+ * Schedules the recording of a Series of Programs.
+ *
+ * <p>
+ * Contains the data needed to create new ScheduleRecordings as the programs become available in
+ * the EPG.
+ */
+public class SeriesRecording implements Parcelable {
+ /**
+ * Indicates that the ID is not assigned yet.
+ */
+ public static final long ID_NOT_SET = 0;
+
+ /**
+ * The default priority of this recording.
+ */
+ public static final long DEFAULT_PRIORITY = Long.MAX_VALUE >> 1;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true,
+ value = {OPTION_CHANNEL_ONE, OPTION_CHANNEL_ALL})
+ public @interface ChannelOption {}
+ /**
+ * An option which indicates that the episodes in one channel are recorded.
+ */
+ public static final int OPTION_CHANNEL_ONE = 0;
+ /**
+ * An option which indicates that the episodes in all the channels are recorded.
+ */
+ public static final int OPTION_CHANNEL_ALL = 1;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true,
+ value = {STATE_SERIES_NORMAL, STATE_SERIES_STOPPED})
+ public @interface SeriesState {}
+
+ /**
+ * The state indicates that the series recording is a normal one.
+ */
+ public static final int STATE_SERIES_NORMAL = 0;
+
+ /**
+ * The state indicates that the series recording is stopped.
+ */
+ public static final int STATE_SERIES_STOPPED = 1;
+
+ /**
+ * Compare priority in descending order.
+ */
+ public static final Comparator<SeriesRecording> PRIORITY_COMPARATOR =
+ new Comparator<SeriesRecording>() {
+ @Override
+ public int compare(SeriesRecording lhs, SeriesRecording rhs) {
+ int value = Long.compare(rhs.mPriority, lhs.mPriority);
+ if (value == 0) {
+ // New recording has the higher priority.
+ value = Long.compare(rhs.mId, lhs.mId);
+ }
+ return value;
+ }
+ };
+
+ /**
+ * Compare ID in ascending order.
+ */
+ public static final Comparator<SeriesRecording> ID_COMPARATOR =
+ new Comparator<SeriesRecording>() {
+ @Override
+ public int compare(SeriesRecording lhs, SeriesRecording rhs) {
+ return Long.compare(lhs.mId, rhs.mId);
+ }
+ };
+
+ /**
+ * Creates a new Builder with the values set from the series information of {@link BaseProgram}.
+ */
+ public static Builder builder(String inputId, BaseProgram p) {
+ return new Builder()
+ .setInputId(inputId)
+ .setSeriesId(p.getSeriesId())
+ .setChannelId(p.getChannelId())
+ .setTitle(p.getTitle())
+ .setDescription(p.getDescription())
+ .setLongDescription(p.getLongDescription())
+ .setCanonicalGenreIds(p.getCanonicalGenreIds())
+ .setPosterUri(p.getPosterArtUri())
+ .setPhotoUri(p.getThumbnailUri());
+ }
+
+ /**
+ * Creates a new Builder with the values set from an existing {@link SeriesRecording}.
+ */
+ public static Builder buildFrom(SeriesRecording r) {
+ return new Builder()
+ .setId(r.mId)
+ .setInputId(r.getInputId())
+ .setChannelId(r.getChannelId())
+ .setPriority(r.getPriority())
+ .setTitle(r.getTitle())
+ .setDescription(r.getDescription())
+ .setLongDescription(r.getLongDescription())
+ .setSeriesId(r.getSeriesId())
+ .setStartFromEpisode(r.getStartFromEpisode())
+ .setStartFromSeason(r.getStartFromSeason())
+ .setChannelOption(r.getChannelOption())
+ .setCanonicalGenreIds(r.getCanonicalGenreIds())
+ .setPosterUri(r.getPosterUri())
+ .setPhotoUri(r.getPhotoUri())
+ .setState(r.getState());
+ }
+
+ /**
+ * Use this projection if you want to create {@link SeriesRecording} object using
+ * {@link #fromCursor}.
+ */
+ public static final String[] PROJECTION = {
+ // Columns must match what is read in fromCursor()
+ SeriesRecordings._ID,
+ SeriesRecordings.COLUMN_INPUT_ID,
+ SeriesRecordings.COLUMN_CHANNEL_ID,
+ SeriesRecordings.COLUMN_PRIORITY,
+ SeriesRecordings.COLUMN_TITLE,
+ SeriesRecordings.COLUMN_SHORT_DESCRIPTION,
+ SeriesRecordings.COLUMN_LONG_DESCRIPTION,
+ SeriesRecordings.COLUMN_SERIES_ID,
+ SeriesRecordings.COLUMN_START_FROM_EPISODE,
+ SeriesRecordings.COLUMN_START_FROM_SEASON,
+ SeriesRecordings.COLUMN_CHANNEL_OPTION,
+ SeriesRecordings.COLUMN_CANONICAL_GENRE,
+ SeriesRecordings.COLUMN_POSTER_URI,
+ SeriesRecordings.COLUMN_PHOTO_URI,
+ SeriesRecordings.COLUMN_STATE
+ };
+ /**
+ * Creates {@link SeriesRecording} object from the given {@link Cursor}.
+ */
+ public static SeriesRecording fromCursor(Cursor c) {
+ int index = -1;
+ return new Builder()
+ .setId(c.getLong(++index))
+ .setInputId(c.getString(++index))
+ .setChannelId(c.getLong(++index))
+ .setPriority(c.getLong(++index))
+ .setTitle(c.getString(++index))
+ .setDescription(c.getString(++index))
+ .setLongDescription(c.getString(++index))
+ .setSeriesId(c.getString(++index))
+ .setStartFromEpisode(c.getInt(++index))
+ .setStartFromSeason(c.getInt(++index))
+ .setChannelOption(channelOption(c.getString(++index)))
+ .setCanonicalGenreIds(c.getString(++index))
+ .setPosterUri(c.getString(++index))
+ .setPhotoUri(c.getString(++index))
+ .setState(seriesRecordingState(c.getString(++index)))
+ .build();
+ }
+
+ /**
+ * Returns the ContentValues with keys as the columns specified in {@link SeriesRecordings}
+ * and the values from {@code r}.
+ */
+ public static ContentValues toContentValues(SeriesRecording r) {
+ ContentValues values = new ContentValues();
+ if (r.getId() != ID_NOT_SET) {
+ values.put(SeriesRecordings._ID, r.getId());
+ } else {
+ values.putNull(SeriesRecordings._ID);
+ }
+ values.put(SeriesRecordings.COLUMN_INPUT_ID, r.getInputId());
+ values.put(SeriesRecordings.COLUMN_CHANNEL_ID, r.getChannelId());
+ values.put(SeriesRecordings.COLUMN_PRIORITY, r.getPriority());
+ values.put(SeriesRecordings.COLUMN_TITLE, r.getTitle());
+ values.put(SeriesRecordings.COLUMN_SHORT_DESCRIPTION, r.getDescription());
+ values.put(SeriesRecordings.COLUMN_LONG_DESCRIPTION, r.getLongDescription());
+ values.put(SeriesRecordings.COLUMN_SERIES_ID, r.getSeriesId());
+ values.put(SeriesRecordings.COLUMN_START_FROM_EPISODE, r.getStartFromEpisode());
+ values.put(SeriesRecordings.COLUMN_START_FROM_SEASON, r.getStartFromSeason());
+ values.put(SeriesRecordings.COLUMN_CHANNEL_OPTION,
+ channelOption(r.getChannelOption()));
+ values.put(SeriesRecordings.COLUMN_CANONICAL_GENRE,
+ Utils.getCanonicalGenre(r.getCanonicalGenreIds()));
+ values.put(SeriesRecordings.COLUMN_POSTER_URI, r.getPosterUri());
+ values.put(SeriesRecordings.COLUMN_PHOTO_URI, r.getPhotoUri());
+ values.put(SeriesRecordings.COLUMN_STATE, seriesRecordingState(r.getState()));
+ return values;
+ }
+
+ private static String channelOption(@ChannelOption int option) {
+ switch (option) {
+ case OPTION_CHANNEL_ONE:
+ return SeriesRecordings.OPTION_CHANNEL_ONE;
+ case OPTION_CHANNEL_ALL:
+ return SeriesRecordings.OPTION_CHANNEL_ALL;
+ }
+ return SeriesRecordings.OPTION_CHANNEL_ONE;
+ }
+
+ @ChannelOption private static int channelOption(String option) {
+ switch (option) {
+ case SeriesRecordings.OPTION_CHANNEL_ONE:
+ return OPTION_CHANNEL_ONE;
+ case SeriesRecordings.OPTION_CHANNEL_ALL:
+ return OPTION_CHANNEL_ALL;
+ }
+ return OPTION_CHANNEL_ONE;
+ }
+
+ private static String seriesRecordingState(@SeriesState int state) {
+ switch (state) {
+ case STATE_SERIES_NORMAL:
+ return SeriesRecordings.STATE_SERIES_NORMAL;
+ case STATE_SERIES_STOPPED:
+ return SeriesRecordings.STATE_SERIES_STOPPED;
+ }
+ return SeriesRecordings.STATE_SERIES_NORMAL;
+ }
+
+ @SeriesState private static int seriesRecordingState(String state) {
+ switch (state) {
+ case SeriesRecordings.STATE_SERIES_NORMAL:
+ return STATE_SERIES_NORMAL;
+ case SeriesRecordings.STATE_SERIES_STOPPED:
+ return STATE_SERIES_STOPPED;
+ }
+ return STATE_SERIES_NORMAL;
+ }
+
+ /**
+ * Builder for {@link SeriesRecording}.
+ */
+ public static class Builder {
+ private long mId = ID_NOT_SET;
+ private long mPriority = DvrScheduleManager.DEFAULT_SERIES_PRIORITY;
+ private String mTitle;
+ private String mDescription;
+ private String mLongDescription;
+ private String mInputId;
+ private long mChannelId;
+ private String mSeriesId;
+ private int mStartFromSeason = SeriesRecordings.THE_BEGINNING;
+ private int mStartFromEpisode = SeriesRecordings.THE_BEGINNING;
+ private int mChannelOption = OPTION_CHANNEL_ONE;
+ private int[] mCanonicalGenreIds;
+ private String mPosterUri;
+ private String mPhotoUri;
+ private int mState = SeriesRecording.STATE_SERIES_NORMAL;
+
+ /**
+ * @see #getId()
+ */
+ public Builder setId(long id) {
+ mId = id;
+ return this;
+ }
+
+ /**
+ * @see #getPriority() ()
+ */
+ public Builder setPriority(long priority) {
+ mPriority = priority;
+ return this;
+ }
+
+ /**
+ * @see #getTitle()
+ */
+ public Builder setTitle(String title) {
+ mTitle = title;
+ return this;
+ }
+
+ /**
+ * @see #getDescription()
+ */
+ public Builder setDescription(String description) {
+ mDescription = description;
+ return this;
+ }
+
+ /**
+ * @see #getLongDescription()
+ */
+ public Builder setLongDescription(String longDescription) {
+ mLongDescription = longDescription;
+ return this;
+ }
+
+ /**
+ * @see #getInputId()
+ */
+ public Builder setInputId(String inputId) {
+ mInputId = inputId;
+ return this;
+ }
+
+ /**
+ * @see #getChannelId()
+ */
+ public Builder setChannelId(long channelId) {
+ mChannelId = channelId;
+ return this;
+ }
+
+ /**
+ * @see #getSeriesId()
+ */
+ public Builder setSeriesId(String seriesId) {
+ mSeriesId = seriesId;
+ return this;
+ }
+
+ /**
+ * @see #getStartFromSeason()
+ */
+ public Builder setStartFromSeason(int startFromSeason) {
+ mStartFromSeason = startFromSeason;
+ return this;
+ }
+
+ /**
+ * @see #getChannelOption()
+ */
+ public Builder setChannelOption(@ChannelOption int option) {
+ mChannelOption = option;
+ return this;
+ }
+
+ /**
+ * @see #getStartFromEpisode()
+ */
+ public Builder setStartFromEpisode(int startFromEpisode) {
+ mStartFromEpisode = startFromEpisode;
+ return this;
+ }
+
+ /**
+ * @see #getCanonicalGenreIds()
+ */
+ public Builder setCanonicalGenreIds(String genres) {
+ mCanonicalGenreIds = Utils.getCanonicalGenreIds(genres);
+ return this;
+ }
+
+ /**
+ * @see #getCanonicalGenreIds()
+ */
+ public Builder setCanonicalGenreIds(int[] canonicalGenreIds) {
+ mCanonicalGenreIds = canonicalGenreIds;
+ return this;
+ }
+
+ /**
+ * @see #getPosterUri()
+ */
+ public Builder setPosterUri(String posterUri) {
+ mPosterUri = posterUri;
+ return this;
+ }
+
+ /**
+ * @see #getPhotoUri()
+ */
+ public Builder setPhotoUri(String photoUri) {
+ mPhotoUri = photoUri;
+ return this;
+ }
+
+ /**
+ * @see #getState()
+ */
+ public Builder setState(@SeriesState int state) {
+ mState = state;
+ return this;
+ }
+
+ /**
+ * Creates a new {@link SeriesRecording}.
+ */
+ public SeriesRecording build() {
+ return new SeriesRecording(mId, mPriority, mTitle, mDescription, mLongDescription,
+ mInputId, mChannelId, mSeriesId, mStartFromSeason, mStartFromEpisode,
+ mChannelOption, mCanonicalGenreIds, mPosterUri, mPhotoUri, mState);
+ }
+ }
+
+ public static SeriesRecording fromParcel(Parcel in) {
+ return new Builder()
+ .setId(in.readLong())
+ .setPriority(in.readLong())
+ .setTitle(in.readString())
+ .setDescription(in.readString())
+ .setLongDescription(in.readString())
+ .setInputId(in.readString())
+ .setChannelId(in.readLong())
+ .setSeriesId(in.readString())
+ .setStartFromSeason(in.readInt())
+ .setStartFromEpisode(in.readInt())
+ .setChannelOption(in.readInt())
+ .setCanonicalGenreIds(in.createIntArray())
+ .setPosterUri(in.readString())
+ .setPhotoUri(in.readString())
+ .setState(in.readInt())
+ .build();
+ }
+
+ public static final Parcelable.Creator<SeriesRecording> CREATOR =
+ new Parcelable.Creator<SeriesRecording>() {
+ @Override
+ public SeriesRecording createFromParcel(Parcel in) {
+ return SeriesRecording.fromParcel(in);
+ }
+
+ @Override
+ public SeriesRecording[] newArray(int size) {
+ return new SeriesRecording[size];
+ }
+ };
+
+ private long mId;
+ private final long mPriority;
+ private final String mTitle;
+ private final String mDescription;
+ private final String mLongDescription;
+ private final String mInputId;
+ private final long mChannelId;
+ private final String mSeriesId;
+ private final int mStartFromSeason;
+ private final int mStartFromEpisode;
+ @ChannelOption private final int mChannelOption;
+ private final int[] mCanonicalGenreIds;
+ private final String mPosterUri;
+ private final String mPhotoUri;
+ @SeriesState private int mState;
+
+ /**
+ * The input id of this SeriesRecording.
+ */
+ public String getInputId() {
+ return mInputId;
+ }
+
+ /**
+ * The channelId to match. The channel ID might not be valid when the channel option is "ALL".
+ */
+ public long getChannelId() {
+ return mChannelId;
+ }
+
+ /**
+ * The id of this SeriesRecording.
+ */
+ public long getId() {
+ return mId;
+ }
+
+ /**
+ * Sets the ID.
+ */
+ public void setId(long id) {
+ mId = id;
+ }
+
+ /**
+ * The priority of this recording.
+ *
+ * <p> The highest number is recorded first. If there is a tie in mPriority then the higher mId
+ * wins.
+ */
+ public long getPriority() {
+ return mPriority;
+ }
+
+ /**
+ * The series title.
+ */
+ public String getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * The series description.
+ */
+ public String getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * The long series description.
+ */
+ public String getLongDescription() {
+ return mLongDescription;
+ }
+
+ /**
+ * SeriesId when not null is used to match programs instead of using title and channelId.
+ *
+ * <p>SeriesId is an opaque but stable string.
+ */
+ public String getSeriesId() {
+ return mSeriesId;
+ }
+
+ /**
+ * If not == {@link SeriesRecordings#THE_BEGINNING} and seasonNumber == startFromSeason then
+ * only record episodes with a episodeNumber >= this
+ */
+ public int getStartFromEpisode() {
+ return mStartFromEpisode;
+ }
+
+ /**
+ * If not == {@link SeriesRecordings#THE_BEGINNING} then only record episodes with a
+ * seasonNumber >= this
+ */
+ public int getStartFromSeason() {
+ return mStartFromSeason;
+ }
+
+ /**
+ * Returns the channel recording option.
+ */
+ @ChannelOption public int getChannelOption() {
+ return mChannelOption;
+ }
+
+ /**
+ * Returns the canonical genre ID's.
+ */
+ public int[] getCanonicalGenreIds() {
+ return mCanonicalGenreIds;
+ }
+
+ /**
+ * Returns the poster URI.
+ */
+ public String getPosterUri() {
+ return mPosterUri;
+ }
+
+ /**
+ * Returns the photo URI.
+ */
+ public String getPhotoUri() {
+ return mPhotoUri;
+ }
+
+ /**
+ * Returns the state of series recording.
+ */
+ @SeriesState public int getState() {
+ return mState;
+ }
+
+ /**
+ * Checks whether the series recording is stopped or not.
+ */
+ public boolean isStopped() {
+ return mState == STATE_SERIES_STOPPED;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SeriesRecording)) return false;
+ SeriesRecording that = (SeriesRecording) o;
+ return mPriority == that.mPriority
+ && mChannelId == that.mChannelId
+ && mStartFromSeason == that.mStartFromSeason
+ && mStartFromEpisode == that.mStartFromEpisode
+ && Objects.equals(mId, that.mId)
+ && Objects.equals(mTitle, that.mTitle)
+ && Objects.equals(mDescription, that.mDescription)
+ && Objects.equals(mLongDescription, that.mLongDescription)
+ && Objects.equals(mSeriesId, that.mSeriesId)
+ && mChannelOption == that.mChannelOption
+ && Arrays.equals(mCanonicalGenreIds, that.mCanonicalGenreIds)
+ && Objects.equals(mPosterUri, that.mPosterUri)
+ && Objects.equals(mPhotoUri, that.mPhotoUri)
+ && mState == that.mState;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPriority, mChannelId, mStartFromSeason, mStartFromEpisode, mId,
+ mTitle, mDescription, mLongDescription, mSeriesId, mChannelOption,
+ mCanonicalGenreIds, mPosterUri, mPhotoUri, mState);
+ }
+
+ @Override
+ public String toString() {
+ return "SeriesRecording{" +
+ "inputId=" + mInputId +
+ ", channelId=" + mChannelId +
+ ", id='" + mId + '\'' +
+ ", priority=" + mPriority +
+ ", title='" + mTitle + '\'' +
+ ", description='" + mDescription + '\'' +
+ ", longDescription='" + mLongDescription + '\'' +
+ ", startFromSeason=" + mStartFromSeason +
+ ", startFromEpisode=" + mStartFromEpisode +
+ ", channelOption=" + mChannelOption +
+ ", canonicalGenreIds=" + Arrays.toString(mCanonicalGenreIds) +
+ ", posterUri=" + mPosterUri +
+ ", photoUri=" + mPhotoUri +
+ ", state=" + mState +
+ '}';
+ }
+
+ private SeriesRecording(long id, long priority, String title, String description,
+ String longDescription, String inputId, long channelId, String seriesId,
+ int startFromSeason, int startFromEpisode, int channelOption, int[] canonicalGenreIds,
+ String posterUri, String photoUri, int state) {
+ this.mId = id;
+ this.mPriority = priority;
+ this.mTitle = title;
+ this.mDescription = description;
+ this.mLongDescription = longDescription;
+ this.mInputId = inputId;
+ this.mChannelId = channelId;
+ this.mSeriesId = seriesId;
+ this.mStartFromSeason = startFromSeason;
+ this.mStartFromEpisode = startFromEpisode;
+ this.mChannelOption = channelOption;
+ this.mCanonicalGenreIds = canonicalGenreIds;
+ this.mPosterUri = posterUri;
+ this.mPhotoUri = photoUri;
+ this.mState = state;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int paramInt) {
+ out.writeLong(mId);
+ out.writeLong(mPriority);
+ out.writeString(mTitle);
+ out.writeString(mDescription);
+ out.writeString(mLongDescription);
+ out.writeString(mInputId);
+ out.writeLong(mChannelId);
+ out.writeString(mSeriesId);
+ out.writeInt(mStartFromSeason);
+ out.writeInt(mStartFromEpisode);
+ out.writeInt(mChannelOption);
+ out.writeIntArray(mCanonicalGenreIds);
+ out.writeString(mPosterUri);
+ out.writeString(mPhotoUri);
+ out.writeInt(mState);
+ }
+
+ /**
+ * Returns an array containing all of the elements in the list.
+ */
+ public static SeriesRecording[] toArray(Collection<SeriesRecording> series) {
+ return series.toArray(new SeriesRecording[series.size()]);
+ }
+
+ /**
+ * Returns {@code true} if the {@code program} is part of the series and meets the season and
+ * episode constraints.
+ */
+ public boolean matchProgram(Program program) {
+ return matchProgram(program, mChannelOption);
+ }
+
+ /**
+ * Returns {@code true} if the {@code program} is part of the series and meets the season and
+ * episode constraints. It checks the channel option only if {@code checkChannelOption} is
+ * {@code true}.
+ */
+ public boolean matchProgram(Program program, @ChannelOption int channelOption) {
+ String seriesId = program.getSeriesId();
+ long channelId = program.getChannelId();
+ String seasonNumber = program.getSeasonNumber();
+ String episodeNumber = program.getEpisodeNumber();
+ if (!mSeriesId.equals(seriesId) || (channelOption == SeriesRecording.OPTION_CHANNEL_ONE
+ && mChannelId != channelId)) {
+ return false;
+ }
+ // Season number and episode number matches if
+ // start_season_number < program_season_number
+ // || (start_season_number == program_season_number
+ // && start_episode_number <= program_episode_number).
+ if (mStartFromSeason == SeriesRecordings.THE_BEGINNING
+ || TextUtils.isEmpty(seasonNumber)) {
+ return true;
+ } else {
+ int intSeasonNumber;
+ try {
+ intSeasonNumber = Integer.valueOf(seasonNumber);
+ } catch (NumberFormatException e) {
+ return true;
+ }
+ if (intSeasonNumber > mStartFromSeason) {
+ return true;
+ } else if (intSeasonNumber < mStartFromSeason) {
+ return false;
+ }
+ }
+ if (mStartFromEpisode == SeriesRecordings.THE_BEGINNING
+ || TextUtils.isEmpty(episodeNumber)) {
+ return true;
+ } else {
+ int intEpisodeNumber;
+ try {
+ intEpisodeNumber = Integer.valueOf(episodeNumber);
+ } catch (NumberFormatException e) {
+ return true;
+ }
+ return intEpisodeNumber >= mStartFromEpisode;
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/provider/AsyncDvrDbTask.java b/src/com/android/tv/dvr/provider/AsyncDvrDbTask.java
index 1a12fb23..c5383d02 100644
--- a/src/com/android/tv/dvr/provider/AsyncDvrDbTask.java
+++ b/src/com/android/tv/dvr/provider/AsyncDvrDbTask.java
@@ -21,8 +21,8 @@ import android.database.Cursor;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.DvrContract.Schedules;
import com.android.tv.dvr.provider.DvrContract.SeriesRecordings;
import com.android.tv.util.NamedThreadFactory;
diff --git a/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java b/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
index 2f16ba5d..8b9481a9 100644
--- a/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
+++ b/src/com/android/tv/dvr/provider/DvrDatabaseHelper.java
@@ -27,8 +27,8 @@ import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.provider.DvrContract.Schedules;
import com.android.tv.dvr.provider.DvrContract.SeriesRecordings;
diff --git a/src/com/android/tv/dvr/provider/DvrDbSync.java b/src/com/android/tv/dvr/provider/DvrDbSync.java
new file mode 100644
index 00000000..ff391959
--- /dev/null
+++ b/src/com/android/tv/dvr/provider/DvrDbSync.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.provider;
+
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.ContentUris;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.media.tv.TvContract.Programs;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.MainThread;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import com.android.tv.TvApplication;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.Program;
+import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
+import com.android.tv.dvr.DvrDataManagerImpl;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
+import com.android.tv.util.AsyncDbTask.AsyncQueryProgramTask;
+import com.android.tv.util.TvUriMatcher;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Queue;
+import java.util.Set;
+
+/**
+ * A class to synchronizes DVR DB with TvProvider.
+ *
+ * <p>The current implementation of AsyncDbTask allows only one task to run at a time, and all the
+ * other tasks are blocked until the current one finishes. As this class performs the low priority
+ * jobs which take long time, it should not block others if possible. For this reason, only one
+ * program is queried at a time and others are queued and will be executed on the other
+ * AsyncDbTask's after the current one finishes to minimize the execution time of one AsyncDbTask.
+ */
+@MainThread
+@TargetApi(Build.VERSION_CODES.N)
+public class DvrDbSync {
+ private static final String TAG = "DvrDbSync";
+ private static final boolean DEBUG = false;
+
+ private final Context mContext;
+ private final DvrManager mDvrManager;
+ private final DvrDataManagerImpl mDataManager;
+ private final ChannelDataManager mChannelDataManager;
+ private final Queue<Long> mProgramIdQueue = new LinkedList<>();
+ private QueryProgramTask mQueryProgramTask;
+ private final SeriesRecordingScheduler mSeriesRecordingScheduler;
+ private final ContentObserver mContentObserver = new ContentObserver(new Handler(
+ Looper.getMainLooper())) {
+ @SuppressLint("SwitchIntDef")
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ switch (TvUriMatcher.match(uri)) {
+ case TvUriMatcher.MATCH_PROGRAM:
+ if (DEBUG) Log.d(TAG, "onProgramsUpdated");
+ onProgramsUpdated();
+ break;
+ case TvUriMatcher.MATCH_PROGRAM_ID:
+ if (DEBUG) {
+ Log.d(TAG, "onProgramUpdated: programId=" + ContentUris.parseId(uri));
+ }
+ onProgramUpdated(ContentUris.parseId(uri));
+ break;
+ }
+ }
+ };
+
+ private final ChannelDataManager.Listener mChannelDataManagerListener =
+ new ChannelDataManager.Listener() {
+ @Override
+ public void onLoadFinished() {
+ start();
+ }
+
+ @Override
+ public void onChannelListUpdated() {
+ onChannelsUpdated();
+ }
+
+ @Override
+ public void onChannelBrowsableChanged() { }
+ };
+
+ private final ScheduledRecordingListener mScheduleListener = new ScheduledRecordingListener() {
+ @Override
+ public void onScheduledRecordingAdded(ScheduledRecording... schedules) {
+ for (ScheduledRecording schedule : schedules) {
+ addProgramIdToCheckIfNeeded(schedule);
+ }
+ startNextUpdateIfNeeded();
+ }
+
+ @Override
+ public void onScheduledRecordingRemoved(ScheduledRecording... schedules) {
+ for (ScheduledRecording schedule : schedules) {
+ mProgramIdQueue.remove(schedule.getProgramId());
+ }
+ }
+
+ @Override
+ public void onScheduledRecordingStatusChanged(ScheduledRecording... schedules) {
+ for (ScheduledRecording schedule : schedules) {
+ mProgramIdQueue.remove(schedule.getProgramId());
+ addProgramIdToCheckIfNeeded(schedule);
+ }
+ startNextUpdateIfNeeded();
+ }
+ };
+
+ public DvrDbSync(Context context, DvrDataManagerImpl dataManager) {
+ this(context, dataManager, TvApplication.getSingletons(context).getChannelDataManager(),
+ TvApplication.getSingletons(context).getDvrManager(),
+ SeriesRecordingScheduler.getInstance(context));
+ }
+
+ @VisibleForTesting
+ DvrDbSync(Context context, DvrDataManagerImpl dataManager,
+ ChannelDataManager channelDataManager, DvrManager dvrManager,
+ SeriesRecordingScheduler seriesRecordingScheduler) {
+ mContext = context;
+ mDvrManager = dvrManager;
+ mDataManager = dataManager;
+ mChannelDataManager = channelDataManager;
+ mSeriesRecordingScheduler = seriesRecordingScheduler;
+ }
+
+ /**
+ * Starts the DB sync.
+ */
+ public void start() {
+ if (!mChannelDataManager.isDbLoadFinished()) {
+ mChannelDataManager.addListener(mChannelDataManagerListener);
+ return;
+ }
+ mContext.getContentResolver().registerContentObserver(Programs.CONTENT_URI, true,
+ mContentObserver);
+ mDataManager.addScheduledRecordingListener(mScheduleListener);
+ onChannelsUpdated();
+ onProgramsUpdated();
+ }
+
+ /**
+ * Stops the DB sync.
+ */
+ public void stop() {
+ mProgramIdQueue.clear();
+ if (mQueryProgramTask != null) {
+ mQueryProgramTask.cancel(true);
+ }
+ mChannelDataManager.removeListener(mChannelDataManagerListener);
+ mDataManager.removeScheduledRecordingListener(mScheduleListener);
+ mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+ }
+
+ private void onChannelsUpdated() {
+ List<SeriesRecording> seriesRecordingsToUpdate = new ArrayList<>();
+ for (SeriesRecording r : mDataManager.getSeriesRecordings()) {
+ if (r.getChannelOption() == SeriesRecording.OPTION_CHANNEL_ONE
+ && !mChannelDataManager.doesChannelExistInDb(r.getChannelId())) {
+ seriesRecordingsToUpdate.add(SeriesRecording.buildFrom(r)
+ .setChannelOption(SeriesRecording.OPTION_CHANNEL_ALL)
+ .setState(SeriesRecording.STATE_SERIES_STOPPED).build());
+ }
+ }
+ if (!seriesRecordingsToUpdate.isEmpty()) {
+ mDataManager.updateSeriesRecording(
+ SeriesRecording.toArray(seriesRecordingsToUpdate));
+ }
+ List<ScheduledRecording> schedulesToRemove = new ArrayList<>();
+ for (ScheduledRecording r : mDataManager.getAvailableScheduledRecordings()) {
+ if (!mChannelDataManager.doesChannelExistInDb(r.getChannelId())) {
+ schedulesToRemove.add(r);
+ mProgramIdQueue.remove(r.getProgramId());
+ }
+ }
+ if (!schedulesToRemove.isEmpty()) {
+ mDataManager.removeScheduledRecording(
+ ScheduledRecording.toArray(schedulesToRemove));
+ }
+ }
+
+ private void onProgramsUpdated() {
+ for (ScheduledRecording schedule : mDataManager.getAvailableScheduledRecordings()) {
+ addProgramIdToCheckIfNeeded(schedule);
+ }
+ startNextUpdateIfNeeded();
+ }
+
+ private void onProgramUpdated(long programId) {
+ addProgramIdToCheckIfNeeded(mDataManager.getScheduledRecordingForProgramId(programId));
+ startNextUpdateIfNeeded();
+ }
+
+ private void addProgramIdToCheckIfNeeded(ScheduledRecording schedule) {
+ if (schedule == null) {
+ return;
+ }
+ long programId = schedule.getProgramId();
+ if (programId != ScheduledRecording.ID_NOT_SET
+ && !mProgramIdQueue.contains(programId)
+ && (schedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED
+ || schedule.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS)) {
+ if (DEBUG) Log.d(TAG, "Program ID enqueued: " + programId);
+ mProgramIdQueue.offer(programId);
+ // There are schedules to be updated. Pause the SeriesRecordingScheduler until all the
+ // schedule updates finish.
+ // Note that the SeriesRecordingScheduler should be paused even though the program to
+ // check is not episodic because it can be changed to the episodic program after the
+ // update, which affect the SeriesRecordingScheduler.
+ mSeriesRecordingScheduler.pauseUpdate();
+ }
+ }
+
+ private void startNextUpdateIfNeeded() {
+ if (mQueryProgramTask != null && !mQueryProgramTask.isCancelled()) {
+ return;
+ }
+ if (!mProgramIdQueue.isEmpty()) {
+ if (DEBUG) Log.d(TAG, "Program ID dequeued: " + mProgramIdQueue.peek());
+ mQueryProgramTask = new QueryProgramTask(mProgramIdQueue.poll());
+ mQueryProgramTask.executeOnDbThread();
+ } else {
+ mSeriesRecordingScheduler.resumeUpdate();
+ }
+ }
+
+ @VisibleForTesting
+ void handleUpdateProgram(Program program, long programId) {
+ Set<SeriesRecording> seriesRecordingsToUpdate = new HashSet<>();
+ ScheduledRecording schedule = mDataManager.getScheduledRecordingForProgramId(programId);
+ if (schedule != null
+ && (schedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED
+ || schedule.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS)) {
+ if (program == null) {
+ mDataManager.removeScheduledRecording(schedule);
+ if (schedule.getSeriesRecordingId() != SeriesRecording.ID_NOT_SET) {
+ SeriesRecording seriesRecording =
+ mDataManager.getSeriesRecording(schedule.getSeriesRecordingId());
+ if (seriesRecording != null) {
+ seriesRecordingsToUpdate.add(seriesRecording);
+ }
+ }
+ } else {
+ long currentTimeMs = System.currentTimeMillis();
+ ScheduledRecording.Builder builder = ScheduledRecording.buildFrom(schedule)
+ .setEndTimeMs(program.getEndTimeUtcMillis())
+ .setSeasonNumber(program.getSeasonNumber())
+ .setEpisodeNumber(program.getEpisodeNumber())
+ .setEpisodeTitle(program.getEpisodeTitle())
+ .setProgramDescription(program.getDescription())
+ .setProgramLongDescription(program.getLongDescription())
+ .setProgramPosterArtUri(program.getPosterArtUri())
+ .setProgramThumbnailUri(program.getThumbnailUri());
+ boolean needUpdate = false;
+ // Check the series recording.
+ SeriesRecording seriesRecordingForOldSchedule =
+ mDataManager.getSeriesRecording(schedule.getSeriesRecordingId());
+ if (program.isEpisodic()) {
+ // New program belongs to a series.
+ SeriesRecording seriesRecording =
+ mDataManager.getSeriesRecording(program.getSeriesId());
+ if (seriesRecording == null) {
+ // The new program is episodic while the previous one isn't.
+ SeriesRecording newSeriesRecording = mDvrManager.addSeriesRecording(
+ program, Collections.singletonList(program),
+ SeriesRecording.STATE_SERIES_STOPPED);
+ builder.setSeriesRecordingId(newSeriesRecording.getId());
+ needUpdate = true;
+ } else if (seriesRecording.getId() != schedule.getSeriesRecordingId()) {
+ // The new program belongs to the other series.
+ builder.setSeriesRecordingId(seriesRecording.getId());
+ needUpdate = true;
+ seriesRecordingsToUpdate.add(seriesRecording);
+ if (seriesRecordingForOldSchedule != null) {
+ seriesRecordingsToUpdate.add(seriesRecordingForOldSchedule);
+ }
+ } else if (!Objects.equals(schedule.getSeasonNumber(),
+ program.getSeasonNumber())
+ || !Objects.equals(schedule.getEpisodeNumber(),
+ program.getEpisodeNumber())) {
+ // The episode number has been changed.
+ if (seriesRecordingForOldSchedule != null) {
+ seriesRecordingsToUpdate.add(seriesRecordingForOldSchedule);
+ }
+ }
+ } else if (seriesRecordingForOldSchedule != null) {
+ // Old program belongs to a series but the new one doesn't.
+ seriesRecordingsToUpdate.add(seriesRecordingForOldSchedule);
+ }
+ // Change start time only when the recording is not started yet.
+ boolean needToChangeStartTime =
+ schedule.getState() != ScheduledRecording.STATE_RECORDING_IN_PROGRESS
+ && program.getStartTimeUtcMillis() != schedule.getStartTimeMs();
+ if (needToChangeStartTime) {
+ builder.setStartTimeMs(program.getStartTimeUtcMillis());
+ needUpdate = true;
+ }
+ if (needUpdate || schedule.getEndTimeMs() != program.getEndTimeUtcMillis()
+ || !Objects.equals(schedule.getSeasonNumber(), program.getSeasonNumber())
+ || !Objects.equals(schedule.getEpisodeNumber(), program.getEpisodeNumber())
+ || !Objects.equals(schedule.getEpisodeTitle(), program.getEpisodeTitle())
+ || !Objects.equals(schedule.getProgramDescription(),
+ program.getDescription())
+ || !Objects.equals(schedule.getProgramLongDescription(),
+ program.getLongDescription())
+ || !Objects.equals(schedule.getProgramPosterArtUri(),
+ program.getPosterArtUri())
+ || !Objects.equals(schedule.getProgramThumbnailUri(),
+ program.getThumbnailUri())) {
+ mDataManager.updateScheduledRecording(builder.build());
+ }
+ if (!seriesRecordingsToUpdate.isEmpty()) {
+ // The series recordings will be updated after it's resumed.
+ mSeriesRecordingScheduler.updateSchedules(seriesRecordingsToUpdate);
+ }
+ }
+ }
+ }
+
+ private class QueryProgramTask extends AsyncQueryProgramTask {
+ private final long mProgramId;
+
+ QueryProgramTask(long programId) {
+ super(mContext.getContentResolver(), programId);
+ mProgramId = programId;
+ }
+
+ @Override
+ protected void onCancelled(Program program) {
+ if (mQueryProgramTask == this) {
+ mQueryProgramTask = null;
+ }
+ startNextUpdateIfNeeded();
+ }
+
+ @Override
+ protected void onPostExecute(Program program) {
+ if (mQueryProgramTask == this) {
+ mQueryProgramTask = null;
+ }
+ handleUpdateProgram(program, mProgramId);
+ startNextUpdateIfNeeded();
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java b/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java
new file mode 100644
index 00000000..ba0aca51
--- /dev/null
+++ b/src/com/android/tv/dvr/provider/EpisodicProgramLoadTask.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.provider;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.database.Cursor;
+import android.media.tv.TvContract;
+import android.media.tv.TvContract.Programs;
+import android.net.Uri;
+import android.os.Build;
+import android.support.annotation.Nullable;
+import android.support.annotation.WorkerThread;
+
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.data.Program;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.data.SeasonEpisodeNumber;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.util.AsyncDbTask.AsyncProgramQueryTask;
+import com.android.tv.util.AsyncDbTask.CursorFilter;
+import com.android.tv.util.PermissionUtils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A wrapper of AsyncProgramQueryTask to load the episodic programs for the series recordings.
+ */
+@TargetApi(Build.VERSION_CODES.N)
+abstract public class EpisodicProgramLoadTask {
+ private static final String TAG = "EpisodicProgramLoadTask";
+
+ private static final int PROGRAM_ID_INDEX = Program.getColumnIndex(Programs._ID);
+ private static final int START_TIME_INDEX =
+ Program.getColumnIndex(Programs.COLUMN_START_TIME_UTC_MILLIS);
+ private static final int RECORDING_PROHIBITED_INDEX =
+ Program.getColumnIndex(Programs.COLUMN_RECORDING_PROHIBITED);
+
+ private static final String PARAM_START_TIME = "start_time";
+ private static final String PARAM_END_TIME = "end_time";
+
+ private static final String PROGRAM_PREDICATE =
+ Programs.COLUMN_START_TIME_UTC_MILLIS + ">? AND "
+ + Programs.COLUMN_RECORDING_PROHIBITED + "=0";
+ private static final String PROGRAM_PREDICATE_WITH_CURRENT_PROGRAM =
+ Programs.COLUMN_END_TIME_UTC_MILLIS + ">? AND "
+ + Programs.COLUMN_RECORDING_PROHIBITED + "=0";
+ private static final String CHANNEL_ID_PREDICATE = Programs.COLUMN_CHANNEL_ID + "=?";
+ private static final String PROGRAM_TITLE_PREDICATE = Programs.COLUMN_TITLE + "=?";
+
+ private final Context mContext;
+ private final DvrDataManager mDataManager;
+ private boolean mQueryAllChannels;
+ private boolean mLoadCurrentProgram;
+ private boolean mLoadScheduledEpisode;
+ private boolean mLoadDisallowedProgram;
+ // If true, match programs with OPTION_CHANNEL_ALL.
+ private boolean mIgnoreChannelOption;
+ private final ArrayList<SeriesRecording> mSeriesRecordings = new ArrayList<>();
+ private AsyncProgramQueryTask mProgramQueryTask;
+
+ /**
+ *
+ * Constructor used to load programs for one series recording with the given channel option.
+ */
+ public EpisodicProgramLoadTask(Context context, SeriesRecording seriesRecording) {
+ this(context, Collections.singletonList(seriesRecording));
+ }
+
+ /**
+ * Constructor used to load programs for multiple series recordings. The channel option is
+ * {@link SeriesRecording#OPTION_CHANNEL_ALL}.
+ */
+ public EpisodicProgramLoadTask(Context context, Collection<SeriesRecording> seriesRecordings) {
+ mContext = context.getApplicationContext();
+ mDataManager = TvApplication.getSingletons(context).getDvrDataManager();
+ mSeriesRecordings.addAll(seriesRecordings);
+ }
+
+ /**
+ * Returns the series recordings.
+ */
+ public List<SeriesRecording> getSeriesRecordings() {
+ return mSeriesRecordings;
+ }
+
+ /**
+ * Returns the program query task. It is {@code null} until it is executed.
+ */
+ @Nullable
+ public AsyncProgramQueryTask getTask() {
+ return mProgramQueryTask;
+ }
+
+ /**
+ * Enables loading current programs. The default value is {@code false}.
+ */
+ public EpisodicProgramLoadTask setLoadCurrentProgram(boolean loadCurrentProgram) {
+ SoftPreconditions.checkState(mProgramQueryTask == null, TAG,
+ "Can't change setting after execution.");
+ mLoadCurrentProgram = loadCurrentProgram;
+ return this;
+ }
+
+ /**
+ * Enables already schedules episodes. The default value is {@code false}.
+ */
+ public EpisodicProgramLoadTask setLoadScheduledEpisode(boolean loadScheduledEpisode) {
+ SoftPreconditions.checkState(mProgramQueryTask == null, TAG,
+ "Can't change setting after execution.");
+ mLoadScheduledEpisode = loadScheduledEpisode;
+ return this;
+ }
+
+ /**
+ * Enables loading disallowed programs whose schedules were removed manually by the user.
+ * The default value is {@code false}.
+ */
+ public EpisodicProgramLoadTask setLoadDisallowedProgram(boolean loadDisallowedProgram) {
+ SoftPreconditions.checkState(mProgramQueryTask == null, TAG,
+ "Can't change setting after execution.");
+ mLoadDisallowedProgram = loadDisallowedProgram;
+ return this;
+ }
+
+ /**
+ * Gives the option whether to ignore the channel option when matching programs.
+ * If {@code ignoreChannelOption} is {@code true}, the program will be matched with
+ * {@link SeriesRecording#OPTION_CHANNEL_ALL} option.
+ */
+ public EpisodicProgramLoadTask setIgnoreChannelOption(boolean ignoreChannelOption) {
+ SoftPreconditions.checkState(mProgramQueryTask == null, TAG,
+ "Can't change setting after execution.");
+ mIgnoreChannelOption = ignoreChannelOption;
+ return this;
+ }
+
+ /**
+ * Executes the task.
+ *
+ * @see com.android.tv.util.AsyncDbTask#executeOnDbThread
+ */
+ public void execute() {
+ if (SoftPreconditions.checkState(mProgramQueryTask == null, TAG,
+ "Can't execute task: the task is already running.")) {
+ mQueryAllChannels = mSeriesRecordings.size() > 1
+ || mSeriesRecordings.get(0).getChannelOption()
+ == SeriesRecording.OPTION_CHANNEL_ALL
+ || mIgnoreChannelOption;
+ mProgramQueryTask = createTask();
+ mProgramQueryTask.executeOnDbThread();
+ }
+ }
+
+ /**
+ * Cancels the task.
+ *
+ * @see android.os.AsyncTask#cancel
+ */
+ public void cancel(boolean mayInterruptIfRunning) {
+ if (mProgramQueryTask != null) {
+ mProgramQueryTask.cancel(mayInterruptIfRunning);
+ }
+ }
+
+ /**
+ * Runs on the UI thread after the program loading finishes successfully.
+ */
+ protected void onPostExecute(List<Program> programs) {
+ }
+
+ /**
+ * Runs on the UI thread after the program loading was canceled.
+ */
+ protected void onCancelled(List<Program> programs) {
+ }
+
+ private AsyncProgramQueryTask createTask() {
+ SqlParams sqlParams = createSqlParams();
+ return new AsyncProgramQueryTask(mContext.getContentResolver(), sqlParams.uri,
+ sqlParams.selection, sqlParams.selectionArgs, null, sqlParams.filter) {
+ @Override
+ protected void onPostExecute(List<Program> programs) {
+ EpisodicProgramLoadTask.this.onPostExecute(programs);
+ }
+
+ @Override
+ protected void onCancelled(List<Program> programs) {
+ EpisodicProgramLoadTask.this.onCancelled(programs);
+ }
+ };
+ }
+
+ private SqlParams createSqlParams() {
+ SqlParams sqlParams = new SqlParams();
+ if (PermissionUtils.hasAccessAllEpg(mContext)) {
+ sqlParams.uri = Programs.CONTENT_URI;
+ // Base
+ StringBuilder selection = new StringBuilder(mLoadCurrentProgram
+ ? PROGRAM_PREDICATE_WITH_CURRENT_PROGRAM : PROGRAM_PREDICATE);
+ List<String> args = new ArrayList<>();
+ args.add(Long.toString(System.currentTimeMillis()));
+ // Channel option
+ if (!mQueryAllChannels) {
+ selection.append(" AND ").append(CHANNEL_ID_PREDICATE);
+ args.add(Long.toString(mSeriesRecordings.get(0).getChannelId()));
+ }
+ // Title
+ if (mSeriesRecordings.size() == 1) {
+ selection.append(" AND ").append(PROGRAM_TITLE_PREDICATE);
+ args.add(mSeriesRecordings.get(0).getTitle());
+ }
+ sqlParams.selection = selection.toString();
+ sqlParams.selectionArgs = args.toArray(new String[args.size()]);
+ sqlParams.filter = new SeriesRecordingCursorFilter(mSeriesRecordings);
+ } else {
+ // The query includes the current program. Will be filtered if needed.
+ if (mQueryAllChannels) {
+ sqlParams.uri = Programs.CONTENT_URI.buildUpon()
+ .appendQueryParameter(PARAM_START_TIME,
+ String.valueOf(System.currentTimeMillis()))
+ .appendQueryParameter(PARAM_END_TIME, String.valueOf(Long.MAX_VALUE))
+ .build();
+ } else {
+ sqlParams.uri = TvContract.buildProgramsUriForChannel(
+ mSeriesRecordings.get(0).getChannelId(),
+ System.currentTimeMillis(), Long.MAX_VALUE);
+ }
+ sqlParams.selection = null;
+ sqlParams.selectionArgs = null;
+ sqlParams.filter = new SeriesRecordingCursorFilterForNonSystem(mSeriesRecordings);
+ }
+ return sqlParams;
+ }
+
+ /**
+ * Filter the programs which match the series recording. The episodes which the schedules are
+ * already created for are filtered out too.
+ */
+ private class SeriesRecordingCursorFilter implements CursorFilter {
+ private final Set<Long> mDisallowedProgramIds = new HashSet<>();
+ private final Set<SeasonEpisodeNumber> mSeasonEpisodeNumbers = new HashSet<>();
+
+ SeriesRecordingCursorFilter(List<SeriesRecording> seriesRecordings) {
+ if (!mLoadDisallowedProgram) {
+ mDisallowedProgramIds.addAll(mDataManager.getDisallowedProgramIds());
+ }
+ if (!mLoadScheduledEpisode) {
+ Set<Long> seriesRecordingIds = new HashSet<>();
+ for (SeriesRecording r : seriesRecordings) {
+ seriesRecordingIds.add(r.getId());
+ }
+ for (ScheduledRecording r : mDataManager.getAllScheduledRecordings()) {
+ if (seriesRecordingIds.contains(r.getSeriesRecordingId())
+ && r.getState() != ScheduledRecording.STATE_RECORDING_FAILED
+ && r.getState() != ScheduledRecording.STATE_RECORDING_CLIPPED) {
+ mSeasonEpisodeNumbers.add(new SeasonEpisodeNumber(r));
+ }
+ }
+ }
+ }
+
+ @Override
+ @WorkerThread
+ public boolean filter(Cursor c) {
+ if (!mLoadDisallowedProgram
+ && mDisallowedProgramIds.contains(c.getLong(PROGRAM_ID_INDEX))) {
+ return false;
+ }
+ Program program = Program.fromCursor(c);
+ for (SeriesRecording seriesRecording : mSeriesRecordings) {
+ boolean programMatches;
+ if (mIgnoreChannelOption) {
+ programMatches = seriesRecording.matchProgram(program,
+ SeriesRecording.OPTION_CHANNEL_ALL);
+ } else {
+ programMatches = seriesRecording.matchProgram(program);
+ }
+ if (programMatches) {
+ return mLoadScheduledEpisode
+ || !mSeasonEpisodeNumbers.contains(new SeasonEpisodeNumber(
+ seriesRecording.getId(), program.getSeasonNumber(),
+ program.getEpisodeNumber()));
+ }
+ }
+ return false;
+ }
+ }
+
+ private class SeriesRecordingCursorFilterForNonSystem extends SeriesRecordingCursorFilter {
+ SeriesRecordingCursorFilterForNonSystem(List<SeriesRecording> seriesRecordings) {
+ super(seriesRecordings);
+ }
+
+ @Override
+ public boolean filter(Cursor c) {
+ return (mLoadCurrentProgram || c.getLong(START_TIME_INDEX) > System.currentTimeMillis())
+ && c.getInt(RECORDING_PROHIBITED_INDEX) != 0 && super.filter(c);
+ }
+ }
+
+ private static class SqlParams {
+ public Uri uri;
+ public String selection;
+ public String[] selectionArgs;
+ public CursorFilter filter;
+ }
+}
diff --git a/src/com/android/tv/dvr/recorder/ConflictChecker.java b/src/com/android/tv/dvr/recorder/ConflictChecker.java
new file mode 100644
index 00000000..8aa90116
--- /dev/null
+++ b/src/com/android/tv/dvr/recorder/ConflictChecker.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.recorder;
+
+import android.annotation.TargetApi;
+import android.content.ContentUris;
+import android.media.tv.TvContract;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Message;
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.ArraySet;
+import android.util.Log;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.InputSessionManager;
+import com.android.tv.InputSessionManager.OnTvViewChannelChangeListener;
+import com.android.tv.MainActivity;
+import com.android.tv.TvApplication;
+import com.android.tv.common.WeakHandler;
+import com.android.tv.data.Channel;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
+import com.android.tv.dvr.DvrScheduleManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ui.DvrUiHelper;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Checking the runtime conflict of DVR recording.
+ * <p>
+ * This class runs only while the {@link MainActivity} is resumed and holds the upcoming conflicts.
+ */
+@TargetApi(Build.VERSION_CODES.N)
+@MainThread
+public class ConflictChecker {
+ private static final String TAG = "ConflictChecker";
+ private static final boolean DEBUG = false;
+
+ private static final int MSG_CHECK_CONFLICT = 1;
+
+ private static final long CHECK_RETRY_PERIOD_MS = TimeUnit.SECONDS.toMillis(30);
+
+ /**
+ * To show watch conflict dialog, the start time of the earliest conflicting schedule should be
+ * less than or equal to this time.
+ */
+ private static final long MAX_WATCH_CONFLICT_CHECK_TIME_MS = TimeUnit.MINUTES.toMillis(5);
+ /**
+ * To show watch conflict dialog, the start time of the earliest conflicting schedule should be
+ * greater than or equal to this time.
+ */
+ private static final long MIN_WATCH_CONFLICT_CHECK_TIME_MS = TimeUnit.SECONDS.toMillis(30);
+
+ private final MainActivity mMainActivity;
+ private final ChannelDataManager mChannelDataManager;
+ private final DvrScheduleManager mScheduleManager;
+ private final InputSessionManager mSessionManager;
+ private final ConflictCheckerHandler mHandler = new ConflictCheckerHandler(this);
+
+ private final List<ScheduledRecording> mUpcomingConflicts = new ArrayList<>();
+ private final Set<OnUpcomingConflictChangeListener> mOnUpcomingConflictChangeListeners =
+ new ArraySet<>();
+ private final Map<Long, List<ScheduledRecording>> mCheckedConflictsMap = new HashMap<>();
+
+ private final ScheduledRecordingListener mScheduledRecordingListener =
+ new ScheduledRecordingListener() {
+ @Override
+ public void onScheduledRecordingAdded(ScheduledRecording... scheduledRecordings) {
+ if (DEBUG) Log.d(TAG, "onScheduledRecordingAdded: " + scheduledRecordings);
+ mHandler.sendEmptyMessage(MSG_CHECK_CONFLICT);
+ }
+
+ @Override
+ public void onScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings) {
+ if (DEBUG) Log.d(TAG, "onScheduledRecordingRemoved: " + scheduledRecordings);
+ mHandler.sendEmptyMessage(MSG_CHECK_CONFLICT);
+ }
+
+ @Override
+ public void onScheduledRecordingStatusChanged(ScheduledRecording... scheduledRecordings) {
+ if (DEBUG) Log.d(TAG, "onScheduledRecordingStatusChanged: " + scheduledRecordings);
+ mHandler.sendEmptyMessage(MSG_CHECK_CONFLICT);
+ }
+ };
+
+ private final OnTvViewChannelChangeListener mOnTvViewChannelChangeListener =
+ new OnTvViewChannelChangeListener() {
+ @Override
+ public void onTvViewChannelChange(@Nullable Uri channelUri) {
+ mHandler.sendEmptyMessage(MSG_CHECK_CONFLICT);
+ }
+ };
+
+ private boolean mStarted;
+
+ public ConflictChecker(MainActivity mainActivity) {
+ mMainActivity = mainActivity;
+ ApplicationSingletons appSingletons = TvApplication.getSingletons(mainActivity);
+ mChannelDataManager = appSingletons.getChannelDataManager();
+ mScheduleManager = appSingletons.getDvrScheduleManager();
+ mSessionManager = appSingletons.getInputSessionManager();
+ }
+
+ /**
+ * Starts checking the conflict.
+ */
+ public void start() {
+ if (mStarted) {
+ return;
+ }
+ mStarted = true;
+ mHandler.sendEmptyMessage(MSG_CHECK_CONFLICT);
+ mScheduleManager.addScheduledRecordingListener(mScheduledRecordingListener);
+ mSessionManager.addOnTvViewChannelChangeListener(mOnTvViewChannelChangeListener);
+ }
+
+ /**
+ * Stops checking the conflict.
+ */
+ public void stop() {
+ if (!mStarted) {
+ return;
+ }
+ mStarted = false;
+ mSessionManager.removeOnTvViewChannelChangeListener(mOnTvViewChannelChangeListener);
+ mScheduleManager.removeScheduledRecordingListener(mScheduledRecordingListener);
+ mHandler.removeCallbacksAndMessages(null);
+ }
+
+ /**
+ * Returns the upcoming conflicts.
+ */
+ public List<ScheduledRecording> getUpcomingConflicts() {
+ return new ArrayList<>(mUpcomingConflicts);
+ }
+
+ /**
+ * Adds a {@link OnUpcomingConflictChangeListener}.
+ */
+ public void addOnUpcomingConflictChangeListener(OnUpcomingConflictChangeListener listener) {
+ mOnUpcomingConflictChangeListeners.add(listener);
+ }
+
+ /**
+ * Removes the {@link OnUpcomingConflictChangeListener}.
+ */
+ public void removeOnUpcomingConflictChangeListener(OnUpcomingConflictChangeListener listener) {
+ mOnUpcomingConflictChangeListeners.remove(listener);
+ }
+
+ private void notifyUpcomingConflictChanged() {
+ for (OnUpcomingConflictChangeListener l : mOnUpcomingConflictChangeListeners) {
+ l.onUpcomingConflictChange();
+ }
+ }
+
+ /**
+ * Remembers the user's decision to record while watching the channel.
+ */
+ public void setCheckedConflictsForChannel(long mChannelId, List<ScheduledRecording> conflicts) {
+ mCheckedConflictsMap.put(mChannelId, new ArrayList<>(conflicts));
+ }
+
+ void onCheckConflict() {
+ // Checks the conflicting schedules and setup the next re-check time.
+ // If there are upcoming conflicts soon, it opens the conflict dialog.
+ if (DEBUG) Log.d(TAG, "Handling MSG_CHECK_CONFLICT");
+ mHandler.removeMessages(MSG_CHECK_CONFLICT);
+ mUpcomingConflicts.clear();
+ if (!mScheduleManager.isInitialized()
+ || !mChannelDataManager.isDbLoadFinished()) {
+ mHandler.sendEmptyMessageDelayed(MSG_CHECK_CONFLICT, CHECK_RETRY_PERIOD_MS);
+ notifyUpcomingConflictChanged();
+ return;
+ }
+ if (mSessionManager.getCurrentTvViewChannelUri() == null) {
+ // As MainActivity is not using a tuner, no need to check the conflict.
+ notifyUpcomingConflictChanged();
+ return;
+ }
+ Uri channelUri = mSessionManager.getCurrentTvViewChannelUri();
+ if (TvContract.isChannelUriForPassthroughInput(channelUri)) {
+ notifyUpcomingConflictChanged();
+ return;
+ }
+ long channelId = ContentUris.parseId(channelUri);
+ Channel channel = mChannelDataManager.getChannel(channelId);
+ // The conflicts caused by watching the channel.
+ List<ScheduledRecording> conflicts = mScheduleManager
+ .getConflictingSchedulesForWatching(channel.getId());
+ long earliestToCheck = Long.MAX_VALUE;
+ long currentTimeMs = System.currentTimeMillis();
+ for (ScheduledRecording schedule : conflicts) {
+ long startTimeMs = schedule.getStartTimeMs();
+ if (startTimeMs < currentTimeMs + MIN_WATCH_CONFLICT_CHECK_TIME_MS) {
+ // The start time of the upcoming conflict remains less than the minimum
+ // check time.
+ continue;
+ }
+ if (startTimeMs > currentTimeMs + MAX_WATCH_CONFLICT_CHECK_TIME_MS) {
+ // The start time of the upcoming conflict remains greater than the
+ // maximum check time. Setup the next re-check time.
+ long nextCheckTimeMs = startTimeMs - MAX_WATCH_CONFLICT_CHECK_TIME_MS;
+ if (earliestToCheck > nextCheckTimeMs) {
+ earliestToCheck = nextCheckTimeMs;
+ }
+ } else {
+ // Found upcoming conflicts which will start soon.
+ mUpcomingConflicts.add(schedule);
+ // The schedule will be removed from the "upcoming conflict" when the
+ // recording is almost started.
+ long nextCheckTimeMs = startTimeMs - MIN_WATCH_CONFLICT_CHECK_TIME_MS;
+ if (earliestToCheck > nextCheckTimeMs) {
+ earliestToCheck = nextCheckTimeMs;
+ }
+ }
+ }
+ if (earliestToCheck != Long.MAX_VALUE) {
+ mHandler.sendEmptyMessageDelayed(MSG_CHECK_CONFLICT,
+ earliestToCheck - currentTimeMs);
+ }
+ if (DEBUG) Log.d(TAG, "upcoming conflicts: " + mUpcomingConflicts);
+ notifyUpcomingConflictChanged();
+ if (!mUpcomingConflicts.isEmpty()
+ && !DvrUiHelper.isChannelWatchConflictDialogShown(mMainActivity)) {
+ // Don't show the conflict dialog if the user already knows.
+ List<ScheduledRecording> checkedConflicts = mCheckedConflictsMap.get(
+ channel.getId());
+ if (checkedConflicts == null
+ || !checkedConflicts.containsAll(mUpcomingConflicts)) {
+ DvrUiHelper.showChannelWatchConflictDialog(mMainActivity, channel);
+ }
+ }
+ }
+
+ private static class ConflictCheckerHandler extends WeakHandler<ConflictChecker> {
+ ConflictCheckerHandler(ConflictChecker conflictChecker) {
+ super(conflictChecker);
+ }
+
+ @Override
+ protected void handleMessage(Message msg, @NonNull ConflictChecker conflictChecker) {
+ switch (msg.what) {
+ case MSG_CHECK_CONFLICT:
+ conflictChecker.onCheckConflict();
+ break;
+ }
+ }
+ }
+
+ /**
+ * A listener for the change of upcoming conflicts.
+ */
+ public interface OnUpcomingConflictChangeListener {
+ void onUpcomingConflictChange();
+ }
+}
diff --git a/src/com/android/tv/dvr/recorder/DvrRecordingService.java b/src/com/android/tv/dvr/recorder/DvrRecordingService.java
new file mode 100644
index 00000000..5d324ca5
--- /dev/null
+++ b/src/com/android/tv/dvr/recorder/DvrRecordingService.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.recorder;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.IBinder;
+import android.support.annotation.MainThread;
+import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.InputSessionManager;
+import com.android.tv.InputSessionManager.OnRecordingSessionChangeListener;
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.dvr.WritableDvrDataManager;
+import com.android.tv.util.Clock;
+import com.android.tv.util.RecurringRunner;
+
+/**
+ * DVR recording service. This service should be a foreground service and send a notification
+ * to users to do long-running recording task.
+ *
+ * <p>This service is waken up when there's a scheduled recording coming soon and at boot completed
+ * since schedules have to be loaded from databases in order to set new recording alarms, which
+ * might take a long time.
+ */
+@RequiresApi(Build.VERSION_CODES.N)
+public class DvrRecordingService extends Service {
+ private static final String TAG = "DvrRecordingService";
+ private static final boolean DEBUG = false;
+
+ private static final String DVR_NOTIFICATION_CHANNEL_ID = "dvr_notification_channel";
+ private static final int ONGOING_NOTIFICATION_ID = 1;
+ @VisibleForTesting static final String EXTRA_START_FOR_RECORDING = "start_for_recording";
+
+ private static DvrRecordingService sInstance;
+ private NotificationChannel mNotificationChannel;
+ private String mContentTitle;
+ private String mContentTextRecording;
+ private String mContentTextLoading;
+
+ /**
+ * Starts the service in foreground.
+ *
+ * @param startForRecording {@code true} if there are upcoming recordings in
+ * {@link RecordingScheduler#SOON_DURATION_IN_MS} and the service is
+ * started in foreground for those recordings.
+ */
+ @MainThread
+ static void startForegroundService(Context context, boolean startForRecording) {
+ if (sInstance == null) {
+ Intent intent = new Intent(context, DvrRecordingService.class);
+ intent.putExtra(EXTRA_START_FOR_RECORDING, startForRecording);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ context.startForegroundService(intent);
+ } else {
+ context.startService(intent);
+ }
+ } else {
+ sInstance.startForeground(startForRecording);
+ }
+ }
+
+ @MainThread
+ static void stopForegroundIfNotRecording() {
+ if (sInstance != null) {
+ sInstance.stopForegroundIfNotRecordingInternal();
+ }
+ }
+
+ private RecurringRunner mReaperRunner;
+ private InputSessionManager mSessionManager;
+
+ @VisibleForTesting boolean mIsRecording;
+ private boolean mForeground;
+
+ @VisibleForTesting final OnRecordingSessionChangeListener mOnRecordingSessionChangeListener =
+ new OnRecordingSessionChangeListener() {
+ @Override
+ public void onRecordingSessionChange(final boolean create, final int count) {
+ mIsRecording = count > 0;
+ if (create) {
+ startForeground(true);
+ } else {
+ stopForegroundIfNotRecordingInternal();
+ }
+ }
+ };
+
+ @Override
+ public void onCreate() {
+ TvApplication.setCurrentRunningProcess(this, true);
+ if (DEBUG) Log.d(TAG, "onCreate");
+ super.onCreate();
+ SoftPreconditions.checkFeatureEnabled(this, CommonFeatures.DVR, TAG);
+ sInstance = this;
+ ApplicationSingletons singletons = TvApplication.getSingletons(this);
+ WritableDvrDataManager dataManager =
+ (WritableDvrDataManager) singletons.getDvrDataManager();
+ mSessionManager = singletons.getInputSessionManager();
+ mSessionManager.addOnRecordingSessionChangeListener(mOnRecordingSessionChangeListener);
+ mReaperRunner = new RecurringRunner(this, java.util.concurrent.TimeUnit.DAYS.toMillis(1),
+ new ScheduledProgramReaper(dataManager, Clock.SYSTEM), null);
+ mReaperRunner.start();
+ mContentTitle = getString(R.string.dvr_notification_content_title);
+ mContentTextRecording = getString(R.string.dvr_notification_content_text_recording);
+ mContentTextLoading = getString(R.string.dvr_notification_content_text_loading);
+ createNotificationChannel();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (DEBUG) Log.d(TAG, "onStartCommand (" + intent + "," + flags + "," + startId + ")");
+ if (intent != null) {
+ startForeground(intent.getBooleanExtra(EXTRA_START_FOR_RECORDING, false));
+ }
+ return START_STICKY;
+ }
+
+ @Override
+ public void onDestroy() {
+ if (DEBUG) Log.d(TAG, "onDestroy");
+ mReaperRunner.stop();
+ mSessionManager.removeRecordingSessionChangeListener(mOnRecordingSessionChangeListener);
+ sInstance = null;
+ super.onDestroy();
+ }
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @VisibleForTesting
+ protected void stopForegroundIfNotRecordingInternal() {
+ if (mForeground && !mIsRecording) {
+ stopForeground();
+ }
+ }
+
+ private void startForeground(boolean hasUpcomingRecording) {
+ if (!mForeground || hasUpcomingRecording) {
+ // We may need to update notification for upcoming recordings.
+ mForeground = true;
+ startForegroundInternal(hasUpcomingRecording);
+ }
+ }
+
+ private void stopForeground() {
+ stopForegroundInternal();
+ mForeground = false;
+ }
+
+ @VisibleForTesting
+ protected void startForegroundInternal(boolean hasUpcomingRecording) {
+ // STOPSHIP: Replace the content title with real UX strings
+ Notification.Builder builder = new Notification.Builder(this)
+ .setContentTitle(mContentTitle)
+ .setContentText(hasUpcomingRecording ? mContentTextRecording : mContentTextLoading)
+ .setSmallIcon(R.drawable.ic_dvr);
+ Notification notification = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
+ builder.setChannelId(DVR_NOTIFICATION_CHANNEL_ID).build() : builder.build();
+ startForeground(ONGOING_NOTIFICATION_ID, notification);
+ }
+
+ @VisibleForTesting
+ protected void stopForegroundInternal() {
+ stopForeground(true);
+ }
+
+ private void createNotificationChannel() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ // STOPSHIP: Replace the channel name with real UX strings
+ mNotificationChannel = new NotificationChannel(DVR_NOTIFICATION_CHANNEL_ID,
+ getString(R.string.dvr_notification_channel_name),
+ NotificationManager.IMPORTANCE_LOW);
+ ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE))
+ .createNotificationChannel(mNotificationChannel);
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/recorder/DvrStartRecordingReceiver.java b/src/com/android/tv/dvr/recorder/DvrStartRecordingReceiver.java
new file mode 100644
index 00000000..f1c0020b
--- /dev/null
+++ b/src/com/android/tv/dvr/recorder/DvrStartRecordingReceiver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.recorder;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+
+import com.android.tv.TvApplication;
+
+/**
+ * Signals the DVR to start recording shows <i>soon</i>.
+ */
+@RequiresApi(Build.VERSION_CODES.N)
+public class DvrStartRecordingReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ TvApplication.setCurrentRunningProcess(context, true);
+ RecordingScheduler scheduler = TvApplication.getSingletons(context).getRecordingScheduler();
+ if (scheduler != null) {
+ scheduler.updateAndStartServiceIfNeeded();
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/recorder/InputTaskScheduler.java b/src/com/android/tv/dvr/recorder/InputTaskScheduler.java
new file mode 100644
index 00000000..fee4568e
--- /dev/null
+++ b/src/com/android/tv/dvr/recorder/InputTaskScheduler.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.recorder;
+
+import android.content.Context;
+import android.media.tv.TvInputInfo;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.support.annotation.VisibleForTesting;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.LongSparseArray;
+
+import com.android.tv.InputSessionManager;
+import com.android.tv.data.Channel;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.WritableDvrDataManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.util.Clock;
+import com.android.tv.util.CompositeComparator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The scheduler for a TV input.
+ */
+public class InputTaskScheduler {
+ private static final String TAG = "InputTaskScheduler";
+ private static final boolean DEBUG = false;
+
+ private static final int MSG_ADD_SCHEDULED_RECORDING = 1;
+ private static final int MSG_REMOVE_SCHEDULED_RECORDING = 2;
+ private static final int MSG_UPDATE_SCHEDULED_RECORDING = 3;
+ private static final int MSG_BUILD_SCHEDULE = 4;
+ private static final int MSG_STOP_SCHEDULE = 5;
+
+ private static final float MIN_REMAIN_DURATION_PERCENT = 0.05f;
+
+ // The candidate comparator should be the consistent with
+ // DvrScheduleManager#CANDIDATE_COMPARATOR.
+ private static final Comparator<RecordingTask> CANDIDATE_COMPARATOR =
+ new CompositeComparator<>(
+ RecordingTask.PRIORITY_COMPARATOR,
+ RecordingTask.END_TIME_COMPARATOR,
+ RecordingTask.ID_COMPARATOR);
+
+ /**
+ * Returns the comparator which the schedules are sorted with when executed.
+ */
+ public static Comparator<ScheduledRecording> getRecordingOrderComparator() {
+ return ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR;
+ }
+
+ /**
+ * Wraps a {@link RecordingTask} removing it from {@link #mPendingRecordings} when it is done.
+ */
+ public final class HandlerWrapper extends Handler {
+ public static final int MESSAGE_REMOVE = 999;
+ private final long mId;
+ private final RecordingTask mTask;
+
+ HandlerWrapper(Looper looper, ScheduledRecording scheduledRecording,
+ RecordingTask recordingTask) {
+ super(looper, recordingTask);
+ mId = scheduledRecording.getId();
+ mTask = recordingTask;
+ mTask.setHandler(this);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ // The RecordingTask gets a chance first.
+ // It must return false to pass this message to here.
+ if (msg.what == MESSAGE_REMOVE) {
+ if (DEBUG) Log.d(TAG, "done " + mId);
+ mPendingRecordings.remove(mId);
+ }
+ removeCallbacksAndMessages(null);
+ mHandler.removeMessages(MSG_BUILD_SCHEDULE);
+ mHandler.sendEmptyMessage(MSG_BUILD_SCHEDULE);
+ super.handleMessage(msg);
+ }
+ }
+
+ private TvInputInfo mInput;
+ private final Looper mLooper;
+ private final ChannelDataManager mChannelDataManager;
+ private final DvrManager mDvrManager;
+ private final WritableDvrDataManager mDataManager;
+ private final InputSessionManager mSessionManager;
+ private final Clock mClock;
+ private final Context mContext;
+
+ private final LongSparseArray<HandlerWrapper> mPendingRecordings = new LongSparseArray<>();
+ private final Map<Long, ScheduledRecording> mWaitingSchedules = new ArrayMap<>();
+ private final Handler mMainThreadHandler;
+ private final Handler mHandler;
+ private final Object mInputLock = new Object();
+ private final RecordingTaskFactory mRecordingTaskFactory;
+
+ public InputTaskScheduler(Context context, TvInputInfo input, Looper looper,
+ ChannelDataManager channelDataManager, DvrManager dvrManager,
+ DvrDataManager dataManager, InputSessionManager sessionManager, Clock clock) {
+ this(context, input, looper, channelDataManager, dvrManager, dataManager, sessionManager,
+ clock, null);
+ }
+
+ @VisibleForTesting
+ InputTaskScheduler(Context context, TvInputInfo input, Looper looper,
+ ChannelDataManager channelDataManager, DvrManager dvrManager,
+ DvrDataManager dataManager, InputSessionManager sessionManager, Clock clock,
+ RecordingTaskFactory recordingTaskFactory) {
+ if (DEBUG) Log.d(TAG, "Creating scheduler for " + input);
+ mContext = context;
+ mInput = input;
+ mLooper = looper;
+ mChannelDataManager = channelDataManager;
+ mDvrManager = dvrManager;
+ mDataManager = (WritableDvrDataManager) dataManager;
+ mSessionManager = sessionManager;
+ mClock = clock;
+ mMainThreadHandler = new Handler(Looper.getMainLooper());
+ mRecordingTaskFactory = recordingTaskFactory != null ? recordingTaskFactory
+ : new RecordingTaskFactory() {
+ @Override
+ public RecordingTask createRecordingTask(ScheduledRecording schedule, Channel channel,
+ DvrManager dvrManager, InputSessionManager sessionManager,
+ WritableDvrDataManager dataManager, Clock clock) {
+ return new RecordingTask(mContext, schedule, channel, mDvrManager, mSessionManager,
+ mDataManager, mClock);
+ }
+ };
+ mHandler = new WorkerThreadHandler(looper);
+ }
+
+ /**
+ * Adds a {@link ScheduledRecording}.
+ */
+ public void addSchedule(ScheduledRecording schedule) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_ADD_SCHEDULED_RECORDING, schedule));
+ }
+
+ @VisibleForTesting
+ void handleAddSchedule(ScheduledRecording schedule) {
+ if (mPendingRecordings.get(schedule.getId()) != null
+ || mWaitingSchedules.containsKey(schedule.getId())) {
+ return;
+ }
+ mWaitingSchedules.put(schedule.getId(), schedule);
+ mHandler.removeMessages(MSG_BUILD_SCHEDULE);
+ mHandler.sendEmptyMessage(MSG_BUILD_SCHEDULE);
+ }
+
+ /**
+ * Removes the {@link ScheduledRecording}.
+ */
+ public void removeSchedule(ScheduledRecording schedule) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_REMOVE_SCHEDULED_RECORDING, schedule));
+ }
+
+ @VisibleForTesting
+ void handleRemoveSchedule(ScheduledRecording schedule) {
+ HandlerWrapper wrapper = mPendingRecordings.get(schedule.getId());
+ if (wrapper != null) {
+ wrapper.mTask.cancel();
+ return;
+ }
+ if (mWaitingSchedules.containsKey(schedule.getId())) {
+ mWaitingSchedules.remove(schedule.getId());
+ mHandler.removeMessages(MSG_BUILD_SCHEDULE);
+ mHandler.sendEmptyMessage(MSG_BUILD_SCHEDULE);
+ }
+ }
+
+ /**
+ * Updates the {@link ScheduledRecording}.
+ */
+ public void updateSchedule(ScheduledRecording schedule) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_SCHEDULED_RECORDING, schedule));
+ }
+
+ @VisibleForTesting
+ void handleUpdateSchedule(ScheduledRecording schedule) {
+ HandlerWrapper wrapper = mPendingRecordings.get(schedule.getId());
+ if (wrapper != null) {
+ if (schedule.getStartTimeMs() > mClock.currentTimeMillis()
+ && schedule.getStartTimeMs() > wrapper.mTask.getStartTimeMs()) {
+ // It shouldn't have started. Cancel and put to the waiting list.
+ // The schedules will be rebuilt when the task is removed.
+ // The reschedule is called in RecordingScheduler.
+ wrapper.mTask.cancel();
+ mWaitingSchedules.put(schedule.getId(), schedule);
+ return;
+ }
+ wrapper.sendMessage(wrapper.obtainMessage(RecordingTask.MSG_UDPATE_SCHEDULE, schedule));
+ return;
+ }
+ if (mWaitingSchedules.containsKey(schedule.getId())) {
+ mWaitingSchedules.put(schedule.getId(), schedule);
+ mHandler.removeMessages(MSG_BUILD_SCHEDULE);
+ mHandler.sendEmptyMessage(MSG_BUILD_SCHEDULE);
+ }
+ }
+
+ /**
+ * Updates the TV input.
+ */
+ public void updateTvInputInfo(TvInputInfo input) {
+ synchronized (mInputLock) {
+ mInput = input;
+ }
+ }
+
+ /**
+ * Stops the input task scheduler.
+ */
+ public void stop() {
+ mHandler.removeCallbacksAndMessages(null);
+ mHandler.sendEmptyMessage(MSG_STOP_SCHEDULE);
+ }
+
+ private void handleStopSchedule() {
+ mWaitingSchedules.clear();
+ int size = mPendingRecordings.size();
+ for (int i = 0; i < size; ++i) {
+ RecordingTask task = mPendingRecordings.get(mPendingRecordings.keyAt(i)).mTask;
+ task.cleanUp();
+ }
+ }
+
+ @VisibleForTesting
+ void handleBuildSchedule() {
+ if (mWaitingSchedules.isEmpty()) {
+ return;
+ }
+ long currentTimeMs = mClock.currentTimeMillis();
+ // Remove past schedules.
+ for (Iterator<ScheduledRecording> iter = mWaitingSchedules.values().iterator();
+ iter.hasNext(); ) {
+ ScheduledRecording schedule = iter.next();
+ if (schedule.getEndTimeMs() - currentTimeMs
+ <= MIN_REMAIN_DURATION_PERCENT * schedule.getDuration()) {
+ fail(schedule);
+ iter.remove();
+ }
+ }
+ if (mWaitingSchedules.isEmpty()) {
+ return;
+ }
+ // Record the schedules which should start now.
+ List<ScheduledRecording> schedulesToStart = new ArrayList<>();
+ for (ScheduledRecording schedule : mWaitingSchedules.values()) {
+ if (schedule.getState() != ScheduledRecording.STATE_RECORDING_CANCELED
+ && schedule.getStartTimeMs() - RecordingTask.RECORDING_EARLY_START_OFFSET_MS
+ <= currentTimeMs && schedule.getEndTimeMs() > currentTimeMs) {
+ schedulesToStart.add(schedule);
+ }
+ }
+ // The schedules will be executed with the following order.
+ // 1. The schedule which starts early. It can be replaced later when the schedule with the
+ // higher priority needs to start.
+ // 2. The schedule with the higher priority. It can be replaced later when the schedule with
+ // the higher priority needs to start.
+ // 3. The schedule which was created recently.
+ Collections.sort(schedulesToStart, getRecordingOrderComparator());
+ int tunerCount;
+ synchronized (mInputLock) {
+ tunerCount = mInput.canRecord() ? mInput.getTunerCount() : 0;
+ }
+ for (ScheduledRecording schedule : schedulesToStart) {
+ if (hasTaskWhichFinishEarlier(schedule)) {
+ // If there is a schedule which finishes earlier than the new schedule, rebuild the
+ // schedules after it finishes.
+ return;
+ }
+ if (mPendingRecordings.size() < tunerCount) {
+ // Tuners available.
+ createRecordingTask(schedule).start();
+ mWaitingSchedules.remove(schedule.getId());
+ } else {
+ // No available tuners.
+ RecordingTask task = getReplacableTask(schedule);
+ if (task != null) {
+ task.stop();
+ // Just return. The schedules will be rebuilt after the task is stopped.
+ return;
+ }
+ }
+ }
+ if (mWaitingSchedules.isEmpty()) {
+ return;
+ }
+ // Set next scheduling.
+ long earliest = Long.MAX_VALUE;
+ for (ScheduledRecording schedule : mWaitingSchedules.values()) {
+ // The conflicting schedules will be removed if they end before conflicting resolved.
+ if (schedulesToStart.contains(schedule)) {
+ if (earliest > schedule.getEndTimeMs()) {
+ earliest = schedule.getEndTimeMs();
+ }
+ } else {
+ if (earliest > schedule.getStartTimeMs()
+ - RecordingTask.RECORDING_EARLY_START_OFFSET_MS) {
+ earliest = schedule.getStartTimeMs()
+ - RecordingTask.RECORDING_EARLY_START_OFFSET_MS;
+ }
+ }
+ }
+ mHandler.sendEmptyMessageDelayed(MSG_BUILD_SCHEDULE, earliest - currentTimeMs);
+ }
+
+ private RecordingTask createRecordingTask(ScheduledRecording schedule) {
+ Channel channel = mChannelDataManager.getChannel(schedule.getChannelId());
+ RecordingTask recordingTask = mRecordingTaskFactory.createRecordingTask(schedule, channel,
+ mDvrManager, mSessionManager, mDataManager, mClock);
+ HandlerWrapper handlerWrapper = new HandlerWrapper(mLooper, schedule, recordingTask);
+ mPendingRecordings.put(schedule.getId(), handlerWrapper);
+ return recordingTask;
+ }
+
+ private boolean hasTaskWhichFinishEarlier(ScheduledRecording schedule) {
+ int size = mPendingRecordings.size();
+ for (int i = 0; i < size; ++i) {
+ RecordingTask task = mPendingRecordings.get(mPendingRecordings.keyAt(i)).mTask;
+ if (task.getEndTimeMs() <= schedule.getStartTimeMs()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private RecordingTask getReplacableTask(ScheduledRecording schedule) {
+ // Returns the recording with the following priority.
+ // 1. The recording with the lowest priority is returned.
+ // 2. If the priorities are the same, the recording which finishes early is returned.
+ // 3. If 1) and 2) are the same, the early created schedule is returned.
+ int size = mPendingRecordings.size();
+ RecordingTask candidate = null;
+ for (int i = 0; i < size; ++i) {
+ RecordingTask task = mPendingRecordings.get(mPendingRecordings.keyAt(i)).mTask;
+ if (schedule.getPriority() > task.getPriority()) {
+ if (candidate == null || CANDIDATE_COMPARATOR.compare(candidate, task) > 0) {
+ candidate = task;
+ }
+ }
+ }
+ return candidate;
+ }
+
+ private void fail(ScheduledRecording schedule) {
+ // It's called when the scheduling has been failed without creating RecordingTask.
+ runOnMainHandler(new Runnable() {
+ @Override
+ public void run() {
+ ScheduledRecording scheduleInManager =
+ mDataManager.getScheduledRecording(schedule.getId());
+ if (scheduleInManager != null) {
+ // The schedule should be updated based on the object from DataManager in case
+ // when it has been updated.
+ mDataManager.changeState(scheduleInManager,
+ ScheduledRecording.STATE_RECORDING_FAILED);
+ }
+ }
+ });
+ }
+
+ private void runOnMainHandler(Runnable runnable) {
+ if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
+ runnable.run();
+ } else {
+ mMainThreadHandler.post(runnable);
+ }
+ }
+
+ @VisibleForTesting
+ interface RecordingTaskFactory {
+ RecordingTask createRecordingTask(ScheduledRecording scheduledRecording, Channel channel,
+ DvrManager dvrManager, InputSessionManager sessionManager,
+ WritableDvrDataManager dataManager, Clock clock);
+ }
+
+ private class WorkerThreadHandler extends Handler {
+ public WorkerThreadHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ADD_SCHEDULED_RECORDING:
+ handleAddSchedule((ScheduledRecording) msg.obj);
+ break;
+ case MSG_REMOVE_SCHEDULED_RECORDING:
+ handleRemoveSchedule((ScheduledRecording) msg.obj);
+ break;
+ case MSG_UPDATE_SCHEDULED_RECORDING:
+ handleUpdateSchedule((ScheduledRecording) msg.obj);
+ case MSG_BUILD_SCHEDULE:
+ handleBuildSchedule();
+ break;
+ case MSG_STOP_SCHEDULE:
+ handleStopSchedule();
+ break;
+ }
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/recorder/RecordingScheduler.java b/src/com/android/tv/dvr/recorder/RecordingScheduler.java
new file mode 100644
index 00000000..cbaf46b5
--- /dev/null
+++ b/src/com/android/tv/dvr/recorder/RecordingScheduler.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.recorder;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.media.tv.TvInputInfo;
+import android.media.tv.TvInputManager.TvInputCallback;
+import android.os.Build;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.support.annotation.MainThread;
+import android.support.annotation.RequiresApi;
+import android.support.annotation.VisibleForTesting;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Range;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.InputSessionManager;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.ChannelDataManager.Listener;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener;
+import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.WritableDvrDataManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.util.Clock;
+import com.android.tv.util.TvInputManagerHelper;
+import com.android.tv.util.Utils;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * The core class to manage DVR schedule and run recording task.
+ **
+ * <p> This class is responsible for:
+ * <ul>
+ * <li>Sending record commands to TV inputs</li>
+ * <li>Resolving conflicting schedules, handling overlapping recording time durations, etc.</li>
+ * </ul>
+ *
+ * <p>This should be a singleton associated with application's main process.
+ */
+@RequiresApi(Build.VERSION_CODES.N)
+@MainThread
+public class RecordingScheduler extends TvInputCallback implements ScheduledRecordingListener {
+ private static final String TAG = "RecordingScheduler";
+ private static final boolean DEBUG = false;
+
+ private static final String HANDLER_THREAD_NAME = "RecordingScheduler";
+ private final static long SOON_DURATION_IN_MS = TimeUnit.MINUTES.toMillis(1);
+ @VisibleForTesting final static long MS_TO_WAKE_BEFORE_START = TimeUnit.SECONDS.toMillis(30);
+
+ private final Looper mLooper;
+ private final InputSessionManager mSessionManager;
+ private final WritableDvrDataManager mDataManager;
+ private final DvrManager mDvrManager;
+ private final ChannelDataManager mChannelDataManager;
+ private final TvInputManagerHelper mInputManager;
+ private final Context mContext;
+ private final Clock mClock;
+ private final AlarmManager mAlarmManager;
+
+ private final Map<String, InputTaskScheduler> mInputSchedulerMap = new ArrayMap<>();
+ private long mLastStartTimePendingMs;
+
+ private OnDvrScheduleLoadFinishedListener mDvrScheduleLoadListener =
+ new OnDvrScheduleLoadFinishedListener() {
+ @Override
+ public void onDvrScheduleLoadFinished() {
+ mDataManager.removeDvrScheduleLoadFinishedListener(this);
+ if (isDbLoaded()) {
+ updateInternal();
+ }
+ }
+ };
+
+ private Listener mChannelDataLoadListener = new Listener() {
+ @Override
+ public void onLoadFinished() {
+ mChannelDataManager.removeListener(this);
+ if (isDbLoaded()) {
+ updateInternal();
+ }
+ }
+
+ @Override
+ public void onChannelListUpdated() { }
+
+ @Override
+ public void onChannelBrowsableChanged() { }
+ };
+
+ /**
+ * Creates a scheduler to schedule alarms for scheduled recordings and create recording tasks.
+ * This method should be only called once in the life-cycle of the application.
+ */
+ public static RecordingScheduler createScheduler(Context context) {
+ SoftPreconditions.checkState(
+ TvApplication.getSingletons(context).getRecordingScheduler() == null);
+ HandlerThread handlerThread = new HandlerThread(HANDLER_THREAD_NAME);
+ handlerThread.start();
+ ApplicationSingletons singletons = TvApplication.getSingletons(context);
+ return new RecordingScheduler(handlerThread.getLooper(),
+ singletons.getDvrManager(), singletons.getInputSessionManager(),
+ (WritableDvrDataManager) singletons.getDvrDataManager(),
+ singletons.getChannelDataManager(), singletons.getTvInputManagerHelper(), context,
+ Clock.SYSTEM, (AlarmManager) context.getSystemService(Context.ALARM_SERVICE));
+ }
+
+ @VisibleForTesting
+ RecordingScheduler(Looper looper, DvrManager dvrManager, InputSessionManager sessionManager,
+ WritableDvrDataManager dataManager, ChannelDataManager channelDataManager,
+ TvInputManagerHelper inputManager, Context context, Clock clock,
+ AlarmManager alarmManager) {
+ mLooper = looper;
+ mDvrManager = dvrManager;
+ mSessionManager = sessionManager;
+ mDataManager = dataManager;
+ mChannelDataManager = channelDataManager;
+ mInputManager = inputManager;
+ mContext = context;
+ mClock = clock;
+ mAlarmManager = alarmManager;
+ mDataManager.addScheduledRecordingListener(this);
+ mInputManager.addCallback(this);
+ if (isDbLoaded()) {
+ updateInternal();
+ } else {
+ if (!mDataManager.isDvrScheduleLoadFinished()) {
+ mDataManager.addDvrScheduleLoadFinishedListener(mDvrScheduleLoadListener);
+ }
+ if (!mChannelDataManager.isDbLoadFinished()) {
+ mChannelDataManager.addListener(mChannelDataLoadListener);
+ }
+ }
+ }
+
+ /**
+ * Start recording that will happen soon, and set the next alarm time.
+ */
+ public void updateAndStartServiceIfNeeded() {
+ if (DEBUG) Log.d(TAG, "update and start service if needed");
+ if (isDbLoaded()) {
+ updateInternal();
+ } else {
+ // updateInternal will be called when DB is loaded. Start DvrRecordingService to
+ // prevent process being killed before that.
+ DvrRecordingService.startForegroundService(mContext, false);
+ }
+ }
+
+ private void updateInternal() {
+ boolean recordingSoon = updatePendingRecordings();
+ updateNextAlarm();
+ if (recordingSoon) {
+ // Start DvrRecordingService to protect upcoming recording task from being killed.
+ DvrRecordingService.startForegroundService(mContext, true);
+ } else {
+ DvrRecordingService.stopForegroundIfNotRecording();
+ }
+ }
+
+ private boolean updatePendingRecordings() {
+ List<ScheduledRecording> scheduledRecordings = mDataManager
+ .getScheduledRecordings(new Range<>(mLastStartTimePendingMs,
+ mClock.currentTimeMillis() + SOON_DURATION_IN_MS),
+ ScheduledRecording.STATE_RECORDING_NOT_STARTED);
+ for (ScheduledRecording r : scheduledRecordings) {
+ scheduleRecordingSoon(r);
+ }
+ // update() may be called multiple times, under this situation, pending recordings may be
+ // already updated thus scheduledRecordings may have a size of 0. Therefore we also have to
+ // check mLastStartTimePendingMs to check if we have upcoming recordings and prevent the
+ // recording service being wrongly pushed back to background in updateInternal().
+ return scheduledRecordings.size() > 0
+ || (mLastStartTimePendingMs > mClock.currentTimeMillis()
+ && mLastStartTimePendingMs < mClock.currentTimeMillis() + SOON_DURATION_IN_MS);
+ }
+
+ private boolean isDbLoaded() {
+ return mDataManager.isDvrScheduleLoadFinished() && mChannelDataManager.isDbLoadFinished();
+ }
+
+ @Override
+ public void onScheduledRecordingAdded(ScheduledRecording... schedules) {
+ if (DEBUG) Log.d(TAG, "added " + Arrays.asList(schedules));
+ if (!isDbLoaded()) {
+ return;
+ }
+ handleScheduleChange(schedules);
+ }
+
+ @Override
+ public void onScheduledRecordingRemoved(ScheduledRecording... schedules) {
+ if (DEBUG) Log.d(TAG, "removed " + Arrays.asList(schedules));
+ if (!isDbLoaded()) {
+ return;
+ }
+ boolean needToUpdateAlarm = false;
+ for (ScheduledRecording schedule : schedules) {
+ InputTaskScheduler inputTaskScheduler = mInputSchedulerMap.get(schedule.getInputId());
+ if (inputTaskScheduler != null) {
+ inputTaskScheduler.removeSchedule(schedule);
+ needToUpdateAlarm = true;
+ }
+ }
+ if (needToUpdateAlarm) {
+ updateNextAlarm();
+ }
+ }
+
+ @Override
+ public void onScheduledRecordingStatusChanged(ScheduledRecording... schedules) {
+ if (DEBUG) Log.d(TAG, "state changed " + Arrays.asList(schedules));
+ if (!isDbLoaded()) {
+ return;
+ }
+ // Update the recordings.
+ for (ScheduledRecording schedule : schedules) {
+ InputTaskScheduler inputTaskScheduler = mInputSchedulerMap.get(schedule.getInputId());
+ if (inputTaskScheduler != null) {
+ inputTaskScheduler.updateSchedule(schedule);
+ }
+ }
+ handleScheduleChange(schedules);
+ }
+
+ private void handleScheduleChange(ScheduledRecording... schedules) {
+ boolean needToUpdateAlarm = false;
+ for (ScheduledRecording schedule : schedules) {
+ if (schedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED) {
+ if (startsWithin(schedule, SOON_DURATION_IN_MS)) {
+ scheduleRecordingSoon(schedule);
+ } else {
+ needToUpdateAlarm = true;
+ }
+ }
+ }
+ if (needToUpdateAlarm) {
+ updateNextAlarm();
+ }
+ }
+
+ private void scheduleRecordingSoon(ScheduledRecording schedule) {
+ TvInputInfo input = Utils.getTvInputInfoForInputId(mContext, schedule.getInputId());
+ if (input == null) {
+ Log.e(TAG, "Can't find input for " + schedule);
+ mDataManager.changeState(schedule, ScheduledRecording.STATE_RECORDING_FAILED);
+ return;
+ }
+ if (!input.canRecord() || input.getTunerCount() <= 0) {
+ Log.e(TAG, "TV input doesn't support recording: " + input);
+ mDataManager.changeState(schedule, ScheduledRecording.STATE_RECORDING_FAILED);
+ return;
+ }
+ InputTaskScheduler inputTaskScheduler = mInputSchedulerMap.get(input.getId());
+ if (inputTaskScheduler == null) {
+ inputTaskScheduler = new InputTaskScheduler(mContext, input, mLooper,
+ mChannelDataManager, mDvrManager, mDataManager, mSessionManager, mClock);
+ mInputSchedulerMap.put(input.getId(), inputTaskScheduler);
+ }
+ inputTaskScheduler.addSchedule(schedule);
+ if (mLastStartTimePendingMs < schedule.getStartTimeMs()) {
+ mLastStartTimePendingMs = schedule.getStartTimeMs();
+ }
+ }
+
+ private void updateNextAlarm() {
+ long nextStartTime = mDataManager.getNextScheduledStartTimeAfter(
+ Math.max(mLastStartTimePendingMs, mClock.currentTimeMillis()));
+ if (nextStartTime != DvrDataManager.NEXT_START_TIME_NOT_FOUND) {
+ long wakeAt = nextStartTime - MS_TO_WAKE_BEFORE_START;
+ if (DEBUG) Log.d(TAG, "Set alarm to record at " + wakeAt);
+ Intent intent = new Intent(mContext, DvrStartRecordingReceiver.class);
+ PendingIntent alarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+ // This will cancel the previous alarm.
+ mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, wakeAt, alarmIntent);
+ } else {
+ if (DEBUG) Log.d(TAG, "No future recording, alarm not set");
+ }
+ }
+
+ @VisibleForTesting
+ boolean startsWithin(ScheduledRecording scheduledRecording, long durationInMs) {
+ return mClock.currentTimeMillis() >= scheduledRecording.getStartTimeMs() - durationInMs;
+ }
+
+ // No need to remove input task schedule worker when the input is removed. If the input is
+ // removed temporarily, the scheduler should keep the non-started schedules.
+ @Override
+ public void onInputUpdated(String inputId) {
+ InputTaskScheduler inputTaskScheduler = mInputSchedulerMap.get(inputId);
+ if (inputTaskScheduler != null) {
+ inputTaskScheduler.updateTvInputInfo(Utils.getTvInputInfoForInputId(mContext, inputId));
+ }
+ }
+
+ @Override
+ public void onTvInputInfoUpdated(TvInputInfo input) {
+ InputTaskScheduler inputTaskScheduler = mInputSchedulerMap.get(input.getId());
+ if (inputTaskScheduler != null) {
+ inputTaskScheduler.updateTvInputInfo(input);
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/recorder/RecordingTask.java b/src/com/android/tv/dvr/recorder/RecordingTask.java
new file mode 100644
index 00000000..14888056
--- /dev/null
+++ b/src/com/android/tv/dvr/recorder/RecordingTask.java
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.recorder;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.media.tv.TvContract;
+import android.media.tv.TvInputManager;
+import android.media.tv.TvRecordingClient.RecordingCallback;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.support.annotation.VisibleForTesting;
+import android.support.annotation.WorkerThread;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.android.tv.InputSessionManager;
+import com.android.tv.InputSessionManager.RecordingSession;
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.data.Channel;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.WritableDvrDataManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.recorder.InputTaskScheduler.HandlerWrapper;
+import com.android.tv.util.Clock;
+import com.android.tv.util.Utils;
+
+import java.util.Comparator;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A Handler that actually starts and stop a recording at the right time.
+ *
+ * <p>This is run on the looper of thread named {@value DvrRecordingService#HANDLER_THREAD_NAME}.
+ * There is only one looper so messages must be handled quickly or start a separate thread.
+ */
+@WorkerThread
+@TargetApi(Build.VERSION_CODES.N)
+public class RecordingTask extends RecordingCallback implements Handler.Callback,
+ DvrManager.Listener {
+ private static final String TAG = "RecordingTask";
+ private static final boolean DEBUG = false;
+
+ /**
+ * Compares the end time in ascending order.
+ */
+ public static final Comparator<RecordingTask> END_TIME_COMPARATOR
+ = new Comparator<RecordingTask>() {
+ @Override
+ public int compare(RecordingTask lhs, RecordingTask rhs) {
+ return Long.compare(lhs.getEndTimeMs(), rhs.getEndTimeMs());
+ }
+ };
+
+ /**
+ * Compares ID in ascending order.
+ */
+ public static final Comparator<RecordingTask> ID_COMPARATOR
+ = new Comparator<RecordingTask>() {
+ @Override
+ public int compare(RecordingTask lhs, RecordingTask rhs) {
+ return Long.compare(lhs.getScheduleId(), rhs.getScheduleId());
+ }
+ };
+
+ /**
+ * Compares the priority in ascending order.
+ */
+ public static final Comparator<RecordingTask> PRIORITY_COMPARATOR
+ = new Comparator<RecordingTask>() {
+ @Override
+ public int compare(RecordingTask lhs, RecordingTask rhs) {
+ return Long.compare(lhs.getPriority(), rhs.getPriority());
+ }
+ };
+
+ @VisibleForTesting
+ static final int MSG_INITIALIZE = 1;
+ @VisibleForTesting
+ static final int MSG_START_RECORDING = 2;
+ @VisibleForTesting
+ static final int MSG_STOP_RECORDING = 3;
+ /**
+ * Message to update schedule.
+ */
+ public static final int MSG_UDPATE_SCHEDULE = 4;
+
+ /**
+ * The time when the start command will be sent before the recording starts.
+ */
+ public static final long RECORDING_EARLY_START_OFFSET_MS = TimeUnit.SECONDS.toMillis(3);
+ /**
+ * If the recording starts later than the scheduled start time or ends before the scheduled end
+ * time, it's considered as clipped.
+ */
+ private static final long CLIPPED_THRESHOLD_MS = TimeUnit.MINUTES.toMillis(5);
+
+ @VisibleForTesting
+ enum State {
+ NOT_STARTED,
+ SESSION_ACQUIRED,
+ CONNECTION_PENDING,
+ CONNECTED,
+ RECORDING_STARTED,
+ RECORDING_STOP_REQUESTED,
+ FINISHED,
+ ERROR,
+ RELEASED,
+ }
+ private final InputSessionManager mSessionManager;
+ private final DvrManager mDvrManager;
+ private final Context mContext;
+
+ private final WritableDvrDataManager mDataManager;
+ private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
+ private RecordingSession mRecordingSession;
+ private Handler mHandler;
+ private ScheduledRecording mScheduledRecording;
+ private final Channel mChannel;
+ private State mState = State.NOT_STARTED;
+ private final Clock mClock;
+ private boolean mStartedWithClipping;
+ private Uri mRecordedProgramUri;
+ private boolean mCanceled;
+
+ RecordingTask(Context context, ScheduledRecording scheduledRecording, Channel channel,
+ DvrManager dvrManager, InputSessionManager sessionManager,
+ WritableDvrDataManager dataManager, Clock clock) {
+ mContext = context;
+ mScheduledRecording = scheduledRecording;
+ mChannel = channel;
+ mSessionManager = sessionManager;
+ mDataManager = dataManager;
+ mClock = clock;
+ mDvrManager = dvrManager;
+
+ if (DEBUG) Log.d(TAG, "created recording task " + mScheduledRecording);
+ }
+
+ public void setHandler(Handler handler) {
+ mHandler = handler;
+ }
+
+ @Override
+ public boolean handleMessage(Message msg) {
+ if (DEBUG) Log.d(TAG, "handleMessage " + msg);
+ SoftPreconditions.checkState(msg.what == HandlerWrapper.MESSAGE_REMOVE || mHandler != null,
+ TAG, "Null handler trying to handle " + msg);
+ try {
+ switch (msg.what) {
+ case MSG_INITIALIZE:
+ handleInit();
+ break;
+ case MSG_START_RECORDING:
+ handleStartRecording();
+ break;
+ case MSG_STOP_RECORDING:
+ handleStopRecording();
+ break;
+ case MSG_UDPATE_SCHEDULE:
+ handleUpdateSchedule((ScheduledRecording) msg.obj);
+ break;
+ case HandlerWrapper.MESSAGE_REMOVE:
+ mHandler.removeCallbacksAndMessages(null);
+ mHandler = null;
+ release();
+ return false;
+ default:
+ SoftPreconditions.checkArgument(false, TAG, "unexpected message type " + msg);
+ break;
+ }
+ return true;
+ } catch (Exception e) {
+ Log.w(TAG, "Error processing message " + msg + " for " + mScheduledRecording, e);
+ failAndQuit();
+ }
+ return false;
+ }
+
+ @Override
+ public void onDisconnected(String inputId) {
+ if (DEBUG) Log.d(TAG, "onDisconnected(" + inputId + ")");
+ if (mRecordingSession != null && mState != State.FINISHED) {
+ failAndQuit();
+ }
+ }
+
+ @Override
+ public void onConnectionFailed(String inputId) {
+ if (DEBUG) Log.d(TAG, "onConnectionFailed(" + inputId + ")");
+ if (mRecordingSession != null) {
+ failAndQuit();
+ }
+ }
+
+ @Override
+ public void onTuned(Uri channelUri) {
+ if (DEBUG) Log.d(TAG, "onTuned");
+ if (mRecordingSession == null) {
+ return;
+ }
+ mState = State.CONNECTED;
+ if (mHandler == null || !sendEmptyMessageAtAbsoluteTime(MSG_START_RECORDING,
+ mScheduledRecording.getStartTimeMs() - RECORDING_EARLY_START_OFFSET_MS)) {
+ failAndQuit();
+ }
+ }
+
+ @Override
+ public void onRecordingStopped(Uri recordedProgramUri) {
+ if (DEBUG) Log.d(TAG, "onRecordingStopped");
+ if (mRecordingSession == null) {
+ return;
+ }
+ mRecordedProgramUri = recordedProgramUri;
+ mState = State.FINISHED;
+ int state = ScheduledRecording.STATE_RECORDING_FINISHED;
+ if (mStartedWithClipping || mScheduledRecording.getEndTimeMs() - CLIPPED_THRESHOLD_MS
+ > mClock.currentTimeMillis()) {
+ state = ScheduledRecording.STATE_RECORDING_CLIPPED;
+ }
+ updateRecordingState(state);
+ sendRemove();
+ if (mCanceled) {
+ removeRecordedProgram();
+ }
+ }
+
+ @Override
+ public void onError(int reason) {
+ if (DEBUG) Log.d(TAG, "onError reason " + reason);
+ if (mRecordingSession == null) {
+ return;
+ }
+ switch (reason) {
+ case TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE:
+ mMainThreadHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (TvApplication.getSingletons(mContext).getMainActivityWrapper()
+ .isResumed()) {
+ ScheduledRecording scheduledRecording = mDataManager
+ .getScheduledRecording(mScheduledRecording.getId());
+ if (scheduledRecording != null) {
+ Toast.makeText(mContext.getApplicationContext(),
+ mContext.getString(R.string
+ .dvr_error_insufficient_space_description_one_recording,
+ scheduledRecording.getProgramDisplayTitle(mContext)),
+ Toast.LENGTH_LONG)
+ .show();
+ }
+ } else {
+ Utils.setRecordingFailedReason(mContext.getApplicationContext(),
+ TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE);
+ Utils.addFailedScheduledRecordingInfo(mContext.getApplicationContext(),
+ mScheduledRecording.getProgramDisplayTitle(mContext));
+ }
+ }
+ });
+ // Pass through
+ default:
+ failAndQuit();
+ break;
+ }
+ }
+
+ private void handleInit() {
+ if (DEBUG) Log.d(TAG, "handleInit " + mScheduledRecording);
+ if (mScheduledRecording.getEndTimeMs() < mClock.currentTimeMillis()) {
+ Log.w(TAG, "End time already past, not recording " + mScheduledRecording);
+ failAndQuit();
+ return;
+ }
+ if (mChannel == null) {
+ Log.w(TAG, "Null channel for " + mScheduledRecording);
+ failAndQuit();
+ return;
+ }
+ if (mChannel.getId() != mScheduledRecording.getChannelId()) {
+ Log.w(TAG, "Channel" + mChannel + " does not match scheduled recording "
+ + mScheduledRecording);
+ failAndQuit();
+ return;
+ }
+
+ String inputId = mChannel.getInputId();
+ mRecordingSession = mSessionManager.createRecordingSession(inputId,
+ "recordingTask-" + mScheduledRecording.getId(), this,
+ mHandler, mScheduledRecording.getEndTimeMs());
+ mState = State.SESSION_ACQUIRED;
+ mDvrManager.addListener(this, mHandler);
+ mRecordingSession.tune(inputId, mChannel.getUri());
+ mState = State.CONNECTION_PENDING;
+ }
+
+ private void failAndQuit() {
+ if (DEBUG) Log.d(TAG, "failAndQuit");
+ updateRecordingState(ScheduledRecording.STATE_RECORDING_FAILED);
+ mState = State.ERROR;
+ sendRemove();
+ }
+
+ private void sendRemove() {
+ if (DEBUG) Log.d(TAG, "sendRemove");
+ if (mHandler != null) {
+ mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(
+ HandlerWrapper.MESSAGE_REMOVE));
+ }
+ }
+
+ private void handleStartRecording() {
+ if (DEBUG) Log.d(TAG, "handleStartRecording " + mScheduledRecording);
+ long programId = mScheduledRecording.getProgramId();
+ mRecordingSession.startRecording(programId == ScheduledRecording.ID_NOT_SET ? null
+ : TvContract.buildProgramUri(programId));
+ updateRecordingState(ScheduledRecording.STATE_RECORDING_IN_PROGRESS);
+ // If it starts late, it's clipped.
+ if (mScheduledRecording.getStartTimeMs() + CLIPPED_THRESHOLD_MS
+ < mClock.currentTimeMillis()) {
+ mStartedWithClipping = true;
+ }
+ mState = State.RECORDING_STARTED;
+
+ if (!sendEmptyMessageAtAbsoluteTime(MSG_STOP_RECORDING,
+ mScheduledRecording.getEndTimeMs())) {
+ failAndQuit();
+ }
+ }
+
+ private void handleStopRecording() {
+ if (DEBUG) Log.d(TAG, "handleStopRecording " + mScheduledRecording);
+ mRecordingSession.stopRecording();
+ mState = State.RECORDING_STOP_REQUESTED;
+ }
+
+ private void handleUpdateSchedule(ScheduledRecording schedule) {
+ mScheduledRecording = schedule;
+ // Check end time only. The start time is checked in InputTaskScheduler.
+ if (schedule.getEndTimeMs() != mScheduledRecording.getEndTimeMs()) {
+ if (mRecordingSession != null) {
+ mRecordingSession.setEndTimeMs(schedule.getEndTimeMs());
+ }
+ if (mState == State.RECORDING_STARTED) {
+ mHandler.removeMessages(MSG_STOP_RECORDING);
+ if (!sendEmptyMessageAtAbsoluteTime(MSG_STOP_RECORDING, schedule.getEndTimeMs())) {
+ failAndQuit();
+ }
+ }
+ }
+ }
+
+ @VisibleForTesting
+ State getState() {
+ return mState;
+ }
+
+ private long getScheduleId() {
+ return mScheduledRecording.getId();
+ }
+
+ /**
+ * Returns the priority.
+ */
+ public long getPriority() {
+ return mScheduledRecording.getPriority();
+ }
+
+ /**
+ * Returns the start time of the recording.
+ */
+ public long getStartTimeMs() {
+ return mScheduledRecording.getStartTimeMs();
+ }
+
+ /**
+ * Returns the end time of the recording.
+ */
+ public long getEndTimeMs() {
+ return mScheduledRecording.getEndTimeMs();
+ }
+
+ private void release() {
+ if (mRecordingSession != null) {
+ mSessionManager.releaseRecordingSession(mRecordingSession);
+ mRecordingSession = null;
+ }
+ mDvrManager.removeListener(this);
+ }
+
+ private boolean sendEmptyMessageAtAbsoluteTime(int what, long when) {
+ long now = mClock.currentTimeMillis();
+ long delay = Math.max(0L, when - now);
+ if (DEBUG) {
+ Log.d(TAG, "Sending message " + what + " with a delay of " + delay / 1000
+ + " seconds to arrive at " + Utils.toIsoDateTimeString(when));
+ }
+ return mHandler.sendEmptyMessageDelayed(what, delay);
+ }
+
+ private void updateRecordingState(@ScheduledRecording.RecordingState int state) {
+ if (DEBUG) Log.d(TAG, "Updating the state of " + mScheduledRecording + " to " + state);
+ mScheduledRecording = ScheduledRecording.buildFrom(mScheduledRecording).setState(state)
+ .build();
+ runOnMainThread(new Runnable() {
+ @Override
+ public void run() {
+ ScheduledRecording schedule = mDataManager.getScheduledRecording(
+ mScheduledRecording.getId());
+ if (schedule == null) {
+ // Schedule has been deleted. Delete the recorded program.
+ removeRecordedProgram();
+ } else {
+ // Update the state based on the object in DataManager in case when it has been
+ // updated. mScheduledRecording will be updated from
+ // onScheduledRecordingStateChanged.
+ mDataManager.updateScheduledRecording(ScheduledRecording.buildFrom(schedule)
+ .setState(state).build());
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onStopRecordingRequested(ScheduledRecording recording) {
+ if (recording.getId() != mScheduledRecording.getId()) {
+ return;
+ }
+ stop();
+ }
+
+ /**
+ * Starts the task.
+ */
+ public void start() {
+ mHandler.sendEmptyMessage(MSG_INITIALIZE);
+ }
+
+ /**
+ * Stops the task.
+ */
+ public void stop() {
+ if (DEBUG) Log.d(TAG, "stop");
+ switch (mState) {
+ case RECORDING_STARTED:
+ mHandler.removeMessages(MSG_STOP_RECORDING);
+ handleStopRecording();
+ break;
+ case RECORDING_STOP_REQUESTED:
+ // Do nothing
+ break;
+ case NOT_STARTED:
+ case SESSION_ACQUIRED:
+ case CONNECTION_PENDING:
+ case CONNECTED:
+ case FINISHED:
+ case ERROR:
+ case RELEASED:
+ default:
+ sendRemove();
+ break;
+ }
+ }
+
+ /**
+ * Cancels the task
+ */
+ public void cancel() {
+ if (DEBUG) Log.d(TAG, "cancel");
+ mCanceled = true;
+ stop();
+ removeRecordedProgram();
+ }
+
+ /**
+ * Clean up the task.
+ */
+ public void cleanUp() {
+ if (mState == State.RECORDING_STARTED || mState == State.RECORDING_STOP_REQUESTED) {
+ updateRecordingState(ScheduledRecording.STATE_RECORDING_FAILED);
+ }
+ release();
+ if (mHandler != null) {
+ mHandler.removeCallbacksAndMessages(null);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getName() + "(" + mScheduledRecording + ")";
+ }
+
+ private void removeRecordedProgram() {
+ runOnMainThread(new Runnable() {
+ @Override
+ public void run() {
+ if (mRecordedProgramUri != null) {
+ mDvrManager.removeRecordedProgram(mRecordedProgramUri);
+ }
+ }
+ });
+ }
+
+ private void runOnMainThread(Runnable runnable) {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ runnable.run();
+ } else {
+ mMainThreadHandler.post(runnable);
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/recorder/ScheduledProgramReaper.java b/src/com/android/tv/dvr/recorder/ScheduledProgramReaper.java
new file mode 100644
index 00000000..d958c4a1
--- /dev/null
+++ b/src/com/android/tv/dvr/recorder/ScheduledProgramReaper.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.recorder;
+
+import android.support.annotation.MainThread;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.tv.dvr.WritableDvrDataManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.util.Clock;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Deletes {@link ScheduledRecording} older than {@value @DAYS} days.
+ */
+class ScheduledProgramReaper implements Runnable {
+
+ @VisibleForTesting
+ static final int DAYS = 2;
+ private final WritableDvrDataManager mDvrDataManager;
+ private final Clock mClock;
+
+ ScheduledProgramReaper(WritableDvrDataManager dvrDataManager, Clock clock) {
+ mDvrDataManager = dvrDataManager;
+ mClock = clock;
+ }
+
+ @Override
+ @MainThread
+ public void run() {
+ long cutoff = mClock.currentTimeMillis() - TimeUnit.DAYS.toMillis(DAYS);
+ List<ScheduledRecording> toRemove = new ArrayList<>();
+ for (ScheduledRecording r : mDvrDataManager.getAllScheduledRecordings()) {
+ // Do not remove the schedules if it belongs to the series recording and was finished
+ // successfully. The schedule is necessary for checking the scheduled episode of the
+ // series recording.
+ if (r.getEndTimeMs() < cutoff
+ && (r.getSeriesRecordingId() == SeriesRecording.ID_NOT_SET
+ || r.getState() != ScheduledRecording.STATE_RECORDING_FINISHED)) {
+ toRemove.add(r);
+ }
+ }
+ for (ScheduledRecording r : mDvrDataManager.getDeletedSchedules()) {
+ if (r.getEndTimeMs() < cutoff) {
+ toRemove.add(r);
+ }
+ }
+ if (!toRemove.isEmpty()) {
+ mDvrDataManager.removeScheduledRecording(ScheduledRecording.toArray(toRemove));
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java b/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
new file mode 100644
index 00000000..15508c24
--- /dev/null
+++ b/src/com/android/tv/dvr/recorder/SeriesRecordingScheduler.java
@@ -0,0 +1,563 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.recorder;
+
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.support.annotation.MainThread;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.LongSparseArray;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.TvApplication;
+import com.android.tv.common.CollectionUtils;
+import com.android.tv.common.SharedPreferencesUtils;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.data.Program;
+import com.android.tv.data.epg.EpgFetcher;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
+import com.android.tv.dvr.DvrDataManager.SeriesRecordingListener;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.WritableDvrDataManager;
+import com.android.tv.dvr.data.SeasonEpisodeNumber;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesInfo;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
+import com.android.tv.experiments.Experiments;
+
+import com.android.tv.util.LocationUtils;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Creates the {@link com.android.tv.dvr.data.ScheduledRecording}s for
+ * the {@link com.android.tv.dvr.data.SeriesRecording}.
+ * <p>
+ * The current implementation assumes that the series recordings are scheduled only for one channel.
+ */
+@TargetApi(Build.VERSION_CODES.N)
+public class SeriesRecordingScheduler {
+ private static final String TAG = "SeriesRecordingSchd";
+ private static final boolean DEBUG = false;
+
+ private static final String KEY_FETCHED_SERIES_IDS =
+ "SeriesRecordingScheduler.fetched_series_ids";
+
+ @SuppressLint("StaticFieldLeak")
+ private static SeriesRecordingScheduler sInstance;
+
+ /**
+ * Creates and returns the {@link SeriesRecordingScheduler}.
+ */
+ public static synchronized SeriesRecordingScheduler getInstance(Context context) {
+ if (sInstance == null) {
+ sInstance = new SeriesRecordingScheduler(context);
+ }
+ return sInstance;
+ }
+
+ private final Context mContext;
+ private final DvrManager mDvrManager;
+ private final WritableDvrDataManager mDataManager;
+ private final List<SeriesRecordingUpdateTask> mScheduleTasks = new ArrayList<>();
+ private final LongSparseArray<FetchSeriesInfoTask> mFetchSeriesInfoTasks =
+ new LongSparseArray<>();
+ private final Set<String> mFetchedSeriesIds = new ArraySet<>();
+ private final SharedPreferences mSharedPreferences;
+ private boolean mStarted;
+ private boolean mPaused;
+ private final Set<Long> mPendingSeriesRecordings = new ArraySet<>();
+
+ private final SeriesRecordingListener mSeriesRecordingListener = new SeriesRecordingListener() {
+ @Override
+ public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) {
+ for (SeriesRecording seriesRecording : seriesRecordings) {
+ executeFetchSeriesInfoTask(seriesRecording);
+ }
+ }
+
+ @Override
+ public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) {
+ // Cancel the update.
+ for (Iterator<SeriesRecordingUpdateTask> iter = mScheduleTasks.iterator();
+ iter.hasNext(); ) {
+ SeriesRecordingUpdateTask task = iter.next();
+ if (CollectionUtils.subtract(task.getSeriesRecordings(), seriesRecordings,
+ SeriesRecording.ID_COMPARATOR).isEmpty()) {
+ task.cancel(true);
+ iter.remove();
+ }
+ }
+ for (SeriesRecording seriesRecording : seriesRecordings) {
+ FetchSeriesInfoTask task = mFetchSeriesInfoTasks.get(seriesRecording.getId());
+ if (task != null) {
+ task.cancel(true);
+ mFetchSeriesInfoTasks.remove(seriesRecording.getId());
+ }
+ }
+ }
+
+ @Override
+ public void onSeriesRecordingChanged(SeriesRecording... seriesRecordings) {
+ List<SeriesRecording> stopped = new ArrayList<>();
+ List<SeriesRecording> normal = new ArrayList<>();
+ for (SeriesRecording r : seriesRecordings) {
+ if (r.isStopped()) {
+ stopped.add(r);
+ } else {
+ normal.add(r);
+ }
+ }
+ if (!stopped.isEmpty()) {
+ onSeriesRecordingRemoved(SeriesRecording.toArray(stopped));
+ }
+ if (!normal.isEmpty()) {
+ updateSchedules(normal);
+ }
+ }
+ };
+
+ private final ScheduledRecordingListener mScheduledRecordingListener =
+ new ScheduledRecordingListener() {
+ @Override
+ public void onScheduledRecordingAdded(ScheduledRecording... schedules) {
+ // No need to update series recordings when the new schedule is added.
+ }
+
+ @Override
+ public void onScheduledRecordingRemoved(ScheduledRecording... schedules) {
+ handleScheduledRecordingChange(Arrays.asList(schedules));
+ }
+
+ @Override
+ public void onScheduledRecordingStatusChanged(ScheduledRecording... schedules) {
+ List<ScheduledRecording> schedulesForUpdate = new ArrayList<>();
+ for (ScheduledRecording r : schedules) {
+ if ((r.getState() == ScheduledRecording.STATE_RECORDING_FAILED
+ || r.getState() == ScheduledRecording.STATE_RECORDING_CLIPPED)
+ && r.getSeriesRecordingId() != SeriesRecording.ID_NOT_SET
+ && !TextUtils.isEmpty(r.getSeasonNumber())
+ && !TextUtils.isEmpty(r.getEpisodeNumber())) {
+ schedulesForUpdate.add(r);
+ }
+ }
+ if (!schedulesForUpdate.isEmpty()) {
+ handleScheduledRecordingChange(schedulesForUpdate);
+ }
+ }
+
+ private void handleScheduledRecordingChange(List<ScheduledRecording> schedules) {
+ if (schedules.isEmpty()) {
+ return;
+ }
+ Set<Long> seriesRecordingIds = new HashSet<>();
+ for (ScheduledRecording r : schedules) {
+ if (r.getSeriesRecordingId() != SeriesRecording.ID_NOT_SET) {
+ seriesRecordingIds.add(r.getSeriesRecordingId());
+ }
+ }
+ if (!seriesRecordingIds.isEmpty()) {
+ List<SeriesRecording> seriesRecordings = new ArrayList<>();
+ for (Long id : seriesRecordingIds) {
+ SeriesRecording seriesRecording = mDataManager.getSeriesRecording(id);
+ if (seriesRecording != null) {
+ seriesRecordings.add(seriesRecording);
+ }
+ }
+ if (!seriesRecordings.isEmpty()) {
+ updateSchedules(seriesRecordings);
+ }
+ }
+ }
+ };
+
+ private SeriesRecordingScheduler(Context context) {
+ mContext = context.getApplicationContext();
+ ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
+ mDvrManager = appSingletons.getDvrManager();
+ mDataManager = (WritableDvrDataManager) appSingletons.getDvrDataManager();
+ mSharedPreferences = context.getSharedPreferences(
+ SharedPreferencesUtils.SHARED_PREF_SERIES_RECORDINGS, Context.MODE_PRIVATE);
+ mFetchedSeriesIds.addAll(mSharedPreferences.getStringSet(KEY_FETCHED_SERIES_IDS,
+ Collections.emptySet()));
+ }
+
+ /**
+ * Starts the scheduler.
+ */
+ @MainThread
+ public void start() {
+ SoftPreconditions.checkState(mDataManager.isInitialized());
+ if (mStarted) {
+ return;
+ }
+ if (DEBUG) Log.d(TAG, "start");
+ mStarted = true;
+ mDataManager.addSeriesRecordingListener(mSeriesRecordingListener);
+ mDataManager.addScheduledRecordingListener(mScheduledRecordingListener);
+ startFetchingSeriesInfo();
+ updateSchedules(mDataManager.getSeriesRecordings());
+ }
+
+ @MainThread
+ public void stop() {
+ if (!mStarted) {
+ return;
+ }
+ if (DEBUG) Log.d(TAG, "stop");
+ mStarted = false;
+ for (int i = 0; i < mFetchSeriesInfoTasks.size(); i++) {
+ FetchSeriesInfoTask task = mFetchSeriesInfoTasks.get(mFetchSeriesInfoTasks.keyAt(i));
+ task.cancel(true);
+ }
+ mFetchSeriesInfoTasks.clear();
+ for (SeriesRecordingUpdateTask task : mScheduleTasks) {
+ task.cancel(true);
+ }
+ mScheduleTasks.clear();
+ mDataManager.removeScheduledRecordingListener(mScheduledRecordingListener);
+ mDataManager.removeSeriesRecordingListener(mSeriesRecordingListener);
+ }
+
+ private void startFetchingSeriesInfo() {
+ for (SeriesRecording seriesRecording : mDataManager.getSeriesRecordings()) {
+ if (!mFetchedSeriesIds.contains(seriesRecording.getSeriesId())) {
+ executeFetchSeriesInfoTask(seriesRecording);
+ }
+ }
+ }
+
+ private void executeFetchSeriesInfoTask(SeriesRecording seriesRecording) {
+ if (Experiments.CLOUD_EPG.get()) {
+ FetchSeriesInfoTask task = new FetchSeriesInfoTask(seriesRecording);
+ task.execute();
+ mFetchSeriesInfoTasks.put(seriesRecording.getId(), task);
+ }
+ }
+
+ /**
+ * Pauses the updates of the series recordings.
+ */
+ public void pauseUpdate() {
+ if (DEBUG) Log.d(TAG, "Schedule paused");
+ if (mPaused) {
+ return;
+ }
+ mPaused = true;
+ if (!mStarted) {
+ return;
+ }
+ for (SeriesRecordingUpdateTask task : mScheduleTasks) {
+ for (SeriesRecording r : task.getSeriesRecordings()) {
+ mPendingSeriesRecordings.add(r.getId());
+ }
+ task.cancel(true);
+ }
+ }
+
+ /**
+ * Resumes the updates of the series recordings.
+ */
+ public void resumeUpdate() {
+ if (DEBUG) Log.d(TAG, "Schedule resumed");
+ if (!mPaused) {
+ return;
+ }
+ mPaused = false;
+ if (!mStarted) {
+ return;
+ }
+ if (!mPendingSeriesRecordings.isEmpty()) {
+ List<SeriesRecording> seriesRecordings = new ArrayList<>();
+ for (long seriesRecordingId : mPendingSeriesRecordings) {
+ SeriesRecording seriesRecording =
+ mDataManager.getSeriesRecording(seriesRecordingId);
+ if (seriesRecording != null) {
+ seriesRecordings.add(seriesRecording);
+ }
+ }
+ if (!seriesRecordings.isEmpty()) {
+ updateSchedules(seriesRecordings);
+ }
+ }
+ }
+
+ /**
+ * Update schedules for the given series recordings. If it's paused, the update will be done
+ * after it's resumed.
+ */
+ public void updateSchedules(Collection<SeriesRecording> seriesRecordings) {
+ if (DEBUG) Log.d(TAG, "updateSchedules:" + seriesRecordings);
+ if (!mStarted) {
+ if (DEBUG) Log.d(TAG, "Not started yet.");
+ return;
+ }
+ if (mPaused) {
+ for (SeriesRecording r : seriesRecordings) {
+ mPendingSeriesRecordings.add(r.getId());
+ }
+ if (DEBUG) {
+ Log.d(TAG, "The scheduler has been paused. Adding to the pending list. size="
+ + mPendingSeriesRecordings.size());
+ }
+ return;
+ }
+ Set<SeriesRecording> previousSeriesRecordings = new HashSet<>();
+ for (Iterator<SeriesRecordingUpdateTask> iter = mScheduleTasks.iterator();
+ iter.hasNext(); ) {
+ SeriesRecordingUpdateTask task = iter.next();
+ if (CollectionUtils.containsAny(task.getSeriesRecordings(), seriesRecordings,
+ SeriesRecording.ID_COMPARATOR)) {
+ // The task is affected by the seriesRecordings
+ task.cancel(true);
+ previousSeriesRecordings.addAll(task.getSeriesRecordings());
+ iter.remove();
+ }
+ }
+ List<SeriesRecording> seriesRecordingsToUpdate = CollectionUtils.union(seriesRecordings,
+ previousSeriesRecordings, SeriesRecording.ID_COMPARATOR);
+ for (Iterator<SeriesRecording> iter = seriesRecordingsToUpdate.iterator();
+ iter.hasNext(); ) {
+ SeriesRecording seriesRecording = mDataManager.getSeriesRecording(iter.next().getId());
+ if (seriesRecording == null || seriesRecording.isStopped()) {
+ // Series recording has been removed or stopped.
+ iter.remove();
+ }
+ }
+ if (seriesRecordingsToUpdate.isEmpty()) {
+ return;
+ }
+ if (needToReadAllChannels(seriesRecordingsToUpdate)) {
+ SeriesRecordingUpdateTask task =
+ new SeriesRecordingUpdateTask(seriesRecordingsToUpdate);
+ mScheduleTasks.add(task);
+ if (DEBUG) Log.d(TAG, "Added schedule task: " + task);
+ task.execute();
+ } else {
+ for (SeriesRecording seriesRecording : seriesRecordingsToUpdate) {
+ SeriesRecordingUpdateTask task = new SeriesRecordingUpdateTask(
+ Collections.singletonList(seriesRecording));
+ mScheduleTasks.add(task);
+ if (DEBUG) Log.d(TAG, "Added schedule task: " + task);
+ task.execute();
+ }
+ }
+ }
+
+ private boolean needToReadAllChannels(List<SeriesRecording> seriesRecordingsToUpdate) {
+ for (SeriesRecording seriesRecording : seriesRecordingsToUpdate) {
+ if (seriesRecording.getChannelOption() == SeriesRecording.OPTION_CHANNEL_ALL) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Pick one program per an episode.
+ *
+ * <p>Note that the programs which has been already scheduled have the highest priority, and all
+ * of them are added even though they are the same episodes. That's because the schedules
+ * should be added to the series recording.
+ * <p>If there are no existing schedules for an episode, one program which starts earlier is
+ * picked.
+ */
+ private LongSparseArray<List<Program>> pickOneProgramPerEpisode(
+ List<SeriesRecording> seriesRecordings, List<Program> programs) {
+ return pickOneProgramPerEpisode(mDataManager, seriesRecordings, programs);
+ }
+
+ /**
+ * @see #pickOneProgramPerEpisode(List, List)
+ */
+ public static LongSparseArray<List<Program>> pickOneProgramPerEpisode(
+ DvrDataManager dataManager, List<SeriesRecording> seriesRecordings,
+ List<Program> programs) {
+ // Initialize.
+ LongSparseArray<List<Program>> result = new LongSparseArray<>();
+ Map<String, Long> seriesRecordingIds = new HashMap<>();
+ for (SeriesRecording seriesRecording : seriesRecordings) {
+ result.put(seriesRecording.getId(), new ArrayList<>());
+ seriesRecordingIds.put(seriesRecording.getSeriesId(), seriesRecording.getId());
+ }
+ // Group programs by the episode.
+ Map<SeasonEpisodeNumber, List<Program>> programsForEpisodeMap = new HashMap<>();
+ for (Program program : programs) {
+ long seriesRecordingId = seriesRecordingIds.get(program.getSeriesId());
+ if (TextUtils.isEmpty(program.getSeasonNumber())
+ || TextUtils.isEmpty(program.getEpisodeNumber())) {
+ // Add all the programs if it doesn't have season number or episode number.
+ result.get(seriesRecordingId).add(program);
+ continue;
+ }
+ SeasonEpisodeNumber seasonEpisodeNumber = new SeasonEpisodeNumber(seriesRecordingId,
+ program.getSeasonNumber(), program.getEpisodeNumber());
+ List<Program> programsForEpisode = programsForEpisodeMap.get(seasonEpisodeNumber);
+ if (programsForEpisode == null) {
+ programsForEpisode = new ArrayList<>();
+ programsForEpisodeMap.put(seasonEpisodeNumber, programsForEpisode);
+ }
+ programsForEpisode.add(program);
+ }
+ // Pick one program.
+ for (Entry<SeasonEpisodeNumber, List<Program>> entry : programsForEpisodeMap.entrySet()) {
+ List<Program> programsForEpisode = entry.getValue();
+ Collections.sort(programsForEpisode, new Comparator<Program>() {
+ @Override
+ public int compare(Program lhs, Program rhs) {
+ // Place the existing schedule first.
+ boolean lhsScheduled = isProgramScheduled(dataManager, lhs);
+ boolean rhsScheduled = isProgramScheduled(dataManager, rhs);
+ if (lhsScheduled && !rhsScheduled) {
+ return -1;
+ }
+ if (!lhsScheduled && rhsScheduled) {
+ return 1;
+ }
+ // Sort by the start time in ascending order.
+ return lhs.compareTo(rhs);
+ }
+ });
+ boolean added = false;
+ // Add all the scheduled programs
+ List<Program> programsForSeries = result.get(entry.getKey().seriesRecordingId);
+ for (Program program : programsForEpisode) {
+ if (isProgramScheduled(dataManager, program)) {
+ programsForSeries.add(program);
+ added = true;
+ } else if (!added) {
+ programsForSeries.add(program);
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ private static boolean isProgramScheduled(DvrDataManager dataManager, Program program) {
+ ScheduledRecording schedule =
+ dataManager.getScheduledRecordingForProgramId(program.getId());
+ return schedule != null && schedule.getState()
+ == ScheduledRecording.STATE_RECORDING_NOT_STARTED;
+ }
+
+ private void updateFetchedSeries() {
+ mSharedPreferences.edit().putStringSet(KEY_FETCHED_SERIES_IDS, mFetchedSeriesIds).apply();
+ }
+
+ /**
+ * This works only for the existing series recordings. Do not use this task for the
+ * "adding series recording" UI.
+ */
+ private class SeriesRecordingUpdateTask extends EpisodicProgramLoadTask {
+ SeriesRecordingUpdateTask(List<SeriesRecording> seriesRecordings) {
+ super(mContext, seriesRecordings);
+ }
+
+ @Override
+ protected void onPostExecute(List<Program> programs) {
+ if (DEBUG) Log.d(TAG, "onPostExecute: updating schedules with programs:" + programs);
+ mScheduleTasks.remove(this);
+ if (programs == null) {
+ Log.e(TAG, "Creating schedules for series recording failed: "
+ + getSeriesRecordings());
+ return;
+ }
+ LongSparseArray<List<Program>> seriesProgramMap = pickOneProgramPerEpisode(
+ getSeriesRecordings(), programs);
+ for (SeriesRecording seriesRecording : getSeriesRecordings()) {
+ // Check the series recording is still valid.
+ SeriesRecording actualSeriesRecording = mDataManager.getSeriesRecording(
+ seriesRecording.getId());
+ if (actualSeriesRecording == null || actualSeriesRecording.isStopped()) {
+ continue;
+ }
+ List<Program> programsToSchedule = seriesProgramMap.get(seriesRecording.getId());
+ if (mDataManager.getSeriesRecording(seriesRecording.getId()) != null
+ && !programsToSchedule.isEmpty()) {
+ mDvrManager.addScheduleToSeriesRecording(seriesRecording, programsToSchedule);
+ }
+ }
+ }
+
+ @Override
+ protected void onCancelled(List<Program> programs) {
+ mScheduleTasks.remove(this);
+ }
+
+ @Override
+ public String toString() {
+ return "SeriesRecordingUpdateTask:{"
+ + "series_recordings=" + getSeriesRecordings()
+ + "}";
+ }
+ }
+
+ private class FetchSeriesInfoTask extends AsyncTask<Void, Void, SeriesInfo> {
+ private SeriesRecording mSeriesRecording;
+
+ FetchSeriesInfoTask(SeriesRecording seriesRecording) {
+ mSeriesRecording = seriesRecording;
+ }
+
+ @Override
+ protected SeriesInfo doInBackground(Void... voids) {
+ return EpgFetcher.createEpgReader(mContext, LocationUtils.getCurrentCountry(mContext))
+ .getSeriesInfo(mSeriesRecording.getSeriesId());
+ }
+
+ @Override
+ protected void onPostExecute(SeriesInfo seriesInfo) {
+ if (seriesInfo != null) {
+ mDataManager.updateSeriesRecording(SeriesRecording.buildFrom(mSeriesRecording)
+ .setTitle(seriesInfo.getTitle())
+ .setDescription(seriesInfo.getDescription())
+ .setLongDescription(seriesInfo.getLongDescription())
+ .setCanonicalGenreIds(seriesInfo.getCanonicalGenreIds())
+ .setPosterUri(seriesInfo.getPosterUri())
+ .setPhotoUri(seriesInfo.getPhotoUri())
+ .build());
+ mFetchedSeriesIds.add(seriesInfo.getId());
+ updateFetchedSeries();
+ }
+ mFetchSeriesInfoTasks.remove(mSeriesRecording.getId());
+ }
+
+ @Override
+ protected void onCancelled(SeriesInfo seriesInfo) {
+ mFetchSeriesInfoTasks.remove(mSeriesRecording.getId());
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/ActionPresenterSelector.java b/src/com/android/tv/dvr/ui/ActionPresenterSelector.java
deleted file mode 100644
index 8b8cd5c5..00000000
--- a/src/com/android/tv/dvr/ui/ActionPresenterSelector.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.graphics.drawable.Drawable;
-import android.support.v17.leanback.R;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-// This class is adapted from Leanback's library, which does not support action icon with one-line
-// label. This class modified its getPresenter method to support the above situation.
-class ActionPresenterSelector extends PresenterSelector {
- private final Presenter mOneLineActionPresenter = new OneLineActionPresenter();
- private final Presenter mTwoLineActionPresenter = new TwoLineActionPresenter();
- private final Presenter[] mPresenters = new Presenter[] {
- mOneLineActionPresenter, mTwoLineActionPresenter};
-
- @Override
- public Presenter getPresenter(Object item) {
- Action action = (Action) item;
- if (TextUtils.isEmpty(action.getLabel2()) && action.getIcon() == null) {
- return mOneLineActionPresenter;
- } else {
- return mTwoLineActionPresenter;
- }
- }
-
- @Override
- public Presenter[] getPresenters() {
- return mPresenters;
- }
-
- static class ActionViewHolder extends Presenter.ViewHolder {
- Action mAction;
- Button mButton;
- int mLayoutDirection;
-
- public ActionViewHolder(View view, int layoutDirection) {
- super(view);
- mButton = (Button) view.findViewById(R.id.lb_action_button);
- mLayoutDirection = layoutDirection;
- }
- }
-
- class OneLineActionPresenter extends Presenter {
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent) {
- View v = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.lb_action_1_line, parent, false);
- return new ActionViewHolder(v, parent.getLayoutDirection());
- }
-
- @Override
- public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
- Action action = (Action) item;
- ActionViewHolder vh = (ActionViewHolder) viewHolder;
- vh.mAction = action;
- vh.mButton.setText(action.getLabel1());
- }
-
- @Override
- public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
- ((ActionViewHolder) viewHolder).mAction = null;
- }
- }
-
- class TwoLineActionPresenter extends Presenter {
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent) {
- View v = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.lb_action_2_lines, parent, false);
- return new ActionViewHolder(v, parent.getLayoutDirection());
- }
-
- @Override
- public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
- Action action = (Action) item;
- ActionViewHolder vh = (ActionViewHolder) viewHolder;
- Drawable icon = action.getIcon();
- vh.mAction = action;
-
- if (icon != null) {
- final int startPadding = vh.view.getResources()
- .getDimensionPixelSize(R.dimen.lb_action_with_icon_padding_start);
- final int endPadding = vh.view.getResources()
- .getDimensionPixelSize(R.dimen.lb_action_with_icon_padding_end);
- vh.view.setPaddingRelative(startPadding, 0, endPadding, 0);
- } else {
- final int padding = vh.view.getResources()
- .getDimensionPixelSize(R.dimen.lb_action_padding_horizontal);
- vh.view.setPaddingRelative(padding, 0, padding, 0);
- }
- if (vh.mLayoutDirection == View.LAYOUT_DIRECTION_RTL) {
- vh.mButton.setCompoundDrawablesWithIntrinsicBounds(null, null, icon, null);
- } else {
- vh.mButton.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
- }
-
- CharSequence line1 = action.getLabel1();
- CharSequence line2 = action.getLabel2();
- if (TextUtils.isEmpty(line1)) {
- vh.mButton.setText(line2);
- } else if (TextUtils.isEmpty(line2)) {
- vh.mButton.setText(line1);
- } else {
- vh.mButton.setText(line1 + "\n" + line2);
- }
- }
-
- @Override
- public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
- ActionViewHolder vh = (ActionViewHolder) viewHolder;
- vh.mButton.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
- vh.view.setPadding(0, 0, 0, 0);
- vh.mAction = null;
- }
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/BigArguments.java b/src/com/android/tv/dvr/ui/BigArguments.java
new file mode 100644
index 00000000..ec3b5065
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/BigArguments.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui;
+
+import android.support.annotation.NonNull;
+
+import com.android.tv.common.SoftPreconditions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Stores the object to pass through activities/fragments.
+ */
+public class BigArguments {
+ private final static String TAG = "BigArguments";
+ private static Map<String, Object> sBigArgumentMap = new HashMap<>();
+
+ /**
+ * Sets the argument.
+ */
+ public static void setArgument(String name, @NonNull Object value) {
+ SoftPreconditions.checkState(value != null, TAG, "Set argument, but value is null");
+ sBigArgumentMap.put(name, value);
+ }
+
+ /**
+ * Returns the argument which is associated to the name.
+ */
+ public static Object getArgument(String name) {
+ return sBigArgumentMap.get(name);
+ }
+
+ /**
+ * Resets the arguments.
+ */
+ public static void reset() {
+ sBigArgumentMap.clear();
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/ChangeImageTransformWithScaledParent.java b/src/com/android/tv/dvr/ui/ChangeImageTransformWithScaledParent.java
new file mode 100644
index 00000000..cddece73
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/ChangeImageTransformWithScaledParent.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Matrix;
+import android.graphics.drawable.BitmapDrawable;
+import android.transition.ChangeImageTransform;
+import android.transition.TransitionValues;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
+
+import com.android.tv.R;
+
+import java.util.Map;
+
+/**
+ * TODO: Remove this class once b/32405620 is fixed.
+ * This class is for the workaround of b/32405620 and only for the shared element transition between
+ * {@link com.android.tv.dvr.ui.browse.RecordingCardView} and
+ * {@link com.android.tv.dvr.ui.browse.DvrDetailsActivity}.
+ */
+public class ChangeImageTransformWithScaledParent extends ChangeImageTransform {
+ private static final String PROPNAME_MATRIX = "android:changeImageTransform:matrix";
+
+ public ChangeImageTransformWithScaledParent(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {
+ super.captureStartValues(transitionValues);
+ applyParentScale(transitionValues);
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ super.captureEndValues(transitionValues);
+ applyParentScale(transitionValues);
+ }
+
+ private void applyParentScale(TransitionValues transitionValues) {
+ View view = transitionValues.view;
+ Map<String, Object> values = transitionValues.values;
+ Matrix matrix = (Matrix) values.get(PROPNAME_MATRIX);
+ if (matrix != null && view.getId() == R.id.details_overview_image
+ && view instanceof ImageView) {
+ ImageView imageView = (ImageView) view;
+ if (imageView.getScaleType() == ScaleType.CENTER_INSIDE
+ && imageView.getDrawable() instanceof BitmapDrawable) {
+ Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
+ if (bitmap.getWidth() < imageView.getWidth()
+ && bitmap.getHeight() < imageView.getHeight()) {
+ float scale = imageView.getContext().getResources().getFraction(
+ R.fraction.lb_focus_zoom_factor_medium, 1, 1);
+ matrix.postScale(scale, scale, imageView.getWidth() / 2,
+ imageView.getHeight() / 2);
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/CurrentRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/CurrentRecordingDetailsFragment.java
deleted file mode 100644
index 5d8e20ff..00000000
--- a/src/com/android/tv/dvr/ui/CurrentRecordingDetailsFragment.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.content.res.Resources;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.dvr.DvrManager;
-
-/**
- * {@link RecordingDetailsFragment} for current recording in DVR.
- */
-public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
- private static final int ACTION_STOP_RECORDING = 1;
-
- @Override
- protected SparseArrayObjectAdapter onCreateActionsAdapter() {
- SparseArrayObjectAdapter adapter =
- new SparseArrayObjectAdapter(new ActionPresenterSelector());
- Resources res = getResources();
- adapter.set(ACTION_STOP_RECORDING, new Action(ACTION_STOP_RECORDING,
- res.getString(R.string.epg_dvr_dialog_message_stop_recording), null,
- res.getDrawable(R.drawable.lb_ic_stop)));
- return adapter;
- }
-
- @Override
- protected OnActionClickedListener onCreateOnActionClickedListener() {
- return new OnActionClickedListener() {
- @Override
- public void onActionClicked(Action action) {
- if (action.getId() == ACTION_STOP_RECORDING) {
- DvrManager dvrManager = TvApplication.getSingletons(getActivity())
- .getDvrManager();
- dvrManager.stopRecording(getRecording());
- }
- getActivity().finish();
- }
- };
- }
-}
diff --git a/src/com/android/tv/dvr/ui/DetailsContent.java b/src/com/android/tv/dvr/ui/DetailsContent.java
deleted file mode 100644
index 19521fca..00000000
--- a/src/com/android/tv/dvr/ui/DetailsContent.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.media.tv.TvContract;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.android.tv.data.BaseProgram;
-import com.android.tv.data.Channel;
-
-/**
- * A class for details content.
- */
-public class DetailsContent {
- /** Constant for invalid time. */
- public static final long INVALID_TIME = -1;
-
- private CharSequence mTitle;
- private long mStartTimeUtcMillis;
- private long mEndTimeUtcMillis;
- private String mDescription;
- private String mLogoImageUri;
- private String mBackgroundImageUri;
-
- private DetailsContent() { }
-
- /**
- * Returns title.
- */
- public CharSequence getTitle() {
- return mTitle;
- }
-
- /**
- * Returns start time.
- */
- public long getStartTimeUtcMillis() {
- return mStartTimeUtcMillis;
- }
-
- /**
- * Returns end time.
- */
- public long getEndTimeUtcMillis() {
- return mEndTimeUtcMillis;
- }
-
- /**
- * Returns description.
- */
- public String getDescription() {
- return mDescription;
- }
-
- /**
- * Returns Logo image URI as a String.
- */
- public String getLogoImageUri() {
- return mLogoImageUri;
- }
-
- /**
- * Returns background image URI as a String.
- */
- public String getBackgroundImageUri() {
- return mBackgroundImageUri;
- }
-
- /**
- * Copies other details content.
- */
- public void copyFrom(DetailsContent other) {
- if (this == other) {
- return;
- }
- mTitle = other.mTitle;
- mStartTimeUtcMillis = other.mStartTimeUtcMillis;
- mEndTimeUtcMillis = other.mEndTimeUtcMillis;
- mDescription = other.mDescription;
- mLogoImageUri = other.mLogoImageUri;
- mBackgroundImageUri = other.mBackgroundImageUri;
- }
-
- /**
- * A class for building details content.
- */
- public static final class Builder {
- private final DetailsContent mDetailsContent;
-
- public Builder() {
- mDetailsContent = new DetailsContent();
- mDetailsContent.mStartTimeUtcMillis = INVALID_TIME;
- mDetailsContent.mEndTimeUtcMillis = INVALID_TIME;
- }
-
- /**
- * Sets title.
- */
- public Builder setTitle(CharSequence title) {
- mDetailsContent.mTitle = title;
- return this;
- }
-
- /**
- * Sets start time.
- */
- public Builder setStartTimeUtcMillis(long startTimeUtcMillis) {
- mDetailsContent.mStartTimeUtcMillis = startTimeUtcMillis;
- return this;
- }
-
- /**
- * Sets end time.
- */
- public Builder setEndTimeUtcMillis(long endTimeUtcMillis) {
- mDetailsContent.mEndTimeUtcMillis = endTimeUtcMillis;
- return this;
- }
-
- /**
- * Sets description.
- */
- public Builder setDescription(String description) {
- mDetailsContent.mDescription = description;
- return this;
- }
-
- /**
- * Sets logo image URI as a String.
- */
- public Builder setLogoImageUri(String logoImageUri) {
- mDetailsContent.mLogoImageUri = logoImageUri;
- return this;
- }
-
- /**
- * Sets background image URI as a String.
- */
- public Builder setBackgroundImageUri(String backgroundImageUri) {
- mDetailsContent.mBackgroundImageUri = backgroundImageUri;
- return this;
- }
-
- /**
- * Sets background image and logo image URI from program and channel.
- */
- public Builder setImageUris(@Nullable BaseProgram program, @Nullable Channel channel) {
- if (program != null) {
- return setImageUris(program.getPosterArtUri(), program.getThumbnailUri(), channel);
- } else {
- return setImageUris(null, null, channel);
- }
- }
-
- /**
- * Sets background image and logo image URI and channel is used for fallback images.
- */
- public Builder setImageUris(@Nullable String posterArtUri,
- @Nullable String thumbnailUri, @Nullable Channel channel) {
- mDetailsContent.mLogoImageUri = null;
- mDetailsContent.mBackgroundImageUri = null;
- if (!TextUtils.isEmpty(posterArtUri) && !TextUtils.isEmpty(thumbnailUri)) {
- mDetailsContent.mLogoImageUri = posterArtUri;
- mDetailsContent.mBackgroundImageUri = thumbnailUri;
- } else if (!TextUtils.isEmpty(posterArtUri)) {
- // thumbnailUri is empty
- mDetailsContent.mLogoImageUri = posterArtUri;
- mDetailsContent.mBackgroundImageUri = posterArtUri;
- } else if (!TextUtils.isEmpty(thumbnailUri)) {
- // posterArtUri is empty
- mDetailsContent.mLogoImageUri = thumbnailUri;
- mDetailsContent.mBackgroundImageUri = thumbnailUri;
- }
- if (TextUtils.isEmpty(mDetailsContent.mLogoImageUri) && channel != null) {
- String channelLogoUri = TvContract.buildChannelLogoUri(channel.getId())
- .toString();
- mDetailsContent.mLogoImageUri = channelLogoUri;
- mDetailsContent.mBackgroundImageUri = channelLogoUri;
- }
- return this;
- }
-
- /**
- * Builds details content.
- */
- public DetailsContent build() {
- DetailsContent detailsContent = new DetailsContent();
- detailsContent.copyFrom(mDetailsContent);
- return detailsContent;
- }
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DetailsContentPresenter.java b/src/com/android/tv/dvr/ui/DetailsContentPresenter.java
deleted file mode 100644
index 175f05bc..00000000
--- a/src/com/android/tv/dvr/ui/DetailsContentPresenter.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.graphics.Paint;
-import android.graphics.Paint.FontMetricsInt;
-import android.support.v17.leanback.widget.Presenter;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.tv.R;
-import com.android.tv.ui.ViewUtils;
-import com.android.tv.util.Utils;
-
-/**
- * An {@link Presenter} for rendering a detailed description of an DVR item.
- * Typically this Presenter will be used in a {@link DetailsOverviewRowPresenter}.
- * Most codes of this class is originated from
- * {@link android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter}.
- * The latter class are re-used to provide a customized version of
- * {@link android.support.v17.leanback.widget.DetailsOverviewRow}.
- */
-public class DetailsContentPresenter extends Presenter {
- /**
- * The ViewHolder for the {@link DetailsContentPresenter}.
- */
- public static class ViewHolder extends Presenter.ViewHolder {
- final TextView mTitle;
- final TextView mSubtitle;
- final LinearLayout mDescriptionContainer;
- final TextView mBody;
- final TextView mReadMoreView;
- final int mTitleMargin;
- final int mUnderTitleBaselineMargin;
- final int mUnderSubtitleBaselineMargin;
- final int mTitleLineSpacing;
- final int mBodyLineSpacing;
- final int mBodyMaxLines;
- final int mBodyMinLines;
- final FontMetricsInt mTitleFontMetricsInt;
- final FontMetricsInt mSubtitleFontMetricsInt;
- final FontMetricsInt mBodyFontMetricsInt;
- final int mTitleMaxLines;
-
- private Activity mActivity;
- private boolean mFullTextMode;
- private int mFullTextAnimationDuration;
- private boolean mIsListeningToPreDraw;
-
- private ViewTreeObserver.OnPreDrawListener mPreDrawListener =
- new ViewTreeObserver.OnPreDrawListener() {
- @Override
- public boolean onPreDraw() {
- if (mSubtitle.getVisibility() == View.VISIBLE
- && mSubtitle.getTop() > view.getHeight()
- && mTitle.getLineCount() > 1) {
- mTitle.setMaxLines(mTitle.getLineCount() - 1);
- return false;
- }
- final int bodyLines = mBody.getLineCount();
- final int maxLines = mFullTextMode ? bodyLines :
- (mTitle.getLineCount() > 1 ? mBodyMinLines : mBodyMaxLines);
- if (bodyLines > maxLines) {
- mReadMoreView.setVisibility(View.VISIBLE);
- mDescriptionContainer.setFocusable(true);
- mDescriptionContainer.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mFullTextMode = true;
- mReadMoreView.setVisibility(View.GONE);
- mDescriptionContainer.setFocusable(false);
- mDescriptionContainer.setOnClickListener(null);
- mBody.setMaxLines(bodyLines);
- // Minus 1 from line difference to eliminate the space
- // originally occupied by "READ MORE"
- showFullText((bodyLines - maxLines - 1) * mBodyLineSpacing);
- }
- });
- }
- if (mBody.getMaxLines() != maxLines) {
- mBody.setMaxLines(maxLines);
- return false;
- } else {
- removePreDrawListener();
- return true;
- }
- }
- };
-
- public ViewHolder(final View view) {
- super(view);
- mTitle = (TextView) view.findViewById(R.id.dvr_details_description_title);
- mSubtitle = (TextView) view.findViewById(R.id.dvr_details_description_subtitle);
- mBody = (TextView) view.findViewById(R.id.dvr_details_description_body);
- mDescriptionContainer =
- (LinearLayout) view.findViewById(R.id.dvr_details_description_container);
- mReadMoreView = (TextView) view.findViewById(R.id.dvr_details_description_read_more);
-
- FontMetricsInt titleFontMetricsInt = getFontMetricsInt(mTitle);
- final int titleAscent = view.getResources().getDimensionPixelSize(
- R.dimen.lb_details_description_title_baseline);
- // Ascent is negative
- mTitleMargin = titleAscent + titleFontMetricsInt.ascent;
-
- mUnderTitleBaselineMargin = view.getResources().getDimensionPixelSize(
- R.dimen.lb_details_description_under_title_baseline_margin);
- mUnderSubtitleBaselineMargin = view.getResources().getDimensionPixelSize(
- R.dimen.lb_details_description_under_subtitle_baseline_margin);
-
- mTitleLineSpacing = view.getResources().getDimensionPixelSize(
- R.dimen.lb_details_description_title_line_spacing);
- mBodyLineSpacing = view.getResources().getDimensionPixelSize(
- R.dimen.lb_details_description_body_line_spacing);
-
- mBodyMaxLines = view.getResources().getInteger(
- R.integer.lb_details_description_body_max_lines);
- mBodyMinLines = view.getResources().getInteger(
- R.integer.lb_details_description_body_min_lines);
- mTitleMaxLines = mTitle.getMaxLines();
-
- mTitleFontMetricsInt = getFontMetricsInt(mTitle);
- mSubtitleFontMetricsInt = getFontMetricsInt(mSubtitle);
- mBodyFontMetricsInt = getFontMetricsInt(mBody);
- }
-
- void addPreDrawListener() {
- if (!mIsListeningToPreDraw) {
- mIsListeningToPreDraw = true;
- view.getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
- }
- }
-
- void removePreDrawListener() {
- if (mIsListeningToPreDraw) {
- view.getViewTreeObserver().removeOnPreDrawListener(mPreDrawListener);
- mIsListeningToPreDraw = false;
- }
- }
-
- public TextView getTitle() {
- return mTitle;
- }
-
- public TextView getSubtitle() {
- return mSubtitle;
- }
-
- public TextView getBody() {
- return mBody;
- }
-
- private FontMetricsInt getFontMetricsInt(TextView textView) {
- Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
- paint.setTextSize(textView.getTextSize());
- paint.setTypeface(textView.getTypeface());
- return paint.getFontMetricsInt();
- }
-
- private void showFullText(int heightDiff) {
- final ViewGroup detailsFrame = (ViewGroup) mActivity.findViewById(R.id.details_frame);
- int nowHeight = ViewUtils.getLayoutHeight(detailsFrame);
- Animator expandAnimator = ViewUtils.createHeightAnimator(
- detailsFrame, nowHeight, nowHeight + heightDiff);
- expandAnimator.setDuration(mFullTextAnimationDuration);
- Animator shiftAnimator = ObjectAnimator.ofPropertyValuesHolder(detailsFrame,
- PropertyValuesHolder.ofFloat(View.TRANSLATION_Y,
- 0f, -(heightDiff / 2)));
- shiftAnimator.setDuration(mFullTextAnimationDuration);
- AnimatorSet fullTextAnimator = new AnimatorSet();
- fullTextAnimator.playTogether(expandAnimator, shiftAnimator);
- fullTextAnimator.start();
- }
- }
-
- private final Activity mActivity;
- private final int mFullTextAnimationDuration;
-
- public DetailsContentPresenter(Activity activity) {
- super();
- mActivity = activity;
- mFullTextAnimationDuration = mActivity.getResources()
- .getInteger(R.integer.dvr_details_full_text_animation_duration);
- }
-
- @Override
- public final ViewHolder onCreateViewHolder(ViewGroup parent) {
- View v = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.dvr_details_description, parent, false);
- return new ViewHolder(v);
- }
-
- @Override
- public final void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
- final ViewHolder vh = (ViewHolder) viewHolder;
- final DetailsContent detailsContent = (DetailsContent) item;
-
- vh.mActivity = mActivity;
- vh.mFullTextAnimationDuration = mFullTextAnimationDuration;
-
- boolean hasTitle = true;
- if (TextUtils.isEmpty(detailsContent.getTitle())) {
- vh.mTitle.setVisibility(View.GONE);
- hasTitle = false;
- } else {
- vh.mTitle.setText(detailsContent.getTitle());
- vh.mTitle.setVisibility(View.VISIBLE);
- vh.mTitle.setLineSpacing(vh.mTitleLineSpacing - vh.mTitle.getLineHeight()
- + vh.mTitle.getLineSpacingExtra(), vh.mTitle.getLineSpacingMultiplier());
- vh.mTitle.setMaxLines(vh.mTitleMaxLines);
- }
- setTopMargin(vh.mTitle, vh.mTitleMargin);
-
- boolean hasSubtitle = true;
- if (detailsContent.getStartTimeUtcMillis() != DetailsContent.INVALID_TIME
- && detailsContent.getEndTimeUtcMillis() != DetailsContent.INVALID_TIME) {
- vh.mSubtitle.setText(Utils.getDurationString(viewHolder.view.getContext(),
- detailsContent.getStartTimeUtcMillis(),
- detailsContent.getEndTimeUtcMillis(), false));
- vh.mSubtitle.setVisibility(View.VISIBLE);
- if (hasTitle) {
- setTopMargin(vh.mSubtitle, vh.mUnderTitleBaselineMargin
- + vh.mSubtitleFontMetricsInt.ascent - vh.mTitleFontMetricsInt.descent);
- } else {
- setTopMargin(vh.mSubtitle, 0);
- }
- } else {
- vh.mSubtitle.setVisibility(View.GONE);
- hasSubtitle = false;
- }
-
- if (TextUtils.isEmpty(detailsContent.getDescription())) {
- vh.mBody.setVisibility(View.GONE);
- } else {
- vh.mBody.setText(detailsContent.getDescription());
- vh.mBody.setVisibility(View.VISIBLE);
- vh.mBody.setLineSpacing(vh.mBodyLineSpacing - vh.mBody.getLineHeight()
- + vh.mBody.getLineSpacingExtra(), vh.mBody.getLineSpacingMultiplier());
- if (hasSubtitle) {
- setTopMargin(vh.mDescriptionContainer, vh.mUnderSubtitleBaselineMargin
- + vh.mBodyFontMetricsInt.ascent - vh.mSubtitleFontMetricsInt.descent
- - vh.mBody.getPaddingTop());
- } else if (hasTitle) {
- setTopMargin(vh.mDescriptionContainer, vh.mUnderTitleBaselineMargin
- + vh.mBodyFontMetricsInt.ascent - vh.mTitleFontMetricsInt.descent
- - vh.mBody.getPaddingTop());
- } else {
- setTopMargin(vh.mDescriptionContainer, 0);
- }
- }
- }
-
- @Override
- public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { }
-
- @Override
- public void onViewAttachedToWindow(Presenter.ViewHolder holder) {
- // In case predraw listener was removed in detach, make sure
- // we have the proper layout.
- ViewHolder vh = (ViewHolder) holder;
- vh.addPreDrawListener();
- super.onViewAttachedToWindow(holder);
- }
-
- @Override
- public void onViewDetachedFromWindow(Presenter.ViewHolder holder) {
- ViewHolder vh = (ViewHolder) holder;
- vh.removePreDrawListener();
- super.onViewDetachedFromWindow(holder);
- }
-
- private void setTopMargin(View view, int topMargin) {
- ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
- lp.topMargin = topMargin;
- view.setLayoutParams(lp);
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DetailsViewBackgroundHelper.java b/src/com/android/tv/dvr/ui/DetailsViewBackgroundHelper.java
deleted file mode 100644
index 6714ecd3..00000000
--- a/src/com/android/tv/dvr/ui/DetailsViewBackgroundHelper.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.support.v17.leanback.app.BackgroundManager;
-
-/**
- * The Background Helper.
- */
-public class DetailsViewBackgroundHelper {
- // Background delay serves to avoid kicking off expensive bitmap loading
- // in case multiple backgrounds are set in quick succession.
- private static final int SET_BACKGROUND_DELAY_MS = 100;
-
- private final BackgroundManager mBackgroundManager;
-
- class LoadBackgroundRunnable implements Runnable {
- final Drawable mBackGround;
-
- LoadBackgroundRunnable(Drawable background) {
- mBackGround = background;
- }
-
- @Override
- public void run() {
- if (!mBackgroundManager.isAttached()) {
- return;
- }
- if (mBackGround instanceof BitmapDrawable) {
- mBackgroundManager.setBitmap(((BitmapDrawable) mBackGround).getBitmap());
- }
- mRunnable = null;
- }
- }
-
- private LoadBackgroundRunnable mRunnable;
-
- private final Handler mHandler = new Handler();
-
- public DetailsViewBackgroundHelper(Activity activity) {
- mBackgroundManager = BackgroundManager.getInstance(activity);
- mBackgroundManager.attach(activity.getWindow());
- }
-
- /**
- * Sets the given image to background.
- */
- public void setBackground(Drawable background) {
- if (mRunnable != null) {
- mHandler.removeCallbacks(mRunnable);
- }
- mRunnable = new LoadBackgroundRunnable(background);
- mHandler.postDelayed(mRunnable, SET_BACKGROUND_DELAY_MS);
- }
-
- /**
- * Sets the background color.
- */
- public void setBackgroundColor(int color) {
- if (mBackgroundManager.isAttached()) {
- mBackgroundManager.setColor(color);
- }
- }
-
- /**
- * Sets the background scrim.
- */
- public void setScrim(int color) {
- if (mBackgroundManager.isAttached()) {
- mBackgroundManager.setDimLayer(new ColorDrawable(color));
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/DvrActivity.java b/src/com/android/tv/dvr/ui/DvrActivity.java
deleted file mode 100644
index 45fb1cf1..00000000
--- a/src/com/android/tv/dvr/ui/DvrActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-
-/**
- * {@link android.app.Activity} for DVR UI.
- */
-public class DvrActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- TvApplication.setCurrentRunningProcess(this, true);
- super.onCreate(savedInstanceState);
- setContentView(R.layout.dvr_main);
- }
-}
diff --git a/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java b/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
index 9df228d1..62327870 100644
--- a/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrAlreadyRecordedFragment.java
@@ -24,15 +24,12 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
import android.support.v17.leanback.widget.GuidedAction;
-import android.widget.Toast;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.dvr.RecordedProgram;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.util.Utils;
+import com.android.tv.dvr.data.RecordedProgram;
import java.util.List;
@@ -92,7 +89,7 @@ public class DvrAlreadyRecordedFragment extends DvrGuidedStepFragment {
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
if (action.getId() == ACTION_RECORD_ANYWAY) {
getDvrManager().addSchedule(mProgram);
} else if (action.getId() == ACTION_WATCH) {
@@ -100,4 +97,23 @@ public class DvrAlreadyRecordedFragment extends DvrGuidedStepFragment {
}
dismissDialog();
}
+
+ @Override
+ public String getTrackerPrefix() {
+ return "onTrackedGuidedActionClicked";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_RECORD_ANYWAY) {
+ return "record-anyway";
+ } else if (actionId == ACTION_WATCH) {
+ return "watch-now";
+ } else if (actionId == ACTION_CANCEL) {
+ return "cancel-recording";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
}
diff --git a/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java b/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
index 78f21784..6da75e55 100644
--- a/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrAlreadyScheduledFragment.java
@@ -25,15 +25,12 @@ import android.support.annotation.NonNull;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
import android.support.v17.leanback.widget.GuidedAction;
import android.text.format.DateUtils;
-import android.widget.Toast;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.util.Utils;
+import com.android.tv.dvr.data.ScheduledRecording;
import java.util.List;
@@ -95,7 +92,7 @@ public class DvrAlreadyScheduledFragment extends DvrGuidedStepFragment {
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
if (action.getId() == ACTION_RECORD_ANYWAY) {
getDvrManager().addSchedule(mProgram);
} else if (action.getId() == ACTION_RECORD_INSTEAD) {
@@ -104,4 +101,23 @@ public class DvrAlreadyScheduledFragment extends DvrGuidedStepFragment {
}
dismissDialog();
}
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrAlreadyScheduledFragment";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_RECORD_ANYWAY) {
+ return "record-anyway";
+ } else if (actionId == ACTION_RECORD_INSTEAD) {
+ return "record-instead";
+ } else if (actionId == ACTION_CANCEL) {
+ return "cancel-recording";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
}
diff --git a/src/com/android/tv/dvr/ui/DvrBrowseFragment.java b/src/com/android/tv/dvr/ui/DvrBrowseFragment.java
deleted file mode 100644
index a6dd31d1..00000000
--- a/src/com/android/tv/dvr/ui/DvrBrowseFragment.java
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr.ui;
-
-import android.content.Context;
-import android.media.tv.TvInputManager.TvInputCallback;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v17.leanback.app.BrowseFragment;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.TitleViewAdapter;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.tv.ApplicationSingletons;
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.GenreItems;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener;
-import com.android.tv.dvr.DvrDataManager.OnRecordedProgramLoadFinishedListener;
-import com.android.tv.dvr.DvrDataManager.RecordedProgramListener;
-import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
-import com.android.tv.dvr.DvrDataManager.SeriesRecordingListener;
-import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.RecordedProgram;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.dvr.SeriesRecording;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * {@link BrowseFragment} for DVR functions.
- */
-public class DvrBrowseFragment extends BrowseFragment implements
- RecordedProgramListener, ScheduledRecordingListener, SeriesRecordingListener,
- OnDvrScheduleLoadFinishedListener, OnRecordedProgramLoadFinishedListener {
- private static final String TAG = "DvrBrowseFragment";
- private static final boolean DEBUG = false;
-
- private static final int MAX_RECENT_ITEM_COUNT = 10;
- private static final int MAX_SCHEDULED_ITEM_COUNT = 4;
-
- private RecordedProgramAdapter mRecentAdapter;
- private ScheduleAdapter mScheduleAdapter;
- private SeriesAdapter mSeriesAdapter;
- private RecordedProgramAdapter[] mGenreAdapters =
- new RecordedProgramAdapter[GenreItems.getGenreCount() + 1];
- private ListRow mRecentRow;
- private ListRow mSeriesRow;
- private ListRow[] mGenreRows = new ListRow[GenreItems.getGenreCount() + 1];
- private List<String> mGenreLabels;
- private DvrDataManager mDvrDataManager;
- private DvrScheduleManager mDvrScheudleManager;
- private ArrayObjectAdapter mRowsAdapter;
- private ClassPresenterSelector mPresenterSelector;
- private final HashMap<String, RecordedProgram> mSeriesId2LatestProgram = new HashMap<>();
- private final Handler mHandler = new Handler();
-
- private final Comparator<Object> RECORDED_PROGRAM_COMPARATOR = new Comparator<Object>() {
- @Override
- public int compare(Object lhs, Object rhs) {
- if (lhs instanceof SeriesRecording) {
- lhs = mSeriesId2LatestProgram.get(((SeriesRecording) lhs).getSeriesId());
- }
- if (rhs instanceof SeriesRecording) {
- rhs = mSeriesId2LatestProgram.get(((SeriesRecording) rhs).getSeriesId());
- }
- if (lhs instanceof RecordedProgram) {
- if (rhs instanceof RecordedProgram) {
- return RecordedProgram.START_TIME_THEN_ID_COMPARATOR.reversed()
- .compare((RecordedProgram) lhs, (RecordedProgram) rhs);
- } else {
- return -1;
- }
- } else if (rhs instanceof RecordedProgram) {
- return 1;
- } else {
- return 0;
- }
- }
- };
-
- private final Comparator<Object> SCHEDULE_COMPARATOR = new Comparator<Object>() {
- @Override
- public int compare(Object lhs, Object rhs) {
- if (lhs instanceof ScheduledRecording) {
- if (rhs instanceof ScheduledRecording) {
- return ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR
- .compare((ScheduledRecording) lhs, (ScheduledRecording) rhs);
- } else {
- return -1;
- }
- } else if (rhs instanceof ScheduledRecording) {
- return 1;
- } else {
- return 0;
- }
- }
- };
-
- private final DvrScheduleManager.OnConflictStateChangeListener mOnConflictStateChangeListener =
- new DvrScheduleManager.OnConflictStateChangeListener() {
- @Override
- public void onConflictStateChange(boolean conflict, ScheduledRecording... schedules) {
- if (mScheduleAdapter != null) {
- for (ScheduledRecording schedule : schedules) {
- onScheduledRecordingStatusChanged(schedule);
- }
- }
- }
- };
-
- private final Runnable mUpdateRowsRunnable = new Runnable() {
- @Override
- public void run() {
- updateRows();
- }
- };
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- if (DEBUG) Log.d(TAG, "onCreate");
- super.onCreate(savedInstanceState);
- Context context = getContext();
- ApplicationSingletons singletons = TvApplication.getSingletons(context);
- mDvrDataManager = singletons.getDvrDataManager();
- mDvrScheudleManager = singletons.getDvrScheduleManager();
- mPresenterSelector = new ClassPresenterSelector()
- .addClassPresenter(ScheduledRecording.class,
- new ScheduledRecordingPresenter(context))
- .addClassPresenter(RecordedProgram.class, new RecordedProgramPresenter(context))
- .addClassPresenter(SeriesRecording.class, new SeriesRecordingPresenter(context))
- .addClassPresenter(FullScheduleCardHolder.class, new FullSchedulesCardPresenter());
- mGenreLabels = new ArrayList<>(Arrays.asList(GenreItems.getLabels(context)));
- mGenreLabels.add(getString(R.string.dvr_main_others));
- setupUiElements();
- setupAdapters();
- mDvrScheudleManager.addOnConflictStateChangeListener(mOnConflictStateChangeListener);
- prepareEntranceTransition();
- if (mDvrDataManager.isInitialized()) {
- startEntranceTransition();
- } else {
- if (!mDvrDataManager.isDvrScheduleLoadFinished()) {
- mDvrDataManager.addDvrScheduleLoadFinishedListener(this);
- }
- if (!mDvrDataManager.isRecordedProgramLoadFinished()) {
- mDvrDataManager.addRecordedProgramLoadFinishedListener(this);
- }
- }
- }
-
- @Override
- public void onDestroy() {
- if (DEBUG) Log.d(TAG, "onDestroy");
- mHandler.removeCallbacks(mUpdateRowsRunnable);
- mDvrScheudleManager.removeOnConflictStateChangeListener(mOnConflictStateChangeListener);
- mDvrDataManager.removeRecordedProgramListener(this);
- mDvrDataManager.removeScheduledRecordingListener(this);
- mDvrDataManager.removeSeriesRecordingListener(this);
- mDvrDataManager.removeDvrScheduleLoadFinishedListener(this);
- mDvrDataManager.removeRecordedProgramLoadFinishedListener(this);
- mRowsAdapter.clear();
- mSeriesId2LatestProgram.clear();
- for (Presenter presenter : mPresenterSelector.getPresenters()) {
- if (presenter instanceof DvrItemPresenter) {
- ((DvrItemPresenter) presenter).unbindAllViewHolders();
- }
- }
- super.onDestroy();
- }
-
- @Override
- public void onDvrScheduleLoadFinished() {
- List<ScheduledRecording> scheduledRecordings = mDvrDataManager.getAllScheduledRecordings();
- onScheduledRecordingAdded(ScheduledRecording.toArray(scheduledRecordings));
- List<SeriesRecording> seriesRecordings = mDvrDataManager.getSeriesRecordings();
- onSeriesRecordingAdded(SeriesRecording.toArray(seriesRecordings));
- if (mDvrDataManager.isInitialized()) {
- startEntranceTransition();
- }
- mDvrDataManager.removeDvrScheduleLoadFinishedListener(this);
- }
-
- @Override
- public void onRecordedProgramLoadFinished() {
- for (RecordedProgram recordedProgram : mDvrDataManager.getRecordedPrograms()) {
- handleRecordedProgramAdded(recordedProgram, true);
- }
- updateRows();
- if (mDvrDataManager.isInitialized()) {
- startEntranceTransition();
- }
- mDvrDataManager.removeRecordedProgramLoadFinishedListener(this);
- }
-
- @Override
- public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) {
- for (RecordedProgram recordedProgram : recordedPrograms) {
- handleRecordedProgramAdded(recordedProgram, true);
- }
- postUpdateRows();
- }
-
- @Override
- public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) {
- for (RecordedProgram recordedProgram : recordedPrograms) {
- handleRecordedProgramChanged(recordedProgram);
- }
- postUpdateRows();
- }
-
- @Override
- public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) {
- for (RecordedProgram recordedProgram : recordedPrograms) {
- handleRecordedProgramRemoved(recordedProgram);
- }
- postUpdateRows();
- }
-
- // No need to call updateRows() during ScheduledRecordings' change because
- // the row for ScheduledRecordings is always displayed.
- @Override
- public void onScheduledRecordingAdded(ScheduledRecording... scheduledRecordings) {
- for (ScheduledRecording scheduleRecording : scheduledRecordings) {
- if (needToShowScheduledRecording(scheduleRecording)) {
- mScheduleAdapter.add(scheduleRecording);
- }
- }
- }
-
- @Override
- public void onScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings) {
- for (ScheduledRecording scheduleRecording : scheduledRecordings) {
- mScheduleAdapter.remove(scheduleRecording);
- }
- }
-
- @Override
- public void onScheduledRecordingStatusChanged(ScheduledRecording... scheduledRecordings) {
- for (ScheduledRecording scheduleRecording : scheduledRecordings) {
- if (needToShowScheduledRecording(scheduleRecording)) {
- mScheduleAdapter.change(scheduleRecording);
- } else {
- mScheduleAdapter.removeWithId(scheduleRecording);
- }
- }
- }
-
- @Override
- public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) {
- handleSeriesRecordingsAdded(Arrays.asList(seriesRecordings));
- postUpdateRows();
- }
-
- @Override
- public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) {
- handleSeriesRecordingsRemoved(Arrays.asList(seriesRecordings));
- postUpdateRows();
- }
-
- @Override
- public void onSeriesRecordingChanged(SeriesRecording... seriesRecordings) {
- handleSeriesRecordingsChanged(Arrays.asList(seriesRecordings));
- postUpdateRows();
- }
-
- // Workaround of b/29108300
- @Override
- public void showTitle(int flags) {
- flags &= ~TitleViewAdapter.SEARCH_VIEW_VISIBLE;
- super.showTitle(flags);
- }
-
- private void setupUiElements() {
- setBadgeDrawable(getActivity().getDrawable(R.drawable.ic_dvr_badge));
- setHeadersState(HEADERS_ENABLED);
- setHeadersTransitionOnBackEnabled(false);
- setBrandColor(getResources().getColor(R.color.program_guide_side_panel_background, null));
- }
-
- private void setupAdapters() {
- mRecentAdapter = new RecordedProgramAdapter(MAX_RECENT_ITEM_COUNT);
- mScheduleAdapter = new ScheduleAdapter(MAX_SCHEDULED_ITEM_COUNT);
- mSeriesAdapter = new SeriesAdapter();
- for (int i = 0; i < mGenreAdapters.length; i++) {
- mGenreAdapters[i] = new RecordedProgramAdapter();
- }
- // Schedule Recordings.
- List<ScheduledRecording> schedules = mDvrDataManager.getAllScheduledRecordings();
- onScheduledRecordingAdded(ScheduledRecording.toArray(schedules));
- mScheduleAdapter.addExtraItem(FullScheduleCardHolder.FULL_SCHEDULE_CARD_HOLDER);
- // Recorded Programs.
- for (RecordedProgram recordedProgram : mDvrDataManager.getRecordedPrograms()) {
- handleRecordedProgramAdded(recordedProgram, false);
- }
- // Series Recordings. Series recordings should be added after recorded programs, because
- // we build series recordings' latest program information while adding recorded programs.
- List<SeriesRecording> recordings = mDvrDataManager.getSeriesRecordings();
- handleSeriesRecordingsAdded(recordings);
- mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
- mRecentRow = new ListRow(new HeaderItem(
- getString(R.string.dvr_main_recent)), mRecentAdapter);
- mRowsAdapter.add(new ListRow(new HeaderItem(
- getString(R.string.dvr_main_scheduled)), mScheduleAdapter));
- mSeriesRow = new ListRow(new HeaderItem(
- getString(R.string.dvr_main_series)), mSeriesAdapter);
- updateRows();
- mDvrDataManager.addRecordedProgramListener(this);
- mDvrDataManager.addScheduledRecordingListener(this);
- mDvrDataManager.addSeriesRecordingListener(this);
- setAdapter(mRowsAdapter);
- }
-
- private void handleRecordedProgramAdded(RecordedProgram recordedProgram,
- boolean updateSeriesRecording) {
- mRecentAdapter.add(recordedProgram);
- String seriesId = recordedProgram.getSeriesId();
- SeriesRecording seriesRecording = null;
- if (seriesId != null) {
- seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
- RecordedProgram latestProgram = mSeriesId2LatestProgram.get(seriesId);
- if (latestProgram == null || RecordedProgram.START_TIME_THEN_ID_COMPARATOR
- .compare(latestProgram, recordedProgram) < 0) {
- mSeriesId2LatestProgram.put(seriesId, recordedProgram);
- if (updateSeriesRecording && seriesRecording != null) {
- onSeriesRecordingChanged(seriesRecording);
- }
- }
- }
- if (seriesRecording == null) {
- for (RecordedProgramAdapter adapter
- : getGenreAdapters(recordedProgram.getCanonicalGenres())) {
- adapter.add(recordedProgram);
- }
- }
- }
-
- private void handleRecordedProgramRemoved(RecordedProgram recordedProgram) {
- mRecentAdapter.remove(recordedProgram);
- String seriesId = recordedProgram.getSeriesId();
- if (seriesId != null) {
- SeriesRecording seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
- RecordedProgram latestProgram =
- mSeriesId2LatestProgram.get(recordedProgram.getSeriesId());
- if (latestProgram != null && latestProgram.getId() == recordedProgram.getId()) {
- if (seriesRecording != null) {
- updateLatestRecordedProgram(seriesRecording);
- onSeriesRecordingChanged(seriesRecording);
- }
- }
- }
- for (RecordedProgramAdapter adapter
- : getGenreAdapters(recordedProgram.getCanonicalGenres())) {
- adapter.remove(recordedProgram);
- }
- }
-
- private void handleRecordedProgramChanged(RecordedProgram recordedProgram) {
- mRecentAdapter.change(recordedProgram);
- String seriesId = recordedProgram.getSeriesId();
- SeriesRecording seriesRecording = null;
- if (seriesId != null) {
- seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
- RecordedProgram latestProgram = mSeriesId2LatestProgram.get(seriesId);
- if (latestProgram == null || RecordedProgram.START_TIME_THEN_ID_COMPARATOR
- .compare(latestProgram, recordedProgram) <= 0) {
- mSeriesId2LatestProgram.put(seriesId, recordedProgram);
- if (seriesRecording != null) {
- onSeriesRecordingChanged(seriesRecording);
- }
- } else if (latestProgram.getId() == recordedProgram.getId()) {
- if (seriesRecording != null) {
- updateLatestRecordedProgram(seriesRecording);
- onSeriesRecordingChanged(seriesRecording);
- }
- }
- }
- if (seriesRecording == null) {
- updateGenreAdapters(getGenreAdapters(
- recordedProgram.getCanonicalGenres()), recordedProgram);
- } else {
- updateGenreAdapters(new ArrayList<>(), recordedProgram);
- }
- }
-
- private void handleSeriesRecordingsAdded(List<SeriesRecording> seriesRecordings) {
- for (SeriesRecording seriesRecording : seriesRecordings) {
- mSeriesAdapter.add(seriesRecording);
- if (mSeriesId2LatestProgram.get(seriesRecording.getSeriesId()) != null) {
- for (RecordedProgramAdapter adapter
- : getGenreAdapters(seriesRecording.getCanonicalGenreIds())) {
- adapter.add(seriesRecording);
- }
- }
- }
- }
-
- private void handleSeriesRecordingsRemoved(List<SeriesRecording> seriesRecordings) {
- for (SeriesRecording seriesRecording : seriesRecordings) {
- mSeriesAdapter.remove(seriesRecording);
- for (RecordedProgramAdapter adapter
- : getGenreAdapters(seriesRecording.getCanonicalGenreIds())) {
- adapter.remove(seriesRecording);
- }
- }
- }
-
- private void handleSeriesRecordingsChanged(List<SeriesRecording> seriesRecordings) {
- for (SeriesRecording seriesRecording : seriesRecordings) {
- mSeriesAdapter.change(seriesRecording);
- if (mSeriesId2LatestProgram.get(seriesRecording.getSeriesId()) != null) {
- updateGenreAdapters(getGenreAdapters(
- seriesRecording.getCanonicalGenreIds()), seriesRecording);
- } else {
- // Remove series recording from all genre rows if it has no recorded program
- updateGenreAdapters(new ArrayList<>(), seriesRecording);
- }
- }
- }
-
- private List<RecordedProgramAdapter> getGenreAdapters(String[] genres) {
- List<RecordedProgramAdapter> result = new ArrayList<>();
- if (genres == null || genres.length == 0) {
- result.add(mGenreAdapters[mGenreAdapters.length - 1]);
- } else {
- for (String genre : genres) {
- int genreId = GenreItems.getId(genre);
- if(genreId >= mGenreAdapters.length) {
- Log.d(TAG, "Wrong Genre ID: " + genreId);
- } else {
- result.add(mGenreAdapters[genreId]);
- }
- }
- }
- return result;
- }
-
- private List<RecordedProgramAdapter> getGenreAdapters(int[] genreIds) {
- List<RecordedProgramAdapter> result = new ArrayList<>();
- if (genreIds == null || genreIds.length == 0) {
- result.add(mGenreAdapters[mGenreAdapters.length - 1]);
- } else {
- for (int genreId : genreIds) {
- if(genreId >= mGenreAdapters.length) {
- Log.d(TAG, "Wrong Genre ID: " + genreId);
- } else {
- result.add(mGenreAdapters[genreId]);
- }
- }
- }
- return result;
- }
-
- private void updateGenreAdapters(List<RecordedProgramAdapter> adapters, Object r) {
- for (RecordedProgramAdapter adapter : mGenreAdapters) {
- if (adapters.contains(adapter)) {
- adapter.change(r);
- } else {
- adapter.remove(r);
- }
- }
- }
-
- private void postUpdateRows() {
- mHandler.removeCallbacks(mUpdateRowsRunnable);
- mHandler.post(mUpdateRowsRunnable);
- }
-
- private void updateRows() {
- int visibleRowsCount = 1; // Schedule's Row will never be empty
- if (mRecentAdapter.isEmpty()) {
- mRowsAdapter.remove(mRecentRow);
- } else {
- if (mRowsAdapter.indexOf(mRecentRow) < 0) {
- mRowsAdapter.add(0, mRecentRow);
- }
- visibleRowsCount++;
- }
- if (mSeriesAdapter.isEmpty()) {
- mRowsAdapter.remove(mSeriesRow);
- } else {
- if (mRowsAdapter.indexOf(mSeriesRow) < 0) {
- mRowsAdapter.add(visibleRowsCount, mSeriesRow);
- }
- visibleRowsCount++;
- }
- for (int i = 0; i < mGenreAdapters.length; i++) {
- RecordedProgramAdapter adapter = mGenreAdapters[i];
- if (adapter != null) {
- if (adapter.isEmpty()) {
- mRowsAdapter.remove(mGenreRows[i]);
- } else {
- if (mGenreRows[i] == null || mRowsAdapter.indexOf(mGenreRows[i]) < 0) {
- mGenreRows[i] = new ListRow(new HeaderItem(mGenreLabels.get(i)), adapter);
- mRowsAdapter.add(visibleRowsCount, mGenreRows[i]);
- }
- visibleRowsCount++;
- }
- }
- }
- }
-
- private boolean needToShowScheduledRecording(ScheduledRecording recording) {
- int state = recording.getState();
- return state == ScheduledRecording.STATE_RECORDING_IN_PROGRESS
- || state == ScheduledRecording.STATE_RECORDING_NOT_STARTED;
- }
-
- private void updateLatestRecordedProgram(SeriesRecording seriesRecording) {
- RecordedProgram latestProgram = null;
- for (RecordedProgram program :
- mDvrDataManager.getRecordedPrograms(seriesRecording.getId())) {
- if (latestProgram == null || RecordedProgram
- .START_TIME_THEN_ID_COMPARATOR.compare(latestProgram, program) < 0) {
- latestProgram = program;
- }
- }
- mSeriesId2LatestProgram.put(seriesRecording.getSeriesId(), latestProgram);
- }
-
- private class ScheduleAdapter extends SortedArrayAdapter<Object> {
- ScheduleAdapter(int maxItemCount) {
- super(mPresenterSelector, SCHEDULE_COMPARATOR, maxItemCount);
- }
-
- @Override
- public long getId(Object item) {
- if (item instanceof ScheduledRecording) {
- return ((ScheduledRecording) item).getId();
- } else {
- return -1;
- }
- }
- }
-
- private class SeriesAdapter extends SortedArrayAdapter<SeriesRecording> {
- SeriesAdapter() {
- super(mPresenterSelector, new Comparator<SeriesRecording>() {
- @Override
- public int compare(SeriesRecording lhs, SeriesRecording rhs) {
- if (lhs.isStopped() && !rhs.isStopped()) {
- return 1;
- } else if (!lhs.isStopped() && rhs.isStopped()) {
- return -1;
- }
- return SeriesRecording.PRIORITY_COMPARATOR.compare(lhs, rhs);
- }
- });
- }
-
- @Override
- public long getId(SeriesRecording item) {
- return item.getId();
- }
- }
-
- private class RecordedProgramAdapter extends SortedArrayAdapter<Object> {
- RecordedProgramAdapter() {
- this(Integer.MAX_VALUE);
- }
-
- RecordedProgramAdapter(int maxItemCount) {
- super(mPresenterSelector, RECORDED_PROGRAM_COMPARATOR, maxItemCount);
- }
-
- @Override
- public long getId(Object item) {
- if (item instanceof SeriesRecording) {
- return ((SeriesRecording) item).getId();
- } else if (item instanceof RecordedProgram) {
- return ((RecordedProgram) item).getId();
- } else {
- return -1;
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java b/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
index 837d8ab2..36659412 100644
--- a/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrChannelRecordDurationOptionFragment.java
@@ -27,7 +27,7 @@ import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrChannelRecordConflictFragment;
import java.util.ArrayList;
@@ -85,7 +85,7 @@ public class DvrChannelRecordDurationOptionFragment extends DvrGuidedStepFragmen
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
long duration = mDurations.get((int) action.getId());
long startTimeMs = System.currentTimeMillis();
@@ -106,4 +106,25 @@ public class DvrChannelRecordDurationOptionFragment extends DvrGuidedStepFragmen
R.id.halfsized_dialog_host);
}
}
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrChannelRecordDurationOptionFragment";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == 0) {
+ return "record-10-minutes";
+ } else if (actionId == 1) {
+ return "record-30-minutes";
+ } else if (actionId == 2) {
+ return "record-1-hour";
+ } else if (actionId == 3) {
+ return "record-3-hour";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
}
diff --git a/src/com/android/tv/dvr/ui/DvrConflictFragment.java b/src/com/android/tv/dvr/ui/DvrConflictFragment.java
index e7be4d0a..6f362e68 100644
--- a/src/com/android/tv/dvr/ui/DvrConflictFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrConflictFragment.java
@@ -34,10 +34,9 @@ import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
-import com.android.tv.dvr.ConflictChecker;
-import com.android.tv.dvr.ConflictChecker.OnUpcomingConflictChangeListener;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.recorder.ConflictChecker;
+import com.android.tv.dvr.recorder.ConflictChecker.OnUpcomingConflictChangeListener;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.util.Utils;
import java.util.ArrayList;
@@ -85,7 +84,7 @@ public abstract class DvrConflictFragment extends DvrGuidedStepFragment {
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
if (action.getId() == ACTION_VIEW_SCHEDULES) {
DvrUiHelper.startSchedulesActivityForOneTimeRecordingConflict(
getContext(), getConflicts());
@@ -93,6 +92,16 @@ public abstract class DvrConflictFragment extends DvrGuidedStepFragment {
dismissDialog();
}
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = getId();
+ if (actionId == ACTION_VIEW_SCHEDULES) {
+ return "view-schedules";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
+
String getConflictDescription() {
List<String> titles = new ArrayList<>();
HashSet<String> titleSet = new HashSet<>();
@@ -185,6 +194,11 @@ public abstract class DvrConflictFragment extends DvrGuidedStepFragment {
Drawable icon = getResources().getDrawable(R.drawable.ic_error_white_48dp, null);
return new Guidance(title, descriptionPrefix + " " + description, null, icon);
}
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrProgramConflictFragment";
+ }
}
/**
@@ -236,6 +250,11 @@ public abstract class DvrConflictFragment extends DvrGuidedStepFragment {
Drawable icon = getResources().getDrawable(R.drawable.ic_error_white_48dp, null);
return new Guidance(title, descriptionPrefix + " " + description, null, icon);
}
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrChannelRecordConflictFragment";
+ }
}
/**
@@ -300,7 +319,7 @@ public abstract class DvrConflictFragment extends DvrGuidedStepFragment {
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
if (action.getId() == ACTION_CANCEL) {
ConflictChecker checker = ((MainActivity) getContext()).getDvrConflictChecker();
if (checker != null) {
@@ -319,6 +338,23 @@ public abstract class DvrConflictFragment extends DvrGuidedStepFragment {
}
@Override
+ public String getTrackerPrefix() {
+ return "DvrChannelWatchConflictFragment";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_CANCEL) {
+ return "cancel";
+ } else if (actionId == ACTION_DELETE_CONFLICT) {
+ return "delete";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
+
+ @Override
public void onDetach() {
ConflictChecker checker = ((MainActivity) getContext()).getDvrConflictChecker();
if (checker != null) {
diff --git a/src/com/android/tv/dvr/ui/DvrDetailsActivity.java b/src/com/android/tv/dvr/ui/DvrDetailsActivity.java
deleted file mode 100644
index 806c775c..00000000
--- a/src/com/android/tv/dvr/ui/DvrDetailsActivity.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.support.v17.leanback.app.DetailsFragment;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-
-/**
- * Activity to show details view in DVR.
- */
-public class DvrDetailsActivity extends Activity {
- /**
- * Name of record id added to the Intent.
- */
- public static final String RECORDING_ID = "record_id";
-
- /**
- * Name of flag added to the Intent to determine if details view should hide "View schedule"
- * button.
- */
- public static final String HIDE_VIEW_SCHEDULE = "hide_view_schedule";
-
- /**
- * Name of details view's type added to the intent.
- */
- public static final String DETAILS_VIEW_TYPE = "details_view_type";
-
- /**
- * Name of shared element between activities.
- */
- public static final String SHARED_ELEMENT_NAME = "shared_element";
-
- /**
- * CURRENT_RECORDING_VIEW refers to Current Recordings in DVR.
- */
- public static final int CURRENT_RECORDING_VIEW = 1;
-
- /**
- * SCHEDULED_RECORDING_VIEW refers to Scheduled Recordings in DVR.
- */
- public static final int SCHEDULED_RECORDING_VIEW = 2;
-
- /**
- * RECORDED_PROGRAM_VIEW refers to Recorded programs in DVR.
- */
- public static final int RECORDED_PROGRAM_VIEW = 3;
-
- /**
- * SERIES_RECORDING_VIEW refers to series recording in DVR.
- */
- public static final int SERIES_RECORDING_VIEW = 4;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- TvApplication.setCurrentRunningProcess(this, true);
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_dvr_details);
- long recordId = getIntent().getLongExtra(RECORDING_ID, -1);
- int detailsViewType = getIntent().getIntExtra(DETAILS_VIEW_TYPE, -1);
- boolean hideViewSchedule = getIntent().getBooleanExtra(HIDE_VIEW_SCHEDULE, false);
- if (recordId != -1 && detailsViewType != -1 && savedInstanceState == null) {
- Bundle args = new Bundle();
- args.putLong(RECORDING_ID, recordId);
- DetailsFragment detailsFragment = null;
- if (detailsViewType == CURRENT_RECORDING_VIEW) {
- detailsFragment = new CurrentRecordingDetailsFragment();
- } else if (detailsViewType == SCHEDULED_RECORDING_VIEW) {
- args.putBoolean(HIDE_VIEW_SCHEDULE, hideViewSchedule);
- detailsFragment = new ScheduledRecordingDetailsFragment();
- } else if (detailsViewType == RECORDED_PROGRAM_VIEW) {
- detailsFragment = new RecordedProgramDetailsFragment();
- } else if (detailsViewType == SERIES_RECORDING_VIEW) {
- detailsFragment = new SeriesRecordingDetailsFragment();
- }
- detailsFragment.setArguments(args);
- getFragmentManager().beginTransaction()
- .replace(R.id.dvr_details_view_frame, detailsFragment).commit();
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/DvrDetailsFragment.java b/src/com/android/tv/dvr/ui/DvrDetailsFragment.java
deleted file mode 100644
index 21f9c4b4..00000000
--- a/src/com/android/tv/dvr/ui/DvrDetailsFragment.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.media.tv.TvContentRating;
-import android.media.tv.TvInputManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v17.leanback.app.DetailsFragment;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.support.v17.leanback.widget.DetailsOverviewRow;
-import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.support.v17.leanback.widget.VerticalGridView;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.text.style.TextAppearanceSpan;
-import android.widget.Toast;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.BaseProgram;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dialog.PinDialogFragment;
-import com.android.tv.dvr.DvrPlaybackActivity;
-import com.android.tv.dvr.RecordedProgram;
-import com.android.tv.parental.ParentalControlSettings;
-import com.android.tv.util.ImageLoader;
-import com.android.tv.util.ToastUtils;
-import com.android.tv.util.Utils;
-
-import java.io.File;
-
-abstract class DvrDetailsFragment extends DetailsFragment {
- private static final int LOAD_LOGO_IMAGE = 1;
- private static final int LOAD_BACKGROUND_IMAGE = 2;
-
- protected DetailsViewBackgroundHelper mBackgroundHelper;
- private ArrayObjectAdapter mRowsAdapter;
- private DetailsOverviewRow mDetailsOverview;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (!onLoadRecordingDetails(getArguments())) {
- getActivity().finish();
- return;
- }
- mBackgroundHelper = new DetailsViewBackgroundHelper(getActivity());
- setupAdapter();
- onCreateInternal();
- }
-
- @Override
- public void onStart() {
- super.onStart();
- // TODO: remove the workaround of b/30401180.
- VerticalGridView container = (VerticalGridView) getActivity()
- .findViewById(R.id.container_list);
- // Need to manually modify offset. Please refer DetailsFragment.setVerticalGridViewLayout.
- container.setItemAlignmentOffset(0);
- container.setWindowAlignmentOffset(
- getResources().getDimensionPixelSize(R.dimen.lb_details_rows_align_top));
- }
-
- private void setupAdapter() {
- DetailsOverviewRowPresenter rowPresenter = new DetailsOverviewRowPresenter(
- new DetailsContentPresenter(getActivity()));
- rowPresenter.setBackgroundColor(getResources().getColor(R.color.common_tv_background,
- null));
- rowPresenter.setSharedElementEnterTransition(getActivity(),
- DvrDetailsActivity.SHARED_ELEMENT_NAME);
- rowPresenter.setOnActionClickedListener(onCreateOnActionClickedListener());
- mRowsAdapter = new ArrayObjectAdapter(onCreatePresenterSelector(rowPresenter));
- setAdapter(mRowsAdapter);
- }
-
- /**
- * Returns details views' rows adapter.
- */
- protected ArrayObjectAdapter getRowsAdapter() {
- return mRowsAdapter;
- }
-
- /**
- * Sets details overview.
- */
- protected void setDetailsOverviewRow(DetailsContent detailsContent) {
- mDetailsOverview = new DetailsOverviewRow(detailsContent);
- mDetailsOverview.setActionsAdapter(onCreateActionsAdapter());
- mRowsAdapter.add(mDetailsOverview);
- onLoadLogoAndBackgroundImages(detailsContent);
- }
-
- /**
- * Creates and returns presenter selector will be used by rows adaptor.
- */
- protected PresenterSelector onCreatePresenterSelector(
- DetailsOverviewRowPresenter rowPresenter) {
- ClassPresenterSelector presenterSelector = new ClassPresenterSelector();
- presenterSelector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
- return presenterSelector;
- }
-
- /**
- * Does customized initialization of subclasses. Since {@link #onCreate(Bundle)} might finish
- * activity early when it cannot fetch valid recordings, subclasses' onCreate method should not
- * do anything after calling {@link #onCreate(Bundle)}. If there's something subclasses have to
- * do after the super class did onCreate, it should override this method and put the codes here.
- */
- protected void onCreateInternal() { }
-
- /**
- * Updates actions of details overview.
- */
- protected void updateActions() {
- mDetailsOverview.setActionsAdapter(onCreateActionsAdapter());
- }
-
- /**
- * Loads recording details according to the arguments the fragment got.
- *
- * @return false if cannot find valid recordings, else return true. If the return value
- * is false, the detail activity and fragment will be ended.
- */
- abstract boolean onLoadRecordingDetails(Bundle args);
-
- /**
- * Creates actions users can interact with and their adaptor for this fragment.
- */
- abstract SparseArrayObjectAdapter onCreateActionsAdapter();
-
- /**
- * Creates actions listeners to implement the behavior of the fragment after users click some
- * action buttons.
- */
- abstract OnActionClickedListener onCreateOnActionClickedListener();
-
- /**
- * Returns program title with episode number. If the program is null, returns channel name.
- */
- protected CharSequence getTitleFromProgram(BaseProgram program, Channel channel) {
- String titleWithEpisodeNumber = program.getTitleWithEpisodeNumber(getContext());
- SpannableString title = titleWithEpisodeNumber == null ? null
- : new SpannableString(titleWithEpisodeNumber);
- if (TextUtils.isEmpty(title)) {
- title = new SpannableString(channel != null ? channel.getDisplayName()
- : getContext().getResources().getString(
- R.string.no_program_information));
- } else {
- String programTitle = program.getTitle();
- title.setSpan(new TextAppearanceSpan(getContext(),
- R.style.text_appearance_card_view_episode_number), programTitle == null ? 0
- : programTitle.length(), title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- return title;
- }
-
- /**
- * Loads logo and background images for detail fragments.
- */
- protected void onLoadLogoAndBackgroundImages(DetailsContent detailsContent) {
- Drawable logoDrawable = null;
- Drawable backgroundDrawable = null;
- if (TextUtils.isEmpty(detailsContent.getLogoImageUri())) {
- logoDrawable = getContext().getResources()
- .getDrawable(R.drawable.dvr_default_poster, null);
- mDetailsOverview.setImageDrawable(logoDrawable);
- }
- if (TextUtils.isEmpty(detailsContent.getBackgroundImageUri())) {
- backgroundDrawable = getContext().getResources()
- .getDrawable(R.drawable.dvr_default_poster, null);
- mBackgroundHelper.setBackground(backgroundDrawable);
- }
- if (logoDrawable != null && backgroundDrawable != null) {
- return;
- }
- if (logoDrawable == null && backgroundDrawable == null
- && detailsContent.getLogoImageUri().equals(
- detailsContent.getBackgroundImageUri())) {
- ImageLoader.loadBitmap(getContext(), detailsContent.getLogoImageUri(),
- new MyImageLoaderCallback(this, LOAD_LOGO_IMAGE | LOAD_BACKGROUND_IMAGE,
- getContext()));
- return;
- }
- if (logoDrawable == null) {
- int imageWidth = getResources().getDimensionPixelSize(R.dimen.dvr_details_poster_width);
- int imageHeight = getResources()
- .getDimensionPixelSize(R.dimen.dvr_details_poster_height);
- ImageLoader.loadBitmap(getContext(), detailsContent.getLogoImageUri(),
- imageWidth, imageHeight,
- new MyImageLoaderCallback(this, LOAD_LOGO_IMAGE, getContext()));
- }
- if (backgroundDrawable == null) {
- ImageLoader.loadBitmap(getContext(), detailsContent.getBackgroundImageUri(),
- new MyImageLoaderCallback(this, LOAD_BACKGROUND_IMAGE, getContext()));
- }
- }
-
- protected void startPlayback(RecordedProgram recordedProgram, long seekTimeMs) {
- if (Utils.isInBundledPackageSet(recordedProgram.getPackageName()) &&
- !isDataUriAccessible(recordedProgram.getDataUri())) {
- // Since cleaning RecordedProgram from forgotten storage will take some time,
- // ignore playback until cleaning is finished.
- ToastUtils.show(getContext(),
- getContext().getResources().getString(R.string.dvr_toast_recording_deleted),
- Toast.LENGTH_SHORT);
- return;
- }
- ParentalControlSettings parental = TvApplication.getSingletons(getActivity())
- .getTvInputManagerHelper().getParentalControlSettings();
- if (!parental.isParentalControlsEnabled()) {
- launchPlaybackActivity(recordedProgram, seekTimeMs, false);
- return;
- }
- ChannelDataManager channelDataManager =
- TvApplication.getSingletons(getActivity()).getChannelDataManager();
- Channel channel = channelDataManager.getChannel(recordedProgram.getChannelId());
- if (channel != null && channel.isLocked()) {
- checkPinToPlay(recordedProgram, seekTimeMs);
- return;
- }
- String ratingString = recordedProgram.getContentRating();
- if (TextUtils.isEmpty(ratingString)) {
- launchPlaybackActivity(recordedProgram, seekTimeMs, false);
- return;
- }
- String[] ratingList = ratingString.split(",");
- TvContentRating[] programRatings = new TvContentRating[ratingList.length];
- for (int i = 0; i < ratingList.length; i++) {
- programRatings[i] = TvContentRating.unflattenFromString(ratingList[i]);
- }
- TvContentRating blockRatings = parental.getBlockedRating(programRatings);
- if (blockRatings != null) {
- checkPinToPlay(recordedProgram, seekTimeMs);
- } else {
- launchPlaybackActivity(recordedProgram, seekTimeMs, false);
- }
- }
-
- private boolean isDataUriAccessible(Uri dataUri) {
- if (dataUri == null || dataUri.getPath() == null) {
- return false;
- }
- try {
- File recordedProgramPath = new File(dataUri.getPath());
- if (recordedProgramPath.exists()) {
- return true;
- }
- } catch (SecurityException e) {
- }
- return false;
- }
-
- private void checkPinToPlay(RecordedProgram recordedProgram, long seekTimeMs) {
- new PinDialogFragment(PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_PROGRAM,
- new PinDialogFragment.ResultListener() {
- @Override
- public void done(boolean success) {
- if (success) {
- launchPlaybackActivity(recordedProgram, seekTimeMs, true);
- }
- }
- }).show(getActivity().getFragmentManager(), PinDialogFragment.DIALOG_TAG);
- }
-
- private void launchPlaybackActivity(RecordedProgram mRecordedProgram, long seekTimeMs,
- boolean pinChecked) {
- Intent intent = new Intent(getActivity(), DvrPlaybackActivity.class);
- intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, mRecordedProgram.getId());
- if (seekTimeMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
- intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_SEEK_TIME, seekTimeMs);
- }
- intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_PIN_CHECKED, pinChecked);
- getActivity().startActivity(intent);
- }
-
- private static class MyImageLoaderCallback extends
- ImageLoader.ImageLoaderCallback<DvrDetailsFragment> {
- private final Context mContext;
- private final int mLoadType;
-
- public MyImageLoaderCallback(DvrDetailsFragment fragment,
- int loadType, Context context) {
- super(fragment);
- mLoadType = loadType;
- mContext = context;
- }
-
- @Override
- public void onBitmapLoaded(DvrDetailsFragment fragment,
- @Nullable Bitmap bitmap) {
- Drawable drawable;
- int loadType = mLoadType;
- if (bitmap == null) {
- Resources res = mContext.getResources();
- drawable = res.getDrawable(R.drawable.dvr_default_poster, null);
- if ((loadType & LOAD_BACKGROUND_IMAGE) != 0 && !fragment.isDetached()) {
- loadType &= ~LOAD_BACKGROUND_IMAGE;
- fragment.mBackgroundHelper.setBackgroundColor(
- res.getColor(R.color.dvr_detail_default_background));
- fragment.mBackgroundHelper.setScrim(
- res.getColor(R.color.dvr_detail_default_background_scrim));
- }
- } else {
- drawable = new BitmapDrawable(mContext.getResources(), bitmap);
- }
- if (!fragment.isDetached()) {
- if ((loadType & LOAD_LOGO_IMAGE) != 0) {
- fragment.mDetailsOverview.setImageDrawable(drawable);
- }
- if ((loadType & LOAD_BACKGROUND_IMAGE) != 0) {
- fragment.mBackgroundHelper.setBackground(drawable);
- }
- }
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/DvrForgetStorageErrorFragment.java b/src/com/android/tv/dvr/ui/DvrForgetStorageErrorFragment.java
deleted file mode 100644
index 73ddcdd0..00000000
--- a/src/com/android/tv/dvr/ui/DvrForgetStorageErrorFragment.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
-import android.support.v17.leanback.widget.GuidedAction;
-import android.text.TextUtils;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrManager;
-
-import java.util.List;
-
-public class DvrForgetStorageErrorFragment extends DvrGuidedStepFragment {
- private static final int ACTION_CANCEL = 1;
- private static final int ACTION_FORGET_STORAGE = 2;
- private String mInputId;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- Bundle args = getArguments();
- if (args != null) {
- mInputId = args.getString(DvrHalfSizedDialogFragment.KEY_INPUT_ID);
- }
- SoftPreconditions.checkArgument(!TextUtils.isEmpty(mInputId));
- super.onCreate(savedInstanceState);
- }
-
- @NonNull
- @Override
- public Guidance onCreateGuidance(Bundle savedInstanceState) {
- String title = getResources().getString(R.string.dvr_error_forget_storage_title);
- String description = getResources().getString(
- R.string.dvr_error_forget_storage_description);
- return new Guidance(title, description, null, null);
- }
-
- @Override
- public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) {
- Activity activity = getActivity();
- actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_CANCEL)
- .title(getResources().getString(R.string.dvr_action_error_cancel))
- .build());
- actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_FORGET_STORAGE)
- .title(getResources().getString(R.string.dvr_action_error_forget_storage))
- .build());
- }
-
- @Override
- public void onGuidedActionClicked(GuidedAction action) {
- if (action.getId() != ACTION_FORGET_STORAGE) {
- dismissDialog();
- return;
- }
- DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
- dvrManager.forgetStorage(mInputId);
- Activity activity = getActivity();
- if (activity instanceof DvrDetailsActivity) {
- // Since we removed everything, just finish the activity.
- activity.finish();
- } else {
- dismissDialog();
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java b/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
index d26e6836..ab852e10 100644
--- a/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrGuidedStepFragment.java
@@ -16,24 +16,43 @@
package com.android.tv.dvr.ui;
+import android.app.Activity;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
-import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist;
import android.support.v17.leanback.widget.GuidedAction;
import android.support.v17.leanback.widget.VerticalGridView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import com.android.tv.ApplicationSingletons;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvApplication;
+import com.android.tv.dialog.HalfSizedDialogFragment.OnActionClickListener;
import com.android.tv.dialog.SafeDismissDialogFragment;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.ui.HalfSizedDialogFragment.OnActionClickListener;
+import com.android.tv.dvr.DvrStorageStatusManager;
+
+import java.util.List;
+
+public abstract class DvrGuidedStepFragment extends TrackedGuidedStepFragment {
+ /**
+ * Action ID for "recording/scheduling the program anyway".
+ */
+ public static final int ACTION_RECORD_ANYWAY = 1;
+ /**
+ * Action ID for "deleting existed recordings".
+ */
+ public static final int ACTION_DELETE_RECORDINGS = 2;
+ /**
+ * Action ID for "cancelling current recording request".
+ */
+ public static final int ACTION_CANCEL_RECORDING = 3;
+ public static final String UNKNOWN_DVR_ACTION = "Unknown DVR Action";
-public class DvrGuidedStepFragment extends GuidedStepFragment {
private DvrManager mDvrManager;
private OnActionClickListener mOnActionClickListener;
@@ -44,7 +63,8 @@ public class DvrGuidedStepFragment extends GuidedStepFragment {
@Override
public void onAttach(Context context) {
super.onAttach(context);
- mDvrManager = TvApplication.getSingletons(context).getDvrManager();
+ ApplicationSingletons singletons = TvApplication.getSingletons(context);
+ mDvrManager = singletons.getDvrManager();
}
@Override
@@ -64,13 +84,27 @@ public class DvrGuidedStepFragment extends GuidedStepFragment {
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
if (mOnActionClickListener != null) {
mOnActionClickListener.onActionClick(action.getId());
}
dismissDialog();
}
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_RECORD_ANYWAY) {
+ return "record-anyway";
+ } else if (actionId == ACTION_DELETE_RECORDINGS) {
+ return "delete-recordings";
+ } else if (actionId == ACTION_CANCEL_RECORDING) {
+ return "cancel-recording";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
+
protected void dismissDialog() {
if (getActivity() instanceof MainActivity) {
SafeDismissDialogFragment currentDialog =
@@ -86,4 +120,76 @@ public class DvrGuidedStepFragment extends GuidedStepFragment {
protected void setOnActionClickListener(OnActionClickListener listener) {
mOnActionClickListener = listener;
}
+
+ /**
+ * The inner guided step fragment for
+ * {@link com.android.tv.dvr.ui.DvrHalfSizedDialogFragment
+ * .DvrNoFreeSpaceErrorDialogFragment}.
+ */
+ public static class DvrNoFreeSpaceErrorFragment extends DvrGuidedStepFragment {
+ @Override
+ public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
+ return new GuidanceStylist.Guidance(getString(R.string.dvr_error_no_free_space_title),
+ getString(R.string.dvr_error_no_free_space_description), null, null);
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ Activity activity = getActivity();
+ actions.add(new GuidedAction.Builder(activity)
+ .id(ACTION_RECORD_ANYWAY)
+ .title(R.string.dvr_action_record_anyway)
+ .build());
+ actions.add(new GuidedAction.Builder(activity)
+ .id(ACTION_DELETE_RECORDINGS)
+ .title(R.string.dvr_action_delete_recordings)
+ .build());
+ actions.add(new GuidedAction.Builder(activity)
+ .id(ACTION_CANCEL_RECORDING)
+ .title(R.string.dvr_action_record_cancel)
+ .build());
+ }
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrNoFreeSpaceErrorFragment";
+ }
+ }
+
+ /**
+ * The inner guided step fragment for
+ * {@link com.android.tv.dvr.ui.DvrHalfSizedDialogFragment
+ * .DvrSmallSizedStorageErrorDialogFragment}.
+ */
+ public static class DvrSmallSizedStorageErrorFragment extends DvrGuidedStepFragment {
+ @Override
+ public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title = getResources().getString(
+ R.string.dvr_error_small_sized_storage_title);
+ String description = getResources().getString(
+ R.string.dvr_error_small_sized_storage_description,
+ DvrStorageStatusManager.MIN_STORAGE_SIZE_FOR_DVR_IN_BYTES / 1024
+ / 1024 / 1024);
+ return new GuidanceStylist.Guidance(title, description, null, null);
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ Activity activity = getActivity();
+ actions.add(new GuidedAction.Builder(activity)
+ .id(GuidedAction.ACTION_ID_OK)
+ .title(android.R.string.ok)
+ .build());
+ }
+
+ @Override
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
+ dismissDialog();
+ }
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrSmallSizedStorageErrorFragment";
+ }
+ }
} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java b/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
index 2b132db8..f8ef3850 100644
--- a/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrHalfSizedDialogFragment.java
@@ -29,6 +29,7 @@ import android.view.ViewGroup;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.dvr.DvrStorageStatusManager;
+import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrChannelWatchConflictFragment;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrProgramConflictFragment;
import com.android.tv.guide.ProgramGuide;
@@ -166,6 +167,17 @@ public class DvrHalfSizedDialogFragment extends HalfSizedDialogFragment {
}
/**
+ * A dialog fragment to show error message when there is no enough free space to record.
+ */
+ public static class DvrNoFreeSpaceErrorDialogFragment
+ extends DvrGuidedStepDialogFragment {
+ @Override
+ protected DvrGuidedStepFragment onCreateGuidedStepFragment() {
+ return new DvrGuidedStepFragment.DvrNoFreeSpaceErrorFragment();
+ }
+ }
+
+ /**
* A dialog fragment to show error message when the current storage is too small to
* support DVR
*/
@@ -173,32 +185,7 @@ public class DvrHalfSizedDialogFragment extends HalfSizedDialogFragment {
extends DvrGuidedStepDialogFragment {
@Override
protected DvrGuidedStepFragment onCreateGuidedStepFragment() {
- return new DvrGuidedStepFragment() {
- @Override
- public Guidance onCreateGuidance(Bundle savedInstanceState) {
- String title = getResources().getString(
- R.string.dvr_error_small_sized_storage_title);
- String description = getResources().getString(
- R.string.dvr_error_small_sized_storage_description,
- DvrStorageStatusManager.MIN_STORAGE_SIZE_FOR_DVR_IN_BYTES / 1024
- / 1024 / 1024);
- return new Guidance(title, description, null, null);
- }
-
- @Override
- public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- Activity activity = getActivity();
- actions.add(new GuidedAction.Builder(activity)
- .id(GuidedAction.ACTION_ID_OK)
- .title(android.R.string.ok)
- .build());
- }
-
- @Override
- public void onGuidedActionClicked(GuidedAction action) {
- dismissDialog();
- }
- };
+ return new DvrGuidedStepFragment.DvrSmallSizedStorageErrorFragment();
}
}
diff --git a/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java b/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
index 3b1dbfa0..182416b6 100644
--- a/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrInsufficientSpaceErrorFragment.java
@@ -17,6 +17,7 @@
package com.android.tv.dvr.ui;
import android.app.Activity;
+import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
@@ -24,19 +25,67 @@ import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.dvr.ui.browse.DvrBrowseActivity;
+import java.util.ArrayList;
import java.util.List;
public class DvrInsufficientSpaceErrorFragment extends DvrGuidedStepFragment {
- private static final int ACTION_DONE = 1;
- private static final int ACTION_OPEN_DVR = 2;
+ /**
+ * Key for the failed scheduled recordings information.
+ */
+ public static final String FAILED_SCHEDULED_RECORDING_INFOS =
+ "failed_scheduled_recording_infos";
+
+ private static final String TAG = "DvrInsufficientSpaceErrorFragment";
+
+ private static final int ACTION_VIEW_RECENT_RECORDINGS = 1;
+
+ private ArrayList<String> mFailedScheduledRecordingInfos;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ Bundle args = getArguments();
+ if (args != null) {
+ mFailedScheduledRecordingInfos =
+ args.getStringArrayList(FAILED_SCHEDULED_RECORDING_INFOS);
+ }
+ SoftPreconditions.checkState(
+ mFailedScheduledRecordingInfos != null && !mFailedScheduledRecordingInfos.isEmpty(),
+ TAG, "failed scheduled recording is null");
+ }
@Override
public Guidance onCreateGuidance(Bundle savedInstanceState) {
- String title = getResources().getString(R.string.dvr_error_insufficient_space_title);
- String description = getResources()
- .getString(R.string.dvr_error_insufficient_space_description);
+ String title;
+ String description;
+ int failedScheduledRecordingSize = mFailedScheduledRecordingInfos.size();
+ if (failedScheduledRecordingSize == 1) {
+ title = getString(
+ R.string.dvr_error_insufficient_space_title_one_recording,
+ mFailedScheduledRecordingInfos.get(0));
+ description = getString(
+ R.string.dvr_error_insufficient_space_description_one_recording,
+ mFailedScheduledRecordingInfos.get(0));
+ } else if (failedScheduledRecordingSize == 2) {
+ title = getString(
+ R.string.dvr_error_insufficient_space_title_two_recordings,
+ mFailedScheduledRecordingInfos.get(0), mFailedScheduledRecordingInfos.get(1));
+ description = getString(
+ R.string.dvr_error_insufficient_space_description_two_recordings,
+ mFailedScheduledRecordingInfos.get(0), mFailedScheduledRecordingInfos.get(1));
+ } else {
+ title = getString(
+ R.string.dvr_error_insufficient_space_title_three_or_more_recordings,
+ mFailedScheduledRecordingInfos.get(0), mFailedScheduledRecordingInfos.get(1),
+ mFailedScheduledRecordingInfos.get(2));
+ description = getString(
+ R.string.dvr_error_insufficient_space_description_three_or_more_recordings,
+ mFailedScheduledRecordingInfos.get(0), mFailedScheduledRecordingInfos.get(1),
+ mFailedScheduledRecordingInfos.get(2));
+ }
return new Guidance(title, description, null, null);
}
@@ -44,28 +93,38 @@ public class DvrInsufficientSpaceErrorFragment extends DvrGuidedStepFragment {
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
Activity activity = getActivity();
actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_DONE)
- .title(getResources().getString(R.string.dvr_action_error_done))
+ .clickAction(GuidedAction.ACTION_ID_OK)
.build());
- DvrDataManager dvrDataManager = TvApplication.getSingletons(getContext())
- .getDvrDataManager();
- if (!(dvrDataManager.getRecordedPrograms().isEmpty()
- && dvrDataManager.getStartedRecordings().isEmpty()
- && dvrDataManager.getNonStartedScheduledRecordings().isEmpty()
- && dvrDataManager.getSeriesRecordings().isEmpty())) {
- actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_OPEN_DVR)
- .title(getResources().getString(R.string.dvr_action_error_open_dvr))
- .build());
+ if (TvApplication.getSingletons(getContext()).getDvrManager().hasValidItems()) {
+ actions.add(new GuidedAction.Builder(activity)
+ .id(ACTION_VIEW_RECENT_RECORDINGS)
+ .title(getResources().getString(
+ R.string.dvr_error_insufficient_space_action_view_recent_recordings))
+ .build());
}
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
- if (action.getId() == ACTION_OPEN_DVR) {
- Intent intent = new Intent(getActivity(), DvrActivity.class);
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
+ if (action.getId() == ACTION_VIEW_RECENT_RECORDINGS) {
+ Intent intent = new Intent(getActivity(), DvrBrowseActivity.class);
getActivity().startActivity(intent);
}
dismissDialog();
}
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrInsufficientSpaceErrorFragment";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_VIEW_RECENT_RECORDINGS) {
+ return "view-recent";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
}
diff --git a/src/com/android/tv/dvr/ui/DvrItemPresenter.java b/src/com/android/tv/dvr/ui/DvrItemPresenter.java
deleted file mode 100644
index 339e5d2f..00000000
--- a/src/com/android/tv/dvr/ui/DvrItemPresenter.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.support.annotation.CallSuper;
-import android.support.v17.leanback.widget.Presenter;
-import android.view.View;
-import android.view.View.OnClickListener;
-
-import com.android.tv.dvr.DvrUiHelper;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * An abstract class to present DVR items in {@link RecordingCardView}, which is mainly used in
- * {@link DvrBrowseFragment}. DVR items might include: {@link ScheduledRecording},
- * {@link RecordedProgram}, and {@link SeriesRecording}.
- */
-public abstract class DvrItemPresenter extends Presenter {
- private final Set<ViewHolder> mBoundViewHolders = new HashSet<>();
- private final OnClickListener mOnClickListener = onCreateOnClickListener();
-
- @Override
- @CallSuper
- public void onBindViewHolder(ViewHolder viewHolder, Object o) {
- viewHolder.view.setTag(o);
- viewHolder.view.setOnClickListener(mOnClickListener);
- mBoundViewHolders.add(viewHolder);
- }
-
- @Override
- @CallSuper
- public void onUnbindViewHolder(ViewHolder viewHolder) {
- mBoundViewHolders.remove(viewHolder);
- }
-
- /**
- * Unbinds all bound view holders.
- */
- public void unbindAllViewHolders() {
- // When browse fragments are destroyed, RecyclerView would not call presenters'
- // onUnbindViewHolder(). We should handle it by ourselves to prevent resources leaks.
- for (ViewHolder viewHolder : new HashSet<>(mBoundViewHolders)) {
- onUnbindViewHolder(viewHolder);
- }
- }
-
- /**
- * Creates {@link OnClickListener} for DVR library's card views.
- */
- protected OnClickListener onCreateOnClickListener() {
- return new OnClickListener() {
- @Override
- public void onClick(View view) {
- if (view instanceof RecordingCardView) {
- RecordingCardView v = (RecordingCardView) view;
- DvrUiHelper.startDetailsActivity((Activity) v.getContext(),
- v.getTag(), v.getImageView(), false);
- }
- }
- };
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java b/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
index 2e2c2849..e726995f 100644
--- a/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrMissingStorageErrorFragment.java
@@ -17,29 +17,27 @@
package com.android.tv.dvr.ui;
import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
import android.os.Bundle;
-import android.support.v17.leanback.app.GuidedStepFragment;
+import android.provider.Settings;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
import android.support.v17.leanback.widget.GuidedAction;
-import android.text.TextUtils;
+import android.util.Log;
import com.android.tv.R;
-import com.android.tv.common.SoftPreconditions;
+import com.android.tv.dvr.ui.browse.DvrDetailsActivity;
import java.util.List;
public class DvrMissingStorageErrorFragment extends DvrGuidedStepFragment {
- private static final int ACTION_CANCEL = 1;
- private static final int ACTION_FORGET_STORAGE = 2;
- private String mInputId;
+ private static final String TAG = "DvrMissingStorageError";
+
+ private static final int ACTION_OK = 1;
+ private static final int ACTION_OPEN_STORAGE_SETTINGS = 2;
@Override
public void onCreate(Bundle savedInstanceState) {
- Bundle args = getArguments();
- if (args != null) {
- mInputId = args.getString(DvrHalfSizedDialogFragment.KEY_INPUT_ID);
- }
- SoftPreconditions.checkArgument(!TextUtils.isEmpty(mInputId));
super.onCreate(savedInstanceState);
}
@@ -55,25 +53,46 @@ public class DvrMissingStorageErrorFragment extends DvrGuidedStepFragment {
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
Activity activity = getActivity();
actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_CANCEL)
- .title(getResources().getString(R.string.dvr_action_error_cancel))
+ .id(ACTION_OK)
+ .title(android.R.string.ok)
.build());
actions.add(new GuidedAction.Builder(activity)
- .id(ACTION_FORGET_STORAGE)
- .title(getResources().getString(R.string.dvr_action_error_forget_storage))
+ .id(ACTION_OPEN_STORAGE_SETTINGS)
+ .title(getResources().getString(R.string.dvr_action_error_storage_settings))
.build());
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
- if (action.getId() == ACTION_FORGET_STORAGE) {
- DvrForgetStorageErrorFragment fragment = new DvrForgetStorageErrorFragment();
- Bundle args = new Bundle();
- args.putString(DvrHalfSizedDialogFragment.KEY_INPUT_ID, mInputId);
- fragment.setArguments(args);
- GuidedStepFragment.add(getFragmentManager(), fragment, R.id.halfsized_dialog_host);
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
+ Activity activity = getActivity();
+ if (activity instanceof DvrDetailsActivity) {
+ activity.finish();
+ } else {
+ dismissDialog();
+ }
+ if (action.getId() != ACTION_OPEN_STORAGE_SETTINGS) {
return;
}
- dismissDialog();
+ final Intent intent = new Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
+ try {
+ getContext().startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "Can't start internal storage settings activity", e);
+ }
+ }
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrMissingStorageErrorFragment";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_OPEN_STORAGE_SETTINGS) {
+ return "open-storage-settings";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/dvr/ui/DvrPlaybackCardPresenter.java b/src/com/android/tv/dvr/ui/DvrPlaybackCardPresenter.java
deleted file mode 100644
index 8c4c856c..00000000
--- a/src/com/android/tv/dvr/ui/DvrPlaybackCardPresenter.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2016 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.tv.dvr.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-
-import com.android.tv.R;
-import com.android.tv.dvr.RecordedProgram;
-import com.android.tv.dvr.DvrPlaybackActivity;
-import com.android.tv.util.Utils;
-
-/**
- * This class is used to generate Views and bind Objects for related recordings in DVR playback.
- */
-public class DvrPlaybackCardPresenter extends RecordedProgramPresenter {
- private static final String TAG = "DvrPlaybackCardPresenter";
- private static final boolean DEBUG = false;
-
- private final int mRelatedRecordingCardWidth;
- private final int mRelatedRecordingCardHeight;
-
- DvrPlaybackCardPresenter(Context context) {
- super(context);
- mRelatedRecordingCardWidth =
- context.getResources().getDimensionPixelSize(R.dimen.dvr_related_recordings_width);
- mRelatedRecordingCardHeight =
- context.getResources().getDimensionPixelSize(R.dimen.dvr_related_recordings_height);
- }
-
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent) {
- Resources res = parent.getResources();
- RecordingCardView view = new RecordingCardView(
- getContext(), mRelatedRecordingCardWidth, mRelatedRecordingCardHeight);
- return new ViewHolder(view);
- }
-
- @Override
- protected OnClickListener onCreateOnClickListener() {
- return new OnClickListener() {
- @Override
- public void onClick(View v) {
- long programId = ((RecordedProgram) v.getTag()).getId();
- if (DEBUG) Log.d(TAG, "Play Related Recording:" + programId);
- Intent intent = new Intent(getContext(), DvrPlaybackActivity.class);
- intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, programId);
- getContext().startActivity(intent);
- }
- };
- }
-
- @Override
- protected String getDescription(RecordedProgram program) {
- String description = program.getDescription();
- if (TextUtils.isEmpty(description)) {
- description =
- getContext().getResources().getString(R.string.dvr_msg_no_program_description);
- }
- return description;
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrPlaybackControlHelper.java b/src/com/android/tv/dvr/ui/DvrPlaybackControlHelper.java
deleted file mode 100644
index 0bc4ecb1..00000000
--- a/src/com/android/tv/dvr/ui/DvrPlaybackControlHelper.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.graphics.drawable.Drawable;
-import android.media.MediaMetadata;
-import android.media.session.MediaController;
-import android.media.session.MediaController.TransportControls;
-import android.media.session.PlaybackState;
-import android.support.v17.leanback.app.PlaybackControlGlue;
-import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-
-import com.android.tv.R;
-import com.android.tv.util.TimeShiftUtils;
-
-/**
- * A helper class to assist {@link DvrPlaybackOverlayFragment} to manage its controls row and
- * send command to the media controller. It also helps to update playback states displayed in the
- * fragment according to information the media session provides.
- */
-public class DvrPlaybackControlHelper extends PlaybackControlGlue {
- private static final String TAG = "DvrPlaybackControlHelper";
- private static final boolean DEBUG = false;
-
- /**
- * Indicates the ID of the media under playback is unknown.
- */
- public static int UNKNOWN_MEDIA_ID = -1;
-
- private int mPlaybackState = PlaybackState.STATE_NONE;
- private int mPlaybackSpeedLevel;
- private int mPlaybackSpeedId;
- private boolean mReadyToControl;
-
- private final MediaController mMediaController;
- private final MediaController.Callback mMediaControllerCallback = new MediaControllerCallback();
- private final TransportControls mTransportControls;
- private final int mExtraPaddingTopForNoDescription;
-
- public DvrPlaybackControlHelper(Activity activity, DvrPlaybackOverlayFragment overlayFragment) {
- super(activity, overlayFragment, new int[TimeShiftUtils.MAX_SPEED_LEVEL + 1]);
- mMediaController = activity.getMediaController();
- mMediaController.registerCallback(mMediaControllerCallback);
- mTransportControls = mMediaController.getTransportControls();
- mExtraPaddingTopForNoDescription = activity.getResources()
- .getDimensionPixelOffset(R.dimen.dvr_playback_controls_extra_padding_top);
- }
-
- @Override
- public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
- PlaybackControlsRow controlsRow = new PlaybackControlsRow(this);
- setControlsRow(controlsRow);
- AbstractDetailsDescriptionPresenter detailsPresenter =
- new AbstractDetailsDescriptionPresenter() {
- @Override
- protected void onBindDescription(
- AbstractDetailsDescriptionPresenter.ViewHolder viewHolder, Object object) {
- PlaybackControlGlue glue = (PlaybackControlGlue) object;
- if (glue.hasValidMedia()) {
- viewHolder.getTitle().setText(glue.getMediaTitle());
- viewHolder.getSubtitle().setText(glue.getMediaSubtitle());
- } else {
- viewHolder.getTitle().setText("");
- viewHolder.getSubtitle().setText("");
- }
- if (TextUtils.isEmpty(viewHolder.getSubtitle().getText())) {
- viewHolder.view.setPadding(viewHolder.view.getPaddingLeft(),
- mExtraPaddingTopForNoDescription,
- viewHolder.view.getPaddingRight(), viewHolder.view.getPaddingBottom());
- }
- }
- };
- PlaybackControlsRowPresenter presenter =
- new PlaybackControlsRowPresenter(detailsPresenter) {
- @Override
- protected void onBindRowViewHolder(RowPresenter.ViewHolder vh, Object item) {
- super.onBindRowViewHolder(vh, item);
- vh.setOnKeyListener(DvrPlaybackControlHelper.this);
- }
-
- @Override
- protected void onUnbindRowViewHolder(RowPresenter.ViewHolder vh) {
- super.onUnbindRowViewHolder(vh);
- vh.setOnKeyListener(null);
- }
- };
- presenter.setProgressColor(getContext().getResources()
- .getColor(R.color.play_controls_progress_bar_watched));
- presenter.setBackgroundColor(getContext().getResources()
- .getColor(R.color.play_controls_body_background_enabled));
- presenter.setOnActionClickedListener(new OnActionClickedListener() {
- @Override
- public void onActionClicked(Action action) {
- if (mReadyToControl) {
- DvrPlaybackControlHelper.super.onActionClicked(action);
- }
- }
- });
- return presenter;
- }
-
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- if (mReadyToControl) {
- if (keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE && event.getAction() == KeyEvent.ACTION_DOWN
- && (mPlaybackState == PlaybackState.STATE_FAST_FORWARDING
- || mPlaybackState == PlaybackState.STATE_REWINDING)) {
- // Workaround of b/31489271. Clicks play/pause button first to reset play controls
- // to "play" state. Then we can pass MEDIA_PAUSE to let playback be paused.
- onActionClicked(getControlsRow().getActionForKeyCode(keyCode));
- }
- return super.onKey(v, keyCode, event);
- }
- return false;
- }
-
- @Override
- public boolean hasValidMedia() {
- PlaybackState playbackState = mMediaController.getPlaybackState();
- return playbackState != null;
- }
-
- @Override
- public boolean isMediaPlaying() {
- PlaybackState playbackState = mMediaController.getPlaybackState();
- if (playbackState == null) {
- return false;
- }
- int state = playbackState.getState();
- return state != PlaybackState.STATE_NONE && state != PlaybackState.STATE_CONNECTING
- && state != PlaybackState.STATE_PAUSED;
- }
-
- /**
- * Returns the ID of the media under playback.
- */
- public long getMediaId() {
- MediaMetadata mediaMetadata = mMediaController.getMetadata();
- return mediaMetadata == null ? UNKNOWN_MEDIA_ID
- : mediaMetadata.getLong(MediaMetadata.METADATA_KEY_MEDIA_ID);
- }
-
- @Override
- public CharSequence getMediaTitle() {
- MediaMetadata mediaMetadata = mMediaController.getMetadata();
- return mediaMetadata == null ? ""
- : mediaMetadata.getString(MediaMetadata.METADATA_KEY_TITLE);
- }
-
- @Override
- public CharSequence getMediaSubtitle() {
- MediaMetadata mediaMetadata = mMediaController.getMetadata();
- return mediaMetadata == null ? ""
- : mediaMetadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE);
- }
-
- @Override
- public int getMediaDuration() {
- MediaMetadata mediaMetadata = mMediaController.getMetadata();
- return mediaMetadata == null ? 0
- : (int) mediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
- }
-
- @Override
- public Drawable getMediaArt() {
- // Do not show the poster art on control row.
- return null;
- }
-
- @Override
- public long getSupportedActions() {
- return ACTION_PLAY_PAUSE | ACTION_FAST_FORWARD | ACTION_REWIND;
- }
-
- @Override
- public int getCurrentSpeedId() {
- return mPlaybackSpeedId;
- }
-
- @Override
- public int getCurrentPosition() {
- PlaybackState playbackState = mMediaController.getPlaybackState();
- if (playbackState == null) {
- return 0;
- }
- return (int) playbackState.getPosition();
- }
-
- /**
- * Unregister media controller's callback.
- */
- public void unregisterCallback() {
- mMediaController.unregisterCallback(mMediaControllerCallback);
- }
-
- @Override
- protected void startPlayback(int speedId) {
- if (getCurrentSpeedId() == speedId) {
- return;
- }
- if (speedId == PLAYBACK_SPEED_NORMAL) {
- mTransportControls.play();
- } else if (speedId <= -PLAYBACK_SPEED_FAST_L0) {
- mTransportControls.rewind();
- } else if (speedId >= PLAYBACK_SPEED_FAST_L0){
- mTransportControls.fastForward();
- }
- }
-
- @Override
- protected void pausePlayback() {
- mTransportControls.pause();
- }
-
- @Override
- protected void skipToNext() {
- // Do nothing.
- }
-
- @Override
- protected void skipToPrevious() {
- // Do nothing.
- }
-
- @Override
- protected void onRowChanged(PlaybackControlsRow row) {
- // Do nothing.
- }
-
- private void onStateChanged(int state, long positionMs, int speedLevel) {
- if (DEBUG) Log.d(TAG, "onStateChanged");
- getControlsRow().setCurrentTime((int) positionMs);
- if (state == mPlaybackState && mPlaybackSpeedLevel == speedLevel) {
- // Only position is changed, no need to update controls row
- return;
- }
- // NOTICE: The below two variables should only be used in this method.
- // The only usage of them is to confirm if the state is changed or not.
- mPlaybackState = state;
- mPlaybackSpeedLevel = speedLevel;
- switch (state) {
- case PlaybackState.STATE_PLAYING:
- mPlaybackSpeedId = PLAYBACK_SPEED_NORMAL;
- setFadingEnabled(true);
- mReadyToControl = true;
- break;
- case PlaybackState.STATE_PAUSED:
- mPlaybackSpeedId = PLAYBACK_SPEED_PAUSED;
- setFadingEnabled(true);
- mReadyToControl = true;
- break;
- case PlaybackState.STATE_FAST_FORWARDING:
- mPlaybackSpeedId = PLAYBACK_SPEED_FAST_L0 + speedLevel;
- setFadingEnabled(false);
- mReadyToControl = true;
- break;
- case PlaybackState.STATE_REWINDING:
- mPlaybackSpeedId = -PLAYBACK_SPEED_FAST_L0 - speedLevel;
- setFadingEnabled(false);
- mReadyToControl = true;
- break;
- case PlaybackState.STATE_CONNECTING:
- setFadingEnabled(false);
- mReadyToControl = false;
- break;
- case PlaybackState.STATE_NONE:
- mReadyToControl = false;
- break;
- default:
- setFadingEnabled(true);
- break;
- }
- onStateChanged();
- }
-
- private class MediaControllerCallback extends MediaController.Callback {
- @Override
- public void onPlaybackStateChanged(PlaybackState state) {
- if (DEBUG) Log.d(TAG, "Playback state changed: " + state.getState());
- onStateChanged(state.getState(), state.getPosition(), (int) state.getPlaybackSpeed());
- }
-
- @Override
- public void onMetadataChanged(MediaMetadata metadata) {
- DvrPlaybackControlHelper.this.onMetadataChanged();
- ((DvrPlaybackOverlayFragment) getFragment()).onMediaControllerUpdated();
- }
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrPlaybackOverlayFragment.java b/src/com/android/tv/dvr/ui/DvrPlaybackOverlayFragment.java
deleted file mode 100644
index 51ec93b8..00000000
--- a/src/com/android/tv/dvr/ui/DvrPlaybackOverlayFragment.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Point;
-import android.hardware.display.DisplayManager;
-import android.media.tv.TvContentRating;
-import android.os.Bundle;
-import android.media.session.PlaybackState;
-import android.media.tv.TvInputManager;
-import android.media.tv.TvView;
-import android.support.v17.leanback.app.PlaybackOverlayFragment;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.SinglePresenterSelector;
-import android.view.Display;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Toast;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.BaseProgram;
-import com.android.tv.dvr.RecordedProgram;
-import com.android.tv.dialog.PinDialogFragment;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrPlayer;
-import com.android.tv.dvr.DvrPlaybackMediaSessionHelper;
-import com.android.tv.parental.ContentRatingsManager;
-import com.android.tv.util.Utils;
-
-public class DvrPlaybackOverlayFragment extends PlaybackOverlayFragment {
- // TODO: Handles audio focus. Deals with block and ratings.
- private static final String TAG = "DvrPlaybackOverlayFragment";
- private static final boolean DEBUG = false;
-
- private static final String MEDIA_SESSION_TAG = "com.android.tv.dvr.mediasession";
- private static final float DISPLAY_ASPECT_RATIO_EPSILON = 0.01f;
-
- // mProgram is only used to store program from intent. Don't use it elsewhere.
- private RecordedProgram mProgram;
- private DvrPlaybackMediaSessionHelper mMediaSessionHelper;
- private DvrPlaybackControlHelper mPlaybackControlHelper;
- private ArrayObjectAdapter mRowsAdapter;
- private SortedArrayAdapter<BaseProgram> mRelatedRecordingsRowAdapter;
- private DvrPlaybackCardPresenter mRelatedRecordingCardPresenter;
- private DvrDataManager mDvrDataManager;
- private ContentRatingsManager mContentRatingsManager;
- private TvView mTvView;
- private View mBlockScreenView;
- private ListRow mRelatedRecordingsRow;
- private int mExtraPaddingNoRelatedRow;
- private int mWindowWidth;
- private int mWindowHeight;
- private float mAppliedAspectRatio;
- private float mWindowAspectRatio;
- private boolean mPinChecked;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- if (DEBUG) Log.d(TAG, "onCreate");
- super.onCreate(savedInstanceState);
- mExtraPaddingNoRelatedRow = getActivity().getResources()
- .getDimensionPixelOffset(R.dimen.dvr_playback_fragment_extra_padding_top);
- mDvrDataManager = TvApplication.getSingletons(getActivity()).getDvrDataManager();
- mContentRatingsManager = TvApplication.getSingletons(getContext())
- .getTvInputManagerHelper().getContentRatingsManager();
- mProgram = getProgramFromIntent(getActivity().getIntent());
- if (mProgram == null) {
- Toast.makeText(getActivity(), getString(R.string.dvr_program_not_found),
- Toast.LENGTH_SHORT).show();
- getActivity().finish();
- return;
- }
- Point size = new Point();
- ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE))
- .getDisplay(Display.DEFAULT_DISPLAY).getSize(size);
- mWindowWidth = size.x;
- mWindowHeight = size.y;
- mWindowAspectRatio = mAppliedAspectRatio = (float) mWindowWidth / mWindowHeight;
- setBackgroundType(PlaybackOverlayFragment.BG_LIGHT);
- setFadingEnabled(true);
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- mTvView = (TvView) getActivity().findViewById(R.id.dvr_tv_view);
- mBlockScreenView = getActivity().findViewById(R.id.block_screen);
- mMediaSessionHelper = new DvrPlaybackMediaSessionHelper(
- getActivity(), MEDIA_SESSION_TAG, new DvrPlayer(mTvView), this);
- mPlaybackControlHelper = new DvrPlaybackControlHelper(getActivity(), this);
- setUpRows();
- preparePlayback(getActivity().getIntent());
- DvrPlayer dvrPlayer = mMediaSessionHelper.getDvrPlayer();
- dvrPlayer.setAspectRatioChangedListener(new DvrPlayer.AspectRatioChangedListener() {
- @Override
- public void onAspectRatioChanged(float videoAspectRatio) {
- updateAspectRatio(videoAspectRatio);
- }
- });
- mPinChecked = getActivity().getIntent()
- .getBooleanExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_PIN_CHECKED, false);
- dvrPlayer.setContentBlockedListener(new DvrPlayer.ContentBlockedListener() {
- @Override
- public void onContentBlocked(TvContentRating rating) {
- if (mPinChecked) {
- mTvView.unblockContent(rating);
- return;
- }
- mBlockScreenView.setVisibility(View.VISIBLE);
- getActivity().getMediaController().getTransportControls().pause();
- new PinDialogFragment(PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_DVR,
- new PinDialogFragment.ResultListener() {
- @Override
- public void done(boolean success) {
- if (success) {
- mPinChecked = true;
- mTvView.unblockContent(rating);
- mBlockScreenView.setVisibility(View.GONE);
- getActivity().getMediaController()
- .getTransportControls().play();
- }
- }
- }, mContentRatingsManager.getDisplayNameForRating(rating))
- .show(getActivity().getFragmentManager(), PinDialogFragment.DIALOG_TAG);
- }
- });
- }
-
- @Override
- public void onPause() {
- if (DEBUG) Log.d(TAG, "onPause");
- super.onPause();
- if (mMediaSessionHelper.getPlaybackState() == PlaybackState.STATE_FAST_FORWARDING
- || mMediaSessionHelper.getPlaybackState() == PlaybackState.STATE_REWINDING) {
- getActivity().getMediaController().getTransportControls().pause();
- }
- if (mMediaSessionHelper.getPlaybackState() == PlaybackState.STATE_NONE) {
- getActivity().requestVisibleBehind(false);
- } else {
- getActivity().requestVisibleBehind(true);
- }
- }
-
- @Override
- public void onDestroy() {
- if (DEBUG) Log.d(TAG, "onDestroy");
- mPlaybackControlHelper.unregisterCallback();
- mMediaSessionHelper.release();
- mRelatedRecordingCardPresenter.unbindAllViewHolders();
- super.onDestroy();
- }
-
- /**
- * Passes the intent to the fragment.
- */
- public void onNewIntent(Intent intent) {
- mProgram = getProgramFromIntent(intent);
- if (mProgram == null) {
- Toast.makeText(getActivity(), getString(R.string.dvr_program_not_found),
- Toast.LENGTH_SHORT).show();
- // Continue playing the original program
- return;
- }
- preparePlayback(intent);
- }
-
- /**
- * Should be called when windows' size is changed in order to notify DVR player
- * to update it's view width/height and position.
- */
- public void onWindowSizeChanged(final int windowWidth, final int windowHeight) {
- mWindowWidth = windowWidth;
- mWindowHeight = windowHeight;
- mWindowAspectRatio = (float) mWindowWidth / mWindowHeight;
- updateAspectRatio(mAppliedAspectRatio);
- }
-
- public RecordedProgram getNextEpisode(RecordedProgram program) {
- int position = mRelatedRecordingsRowAdapter.findInsertPosition(program);
- if (position == mRelatedRecordingsRowAdapter.size()) {
- return null;
- } else {
- return (RecordedProgram) mRelatedRecordingsRowAdapter.get(position);
- }
- }
-
- void onMediaControllerUpdated() {
- mRowsAdapter.notifyArrayItemRangeChanged(0, 1);
- }
-
- private void updateAspectRatio(float videoAspectRatio) {
- if (Math.abs(mAppliedAspectRatio - videoAspectRatio) < DISPLAY_ASPECT_RATIO_EPSILON) {
- // No need to change
- return;
- }
- if (videoAspectRatio < mWindowAspectRatio) {
- int newPadding = (mWindowWidth - Math.round(mWindowHeight * videoAspectRatio)) / 2;
- ((ViewGroup) mTvView.getParent()).setPadding(newPadding, 0, newPadding, 0);
- } else {
- int newPadding = (mWindowHeight - Math.round(mWindowWidth / videoAspectRatio)) / 2;
- ((ViewGroup) mTvView.getParent()).setPadding(0, newPadding, 0, newPadding);
- }
- mAppliedAspectRatio = videoAspectRatio;
- }
-
- private void preparePlayback(Intent intent) {
- mMediaSessionHelper.setupPlayback(mProgram, getSeekTimeFromIntent(intent));
- getActivity().getMediaController().getTransportControls().prepare();
- updateRelatedRecordingsRow();
- }
-
- private void updateRelatedRecordingsRow() {
- boolean wasEmpty = (mRelatedRecordingsRowAdapter.size() == 0);
- mRelatedRecordingsRowAdapter.clear();
- long programId = mProgram.getId();
- String seriesId = mProgram.getSeriesId();
- if (!TextUtils.isEmpty(seriesId)) {
- if (DEBUG) Log.d(TAG, "Update related recordings with:" + seriesId);
- for (RecordedProgram program : mDvrDataManager.getRecordedPrograms()) {
- if (seriesId.equals(program.getSeriesId()) && programId != program.getId()) {
- mRelatedRecordingsRowAdapter.add(program);
- }
- }
- }
- View view = getView();
- if (mRelatedRecordingsRowAdapter.size() == 0) {
- mRowsAdapter.remove(mRelatedRecordingsRow);
- view.setPadding(view.getPaddingLeft(), mExtraPaddingNoRelatedRow,
- view.getPaddingRight(), view.getPaddingBottom());
- } else if (wasEmpty){
- mRowsAdapter.add(mRelatedRecordingsRow);
- view.setPadding(view.getPaddingLeft(), 0,
- view.getPaddingRight(), view.getPaddingBottom());
- }
- }
-
- private void setUpRows() {
- PlaybackControlsRowPresenter controlsRowPresenter =
- mPlaybackControlHelper.createControlsRowAndPresenter();
-
- ClassPresenterSelector selector = new ClassPresenterSelector();
- selector.addClassPresenter(PlaybackControlsRow.class, controlsRowPresenter);
- selector.addClassPresenter(ListRow.class, new ListRowPresenter());
-
- mRowsAdapter = new ArrayObjectAdapter(selector);
- mRowsAdapter.add(mPlaybackControlHelper.getControlsRow());
- mRelatedRecordingsRow = getRelatedRecordingsRow();
- setAdapter(mRowsAdapter);
- }
-
- private ListRow getRelatedRecordingsRow() {
- mRelatedRecordingCardPresenter = new DvrPlaybackCardPresenter(getActivity());
- mRelatedRecordingsRowAdapter = new RelatedRecordingsAdapter(mRelatedRecordingCardPresenter);
- HeaderItem header = new HeaderItem(0,
- getActivity().getString(R.string.dvr_playback_related_recordings));
- return new ListRow(header, mRelatedRecordingsRowAdapter);
- }
-
- private RecordedProgram getProgramFromIntent(Intent intent) {
- long programId = intent.getLongExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, -1);
- return mDvrDataManager.getRecordedProgram(programId);
- }
-
- private long getSeekTimeFromIntent(Intent intent) {
- return intent.getLongExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_SEEK_TIME,
- TvInputManager.TIME_SHIFT_INVALID_TIME);
- }
-
- private class RelatedRecordingsAdapter extends SortedArrayAdapter<BaseProgram> {
- RelatedRecordingsAdapter(DvrPlaybackCardPresenter presenter) {
- super(new SinglePresenterSelector(presenter), BaseProgram.EPISODE_COMPARATOR);
- }
-
- @Override
- long getId(BaseProgram item) {
- return item.getId();
- }
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java b/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java
new file mode 100644
index 00000000..e4cb7243
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/DvrPrioritySettingsFragment.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui;
+
+import android.app.FragmentManager;
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.DvrScheduleManager;
+import com.android.tv.dvr.data.SeriesRecording;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Fragment for DVR series recording settings. */
+public class DvrPrioritySettingsFragment extends TrackedGuidedStepFragment {
+ /**
+ * Name of series recording id starting the fragment.
+ * Type: Long
+ */
+ public static final String COME_FROM_SERIES_RECORDING_ID = "series_recording_id";
+
+ private static final int ONE_TIME_RECORDING_ID = 0;
+ // button action's IDs are negative.
+ private static final long ACTION_ID_SAVE = -100L;
+
+ private final List<SeriesRecording> mSeriesRecordings = new ArrayList<>();
+
+ private SeriesRecording mSelectedRecording;
+ private SeriesRecording mComeFromSeriesRecording;
+ private float mSelectedActionElevation;
+ private int mActionColor;
+ private int mSelectedActionColor;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mSeriesRecordings.clear();
+ mSeriesRecordings.add(new SeriesRecording.Builder()
+ .setTitle(getString(R.string.dvr_priority_action_one_time_recording))
+ .setPriority(Long.MAX_VALUE)
+ .setId(ONE_TIME_RECORDING_ID)
+ .build());
+ DvrDataManager dvrDataManager = TvApplication.getSingletons(context).getDvrDataManager();
+ long comeFromSeriesRecordingId =
+ getArguments().getLong(COME_FROM_SERIES_RECORDING_ID, -1);
+ for (SeriesRecording series : dvrDataManager.getSeriesRecordings()) {
+ if (series.getState() == SeriesRecording.STATE_SERIES_NORMAL
+ || series.getId() == comeFromSeriesRecordingId) {
+ mSeriesRecordings.add(series);
+ }
+ }
+ mSeriesRecordings.sort(SeriesRecording.PRIORITY_COMPARATOR);
+ mComeFromSeriesRecording = dvrDataManager.getSeriesRecording(comeFromSeriesRecordingId);
+ mSelectedActionElevation = getResources().getDimension(R.dimen.card_elevation_normal);
+ mActionColor = getResources().getColor(R.color.dvr_guided_step_action_text_color, null);
+ mSelectedActionColor =
+ getResources().getColor(R.color.dvr_guided_step_action_text_color_selected, null);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ setSelectedActionPosition(mComeFromSeriesRecording == null ? 1
+ : mSeriesRecordings.indexOf(mComeFromSeriesRecording));
+ }
+
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String breadcrumb = mComeFromSeriesRecording == null ? null
+ : mComeFromSeriesRecording.getTitle();
+ return new Guidance(getString(R.string.dvr_priority_title),
+ getString(R.string.dvr_priority_description), breadcrumb, null);
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ int position = 0;
+ for (SeriesRecording seriesRecording : mSeriesRecordings) {
+ actions.add(new GuidedAction.Builder(getActivity())
+ .id(position++)
+ .title(seriesRecording.getTitle())
+ .build());
+ }
+ }
+
+ @Override
+ public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder(getActivity())
+ .id(ACTION_ID_SAVE)
+ .title(getString(R.string.dvr_priority_button_action_save))
+ .build());
+ actions.add(new GuidedAction.Builder(getActivity())
+ .clickAction(GuidedAction.ACTION_ID_CANCEL)
+ .build());
+ }
+
+ @Override
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_ID_SAVE) {
+ DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
+ int size = mSeriesRecordings.size();
+ for (int i = 1; i < size; ++i) {
+ long priority = DvrScheduleManager.suggestSeriesPriority(size - i);
+ SeriesRecording seriesRecording = mSeriesRecordings.get(i);
+ if (seriesRecording.getPriority() != priority) {
+ dvrManager.updateSeriesRecording(SeriesRecording.buildFrom(seriesRecording)
+ .setPriority(priority).build());
+ }
+ }
+ FragmentManager fragmentManager = getFragmentManager();
+ fragmentManager.popBackStack();
+ } else if (actionId == GuidedAction.ACTION_ID_CANCEL) {
+ FragmentManager fragmentManager = getFragmentManager();
+ fragmentManager.popBackStack();
+ } else if (mSelectedRecording == null) {
+ mSelectedRecording = mSeriesRecordings.get((int) actionId);
+ for (int i = 0; i < mSeriesRecordings.size(); ++i) {
+ updateItem(i);
+ }
+ } else {
+ mSelectedRecording = null;
+ for (int i = 0; i < mSeriesRecordings.size(); ++i) {
+ updateItem(i);
+ }
+ }
+ }
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrPrioritySettingsFragment";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_ID_SAVE) {
+ return "save";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
+
+ @Override
+ public void onGuidedActionFocused(GuidedAction action) {
+ super.onGuidedActionFocused(action);
+ if (mSelectedRecording == null) {
+ return;
+ }
+ if (action.getId() < 0) {
+ mSelectedRecording = null;
+ for (int i = 0; i < mSeriesRecordings.size(); ++i) {
+ updateItem(i);
+ }
+ return;
+ }
+ int position = (int) action.getId();
+ int previousPosition = mSeriesRecordings.indexOf(mSelectedRecording);
+ mSeriesRecordings.remove(mSelectedRecording);
+ mSeriesRecordings.add(position, mSelectedRecording);
+ updateItem(previousPosition);
+ updateItem(position);
+ notifyActionChanged(previousPosition);
+ notifyActionChanged(position);
+ }
+
+ @Override
+ public GuidedActionsStylist onCreateButtonActionsStylist() {
+ return new DvrGuidedActionsStylist(true);
+ }
+
+ @Override
+ public GuidedActionsStylist onCreateActionsStylist() {
+ return new DvrGuidedActionsStylist(false) {
+ @Override
+ public void onBindViewHolder(ViewHolder vh, GuidedAction action) {
+ super.onBindViewHolder(vh, action);
+ updateItem(vh.itemView, (int) action.getId());
+ }
+
+ @Override
+ public int onProvideItemLayoutId() {
+ return R.layout.priority_settings_action_item;
+ }
+ };
+ }
+
+ private void updateItem(int position) {
+ View itemView = getActionItemView(position);
+ if (itemView == null) {
+ return;
+ }
+ updateItem(itemView, position);
+ }
+
+ private void updateItem(View itemView, int position) {
+ GuidedAction action = getActions().get(position);
+ action.setTitle(mSeriesRecordings.get(position).getTitle());
+ boolean selected = mSelectedRecording != null
+ && mSeriesRecordings.indexOf(mSelectedRecording) == position;
+ TextView titleView = (TextView) itemView.findViewById(R.id.guidedactions_item_title);
+ ImageView imageView = (ImageView) itemView.findViewById(R.id.guidedactions_item_tail_image);
+ if (position == 0) {
+ // one-time recording
+ itemView.setBackgroundResource(R.drawable.setup_selector_background);
+ imageView.setVisibility(View.GONE);
+ itemView.setFocusable(false);
+ itemView.setElevation(0);
+ // strings.xml <i> tag doesn't work.
+ titleView.setTypeface(titleView.getTypeface(), Typeface.ITALIC);
+ } else if (mSelectedRecording == null) {
+ titleView.setTextColor(mActionColor);
+ itemView.setBackgroundResource(R.drawable.setup_selector_background);
+ imageView.setImageResource(R.drawable.ic_draggable_white);
+ imageView.setVisibility(View.VISIBLE);
+ itemView.setFocusable(true);
+ itemView.setElevation(0);
+ titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL);
+ } else if (selected) {
+ titleView.setTextColor(mSelectedActionColor);
+ itemView.setBackgroundResource(R.drawable.priority_settings_action_item_selected);
+ imageView.setImageResource(R.drawable.ic_dragging_grey);
+ imageView.setVisibility(View.VISIBLE);
+ itemView.setFocusable(true);
+ itemView.setElevation(mSelectedActionElevation);
+ titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL);
+ } else {
+ titleView.setTextColor(mActionColor);
+ itemView.setBackgroundResource(R.drawable.setup_selector_background);
+ imageView.setVisibility(View.INVISIBLE);
+ itemView.setFocusable(true);
+ itemView.setElevation(0);
+ titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrScheduleFragment.java b/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
index da6d1637..390e0928 100644
--- a/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrScheduleFragment.java
@@ -32,9 +32,8 @@ import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.ui.DvrConflictFragment.DvrProgramConflictFragment;
import com.android.tv.util.Utils;
@@ -48,18 +47,26 @@ import java.util.List;
*/
@TargetApi(Build.VERSION_CODES.N)
public class DvrScheduleFragment extends DvrGuidedStepFragment {
+ /**
+ * Key for the whether to add the current program to series.
+ * Type: boolean
+ */
+ public static final String KEY_ADD_CURRENT_PROGRAM_TO_SERIES = "add_current_program_to_series";
+
private static final String TAG = "DvrScheduleFragment";
private static final int ACTION_RECORD_EPISODE = 1;
private static final int ACTION_RECORD_SERIES = 2;
private Program mProgram;
+ private boolean mAddCurrentProgramToSeries;
@Override
public void onCreate(Bundle savedInstanceState) {
Bundle args = getArguments();
if (args != null) {
mProgram = args.getParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM);
+ mAddCurrentProgramToSeries = args.getBoolean(KEY_ADD_CURRENT_PROGRAM_TO_SERIES, false);
}
DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
SoftPreconditions.checkArgument(mProgram != null && mProgram.isEpisodic(), TAG,
@@ -109,7 +116,7 @@ public class DvrScheduleFragment extends DvrGuidedStepFragment {
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
if (action.getId() == ACTION_RECORD_EPISODE) {
getDvrManager().addSchedule(mProgram);
List<ScheduledRecording> conflicts = getDvrManager().getConflictingSchedules(mProgram);
@@ -139,9 +146,28 @@ public class DvrScheduleFragment extends DvrGuidedStepFragment {
.build();
getDvrManager().updateSeriesRecording(seriesRecording);
}
+
DvrUiHelper.startSeriesSettingsActivity(getContext(),
- seriesRecording.getId(), null, true, true, true);
+ seriesRecording.getId(), null, true, true, true,
+ mAddCurrentProgramToSeries ? mProgram : null);
dismissDialog();
}
}
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrSmallSizedStorageErrorFragment";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_RECORD_EPISODE) {
+ return "record-episode";
+ } else if (actionId == ACTION_RECORD_SERIES) {
+ return "record-series";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
}
diff --git a/src/com/android/tv/dvr/ui/DvrSchedulesActivity.java b/src/com/android/tv/dvr/ui/DvrSchedulesActivity.java
deleted file mode 100644
index f6e6ac26..00000000
--- a/src/com/android/tv/dvr/ui/DvrSchedulesActivity.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.os.Bundle;
-import android.support.annotation.IntDef;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.Program;
-import com.android.tv.dvr.EpisodicProgramLoadTask;
-import com.android.tv.dvr.SeriesRecording;
-import com.android.tv.dvr.SeriesRecordingScheduler;
-import com.android.tv.dvr.ui.list.DvrSchedulesFragment;
-import com.android.tv.dvr.ui.list.DvrSeriesSchedulesFragment;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Activity to show the list of recording schedules.
- */
-public class DvrSchedulesActivity extends Activity {
- /**
- * The key for the type of the schedules which will be listed in the list. The type of the value
- * should be {@link ScheduleListType}.
- */
- public static final String KEY_SCHEDULES_TYPE = "schedules_type";
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({TYPE_FULL_SCHEDULE, TYPE_SERIES_SCHEDULE})
- public @interface ScheduleListType {}
- /**
- * A type which means the activity will display the full scheduled recordings.
- */
- public static final int TYPE_FULL_SCHEDULE = 0;
- /**
- * A type which means the activity will display a scheduled recording list of a series
- * recording.
- */
- public static final int TYPE_SERIES_SCHEDULE = 1;
-
- @Override
- public void onCreate(final Bundle savedInstanceState) {
- TvApplication.setCurrentRunningProcess(this, true);
- // Pass null to prevent automatically re-creating fragments
- super.onCreate(null);
- setContentView(R.layout.activity_dvr_schedules);
- int scheduleType = getIntent().getIntExtra(KEY_SCHEDULES_TYPE, TYPE_FULL_SCHEDULE);
- if (scheduleType == TYPE_FULL_SCHEDULE) {
- DvrSchedulesFragment schedulesFragment = new DvrSchedulesFragment();
- schedulesFragment.setArguments(getIntent().getExtras());
- getFragmentManager().beginTransaction().add(
- R.id.fragment_container, schedulesFragment).commit();
- } else if (scheduleType == TYPE_SERIES_SCHEDULE) {
- final ProgressDialog dialog = ProgressDialog.show(this, null, getString(
- R.string.dvr_series_schedules_progress_message_reading_programs));
- SeriesRecording seriesRecording = getIntent().getExtras()
- .getParcelable(DvrSeriesSchedulesFragment
- .SERIES_SCHEDULES_KEY_SERIES_RECORDING);
- // To get programs faster, hold the update of the series schedules.
- SeriesRecordingScheduler.getInstance(this).pauseUpdate();
- new EpisodicProgramLoadTask(this, Collections.singletonList(seriesRecording)) {
- @Override
- protected void onPostExecute(List<Program> programs) {
- SeriesRecordingScheduler.getInstance(DvrSchedulesActivity.this).resumeUpdate();
- dialog.dismiss();
- Bundle args = getIntent().getExtras();
- args.putParcelableArrayList(DvrSeriesSchedulesFragment
- .SERIES_SCHEDULES_KEY_SERIES_PROGRAMS, new ArrayList<>(programs));
- DvrSeriesSchedulesFragment schedulesFragment = new DvrSeriesSchedulesFragment();
- schedulesFragment.setArguments(args);
- getFragmentManager().beginTransaction().add(
- R.id.fragment_container, schedulesFragment).commit();
- }
- }.setLoadCurrentProgram(true)
- .setLoadDisallowedProgram(true)
- .setLoadScheduledEpisode(true)
- .setIgnoreChannelOption(true)
- .execute();
- } else {
- finish();
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
index f57e4b05..667af34a 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesDeletionActivity.java
@@ -22,9 +22,6 @@ import android.support.v17.leanback.app.GuidedStepFragment;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dvr.ui.SeriesDeletionFragment;
-import com.android.tv.ui.sidepanel.SettingsFragment;
/**
* Activity to show details view in DVR.
@@ -42,7 +39,7 @@ public class DvrSeriesDeletionActivity extends Activity {
setContentView(R.layout.activity_dvr_series_settings);
// Check savedInstanceState to prevent that activity is being showed with animation.
if (savedInstanceState == null) {
- SeriesDeletionFragment deletionFragment = new SeriesDeletionFragment();
+ DvrSeriesDeletionFragment deletionFragment = new DvrSeriesDeletionFragment();
deletionFragment.setArguments(getIntent().getExtras());
GuidedStepFragment.addAsRoot(this, deletionFragment, R.id.dvr_settings_view_frame);
}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java
new file mode 100644
index 00000000..8bf8560f
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/DvrSeriesDeletionFragment.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui;
+
+import android.content.Context;
+import android.media.tv.TvInputManager;
+import android.os.Bundle;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
+import android.text.TextUtils;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.Toast;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.DvrWatchedPositionManager;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.ui.GuidedActionsStylistWithDivider;
+import com.android.tv.util.Utils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Fragment for DVR series recording settings.
+ */
+public class DvrSeriesDeletionFragment extends GuidedStepFragment {
+ private static final long WATCHED_TIME_UNIT_THRESHOLD = TimeUnit.MINUTES.toMillis(2);
+
+ // Since recordings' IDs are used as its check actions' IDs, which are random positive numbers,
+ // negative values are used by other actions to prevent duplicated IDs.
+ private static final long ACTION_ID_SELECT_WATCHED = -110;
+ private static final long ACTION_ID_SELECT_ALL = -111;
+ private static final long ACTION_ID_DELETE = -112;
+
+ private DvrDataManager mDvrDataManager;
+ private DvrWatchedPositionManager mDvrWatchedPositionManager;
+ private List<RecordedProgram> mRecordings;
+ private final Set<Long> mWatchedRecordings = new HashSet<>();
+ private boolean mAllSelected;
+ private long mSeriesRecordingId;
+ private int mOneLineActionHeight;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mSeriesRecordingId = getArguments()
+ .getLong(DvrSeriesDeletionActivity.SERIES_RECORDING_ID, -1);
+ SoftPreconditions.checkArgument(mSeriesRecordingId != -1);
+ mDvrDataManager = TvApplication.getSingletons(context).getDvrDataManager();
+ mDvrWatchedPositionManager =
+ TvApplication.getSingletons(context).getDvrWatchedPositionManager();
+ mRecordings = mDvrDataManager.getRecordedPrograms(mSeriesRecordingId);
+ mOneLineActionHeight = getResources().getDimensionPixelSize(
+ R.dimen.dvr_settings_one_line_action_container_height);
+ if (mRecordings.isEmpty()) {
+ Toast.makeText(getActivity(), getString(R.string.dvr_series_deletion_no_recordings),
+ Toast.LENGTH_LONG).show();
+ finishGuidedStepFragments();
+ return;
+ }
+ Collections.sort(mRecordings, RecordedProgram.EPISODE_COMPARATOR);
+ }
+
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String breadcrumb = null;
+ SeriesRecording series = mDvrDataManager.getSeriesRecording(mSeriesRecordingId);
+ if (series != null) {
+ breadcrumb = series.getTitle();
+ }
+ return new Guidance(getString(R.string.dvr_series_deletion_title),
+ getString(R.string.dvr_series_deletion_description), breadcrumb, null);
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder(getActivity())
+ .id(ACTION_ID_SELECT_WATCHED)
+ .title(getString(R.string.dvr_series_select_watched))
+ .build());
+ actions.add(new GuidedAction.Builder(getActivity())
+ .id(ACTION_ID_SELECT_ALL)
+ .title(getString(R.string.dvr_series_select_all))
+ .build());
+ actions.add(GuidedActionsStylistWithDivider.createDividerAction(getContext()));
+ for (RecordedProgram recording : mRecordings) {
+ long watchedPositionMs =
+ mDvrWatchedPositionManager.getWatchedPosition(recording.getId());
+ String title = recording.getEpisodeDisplayTitle(getContext());
+ if (TextUtils.isEmpty(title)) {
+ title = TextUtils.isEmpty(recording.getTitle()) ?
+ getString(R.string.channel_banner_no_title) : recording.getTitle();
+ }
+ String description;
+ if (watchedPositionMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
+ description = getWatchedString(watchedPositionMs, recording.getDurationMillis());
+ mWatchedRecordings.add(recording.getId());
+ } else {
+ description = getString(R.string.dvr_series_never_watched);
+ }
+ actions.add(new GuidedAction.Builder(getActivity())
+ .id(recording.getId())
+ .title(title)
+ .description(description)
+ .checkSetId(GuidedAction.CHECKBOX_CHECK_SET_ID)
+ .build());
+ }
+ }
+
+ @Override
+ public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder(getActivity())
+ .id(ACTION_ID_DELETE)
+ .title(getString(R.string.dvr_detail_delete))
+ .build());
+ actions.add(new GuidedAction.Builder(getActivity())
+ .clickAction(GuidedAction.ACTION_ID_CANCEL)
+ .build());
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_ID_DELETE) {
+ List<Long> idsToDelete = new ArrayList<>();
+ for (GuidedAction guidedAction : getActions()) {
+ if (guidedAction.getCheckSetId() == GuidedAction.CHECKBOX_CHECK_SET_ID
+ && guidedAction.isChecked()) {
+ idsToDelete.add(guidedAction.getId());
+ }
+ }
+ if (!idsToDelete.isEmpty()) {
+ DvrManager dvrManager = TvApplication.getSingletons(getActivity()).getDvrManager();
+ dvrManager.removeRecordedPrograms(idsToDelete);
+ }
+ Toast.makeText(getContext(), getResources().getQuantityString(
+ R.plurals.dvr_msg_episodes_deleted, idsToDelete.size(), idsToDelete.size(),
+ mRecordings.size()), Toast.LENGTH_LONG).show();
+ finishGuidedStepFragments();
+ } else if (actionId == GuidedAction.ACTION_ID_CANCEL) {
+ finishGuidedStepFragments();
+ } else if (actionId == ACTION_ID_SELECT_WATCHED) {
+ for (GuidedAction guidedAction : getActions()) {
+ if (guidedAction.getCheckSetId() == GuidedAction.CHECKBOX_CHECK_SET_ID) {
+ long recordingId = guidedAction.getId();
+ if (mWatchedRecordings.contains(recordingId)) {
+ guidedAction.setChecked(true);
+ } else {
+ guidedAction.setChecked(false);
+ }
+ notifyActionChanged(findActionPositionById(recordingId));
+ }
+ }
+ mAllSelected = updateSelectAllState();
+ } else if (actionId == ACTION_ID_SELECT_ALL) {
+ mAllSelected = !mAllSelected;
+ for (GuidedAction guidedAction : getActions()) {
+ if (guidedAction.getCheckSetId() == GuidedAction.CHECKBOX_CHECK_SET_ID) {
+ guidedAction.setChecked(mAllSelected);
+ notifyActionChanged(findActionPositionById(guidedAction.getId()));
+ }
+ }
+ updateSelectAllState(action, mAllSelected);
+ } else {
+ mAllSelected = updateSelectAllState();
+ }
+ }
+
+ @Override
+ public GuidedActionsStylist onCreateButtonActionsStylist() {
+ return new DvrGuidedActionsStylist(true);
+ }
+
+ @Override
+ public GuidedActionsStylist onCreateActionsStylist() {
+ return new GuidedActionsStylistWithDivider() {
+ @Override
+ public void onBindViewHolder(ViewHolder vh, GuidedAction action) {
+ super.onBindViewHolder(vh, action);
+ if (action.getId() == ACTION_DIVIDER) {
+ return;
+ }
+ LayoutParams lp = vh.itemView.getLayoutParams();
+ if (action.getCheckSetId() != GuidedAction.CHECKBOX_CHECK_SET_ID) {
+ lp.height = mOneLineActionHeight;
+ } else {
+ vh.itemView.setLayoutParams(
+ new LayoutParams(lp.width, LayoutParams.WRAP_CONTENT));
+ }
+ }
+ };
+ }
+
+ private String getWatchedString(long watchedPositionMs, long durationMs) {
+ if (durationMs > WATCHED_TIME_UNIT_THRESHOLD) {
+ return getResources().getString(R.string.dvr_series_watched_info_minutes,
+ Math.max(1, Utils.getRoundOffMinsFromMs(watchedPositionMs)),
+ Utils.getRoundOffMinsFromMs(durationMs));
+ } else {
+ return getResources().getString(R.string.dvr_series_watched_info_seconds,
+ Math.max(1, TimeUnit.MILLISECONDS.toSeconds(watchedPositionMs)),
+ TimeUnit.MILLISECONDS.toSeconds(durationMs));
+ }
+ }
+
+ private boolean updateSelectAllState() {
+ for (GuidedAction guidedAction : getActions()) {
+ if (guidedAction.getCheckSetId() == GuidedAction.CHECKBOX_CHECK_SET_ID) {
+ if (!guidedAction.isChecked()) {
+ if (mAllSelected) {
+ updateSelectAllState(findActionById(ACTION_ID_SELECT_ALL), false);
+ }
+ return false;
+ }
+ }
+ }
+ if (!mAllSelected) {
+ updateSelectAllState(findActionById(ACTION_ID_SELECT_ALL), true);
+ }
+ return true;
+ }
+
+ private void updateSelectAllState(GuidedAction selectAll, boolean select) {
+ selectAll.setTitle(select ? getString(R.string.dvr_series_deselect_all)
+ : getString(R.string.dvr_series_select_all));
+ notifyActionChanged(findActionPositionById(ACTION_ID_SELECT_ALL));
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
index 1173df46..2c4bb3ea 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesScheduledFragment.java
@@ -25,22 +25,29 @@ import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.data.Program;
import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.ui.list.DvrSchedulesActivity;
import com.android.tv.dvr.ui.list.DvrSeriesSchedulesFragment;
import java.util.List;
public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
+ /**
+ * The key for program list which will be passed to {@link DvrSeriesSchedulesFragment}.
+ * Type: List<{@link Program}>
+ */
+ public static final String SERIES_SCHEDULED_KEY_PROGRAMS = "series_scheduled_key_programs";
+
private final static long SERIES_RECORDING_ID_NOT_SET = -1;
private final static int ACTION_VIEW_SCHEDULES = 1;
- private DvrScheduleManager mDvrScheduleManager;
private SeriesRecording mSeriesRecording;
private boolean mShowViewScheduleOption;
+ private List<Program> mPrograms;
private int mSchedulesAddedCount = 0;
private boolean mHasConflict = false;
@@ -58,22 +65,25 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
}
mShowViewScheduleOption = getArguments().getBoolean(
DvrSeriesScheduledDialogActivity.SHOW_VIEW_SCHEDULE_OPTION);
- mDvrScheduleManager = TvApplication.getSingletons(context).getDvrScheduleManager();
mSeriesRecording = TvApplication.getSingletons(context).getDvrDataManager()
.getSeriesRecording(seriesRecordingId);
if (mSeriesRecording == null) {
getActivity().finish();
return;
}
+ mPrograms = (List<Program>) BigArguments.getArgument(SERIES_SCHEDULED_KEY_PROGRAMS);
+ BigArguments.reset();
mSchedulesAddedCount = TvApplication.getSingletons(getContext()).getDvrManager()
.getAvailableScheduledRecording(mSeriesRecording.getId()).size();
+ DvrScheduleManager dvrScheduleManager =
+ TvApplication.getSingletons(context).getDvrScheduleManager();
List<ScheduledRecording> conflictingRecordings =
- mDvrScheduleManager.getConflictingSchedules(mSeriesRecording);
+ dvrScheduleManager.getConflictingSchedules(mSeriesRecording);
mHasConflict = !conflictingRecordings.isEmpty();
for (ScheduledRecording recording : conflictingRecordings) {
if (recording.getSeriesRecordingId() == mSeriesRecording.getId()) {
++mInThisSeriesConflictCount;
- } else {
+ } else if (recording.getPriority() < mSeriesRecording.getPriority()) {
++mOutThisSeriesConflictCount;
}
}
@@ -106,45 +116,63 @@ public class DvrSeriesScheduledFragment extends DvrGuidedStepFragment {
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
if (action.getId() == ACTION_VIEW_SCHEDULES) {
Intent intent = new Intent(getActivity(), DvrSchedulesActivity.class);
intent.putExtra(DvrSchedulesActivity.KEY_SCHEDULES_TYPE, DvrSchedulesActivity
.TYPE_SERIES_SCHEDULE);
intent.putExtra(DvrSeriesSchedulesFragment.SERIES_SCHEDULES_KEY_SERIES_RECORDING,
mSeriesRecording);
+ BigArguments.reset();
+ BigArguments.setArgument(DvrSeriesSchedulesFragment
+ .SERIES_SCHEDULES_KEY_SERIES_PROGRAMS, mPrograms);
startActivity(intent);
}
getActivity().finish();
}
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrMissingStorageErrorFragment";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_VIEW_SCHEDULES) {
+ return "view-schedules";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
+
private String getDescription() {
if (!mHasConflict) {
return getResources().getQuantityString(
- R.plurals.dvr_series_recording_scheduled_no_conflict, mSchedulesAddedCount,
+ R.plurals.dvr_series_scheduled_no_conflict, mSchedulesAddedCount,
mSchedulesAddedCount, mSeriesRecording.getTitle());
} else {
// mInThisSeriesConflictCount equals 0 and mOutThisSeriesConflictCount equals 0 means
// mHasConflict is false. So we don't need to check that case.
if (mInThisSeriesConflictCount != 0 && mOutThisSeriesConflictCount != 0) {
- return getResources().getQuantityString(R.plurals
- .dvr_series_recording_scheduled_this_and_other_series_conflict,
+ return getResources().getQuantityString(
+ R.plurals.dvr_series_scheduled_this_and_other_series_conflict,
mSchedulesAddedCount, mSchedulesAddedCount, mSeriesRecording.getTitle(),
mInThisSeriesConflictCount + mOutThisSeriesConflictCount);
} else if (mInThisSeriesConflictCount != 0) {
- return getResources().getQuantityString(R.plurals
- .dvr_series_recording_scheduled_only_this_series_conflict,
+ return getResources().getQuantityString(
+ R.plurals.dvr_series_recording_scheduled_only_this_series_conflict,
mSchedulesAddedCount, mSchedulesAddedCount, mSeriesRecording.getTitle(),
mInThisSeriesConflictCount);
} else {
if (mOutThisSeriesConflictCount == 1) {
- return getResources().getQuantityString(R.plurals
- .dvr_series_recording_scheduled_only_other_series_one_conflict,
+ return getResources().getQuantityString(
+ R.plurals.dvr_series_scheduled_only_other_series_one_conflict,
mSchedulesAddedCount, mSchedulesAddedCount,
mSeriesRecording.getTitle());
} else {
- return getResources().getQuantityString(R.plurals
- .dvr_series_recording_scheduled_only_other_series_conflict,
+ return getResources().getQuantityString(
+ R.plurals.dvr_series_scheduled_only_other_series_many_conflicts,
mSchedulesAddedCount, mSchedulesAddedCount, mSeriesRecording.getTitle(),
mOutThisSeriesConflictCount);
}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java b/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
index 3f7671b3..6dd20b3a 100644
--- a/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
+++ b/src/com/android/tv/dvr/ui/DvrSeriesSettingsActivity.java
@@ -17,7 +17,6 @@
package com.android.tv.dvr.ui;
import android.app.Activity;
-import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.v17.leanback.app.GuidedStepFragment;
@@ -38,25 +37,34 @@ public class DvrSeriesSettingsActivity extends Activity {
/**
* Name of the boolean flag to decide if the series recording with empty schedule and recording
* will be removed.
+ * Type: boolean
*/
public static final String REMOVE_EMPTY_SERIES_RECORDING = "remove_empty_series_recording";
/**
* Name of the boolean flag to decide if the setting fragment should be translucent.
+ * Type: boolean
*/
public static final String IS_WINDOW_TRANSLUCENT = "windows_translucent";
/**
- * Name of the channel id list. If the channel list is given, we show the channels
- * from the values in channel option.
- * Type: Long array
+ * Name of the program list. The list contains the programs which belong to the series.
+ * Type: List<{@link com.android.tv.data.Program}>
*/
- public static final String CHANNEL_ID_LIST = "channel_id_list";
+ public static final String PROGRAM_LIST = "program_list";
/**
* Name of the boolean flag to check if the confirm dialog should show view schedule option.
+ * Type: boolean
*/
public static final String SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG =
"show_view_schedule_option_in_dialog";
+ /**
+ * Name of the current program added to series. The current program will be recorded only when
+ * the series recording is initialized from media controller. But for other case, the current
+ * program won't be recorded.
+ */
+ public static final String CURRENT_PROGRAM = "current_program";
+
@Override
public void onCreate(Bundle savedInstanceState) {
TvApplication.setCurrentRunningProcess(this, true);
@@ -66,7 +74,7 @@ public class DvrSeriesSettingsActivity extends Activity {
SoftPreconditions.checkArgument(seriesRecordingId != -1);
if (savedInstanceState == null) {
- SeriesSettingsFragment settingFragment = new SeriesSettingsFragment();
+ DvrSeriesSettingsFragment settingFragment = new DvrSeriesSettingsFragment();
settingFragment.setArguments(getIntent().getExtras());
GuidedStepFragment.addAsRoot(this, settingFragment, R.id.dvr_settings_view_frame);
}
diff --git a/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java b/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
new file mode 100644
index 00000000..f28382da
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/DvrSeriesSettingsFragment.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui;
+
+import android.app.FragmentManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
+import android.util.LongSparseArray;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.data.Channel;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.Program;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeasonEpisodeNumber;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.data.SeriesRecording.ChannelOption;
+import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Fragment for DVR series recording settings.
+ */
+public class DvrSeriesSettingsFragment extends GuidedStepFragment
+ implements DvrDataManager.SeriesRecordingListener {
+ private static final String TAG = "SeriesSettingsFragment";
+ private static final boolean DEBUG = false;
+
+ private static final long ACTION_ID_PRIORITY = 10;
+ private static final long ACTION_ID_CHANNEL = 11;
+
+ private static final long SUB_ACTION_ID_CHANNEL_ALL = 102;
+ // Each channel's action id = SUB_ACTION_ID_CHANNEL_ONE_BASE + channel id
+ private static final long SUB_ACTION_ID_CHANNEL_ONE_BASE = 500;
+
+ private DvrDataManager mDvrDataManager;
+ private SeriesRecording mSeriesRecording;
+ private long mSeriesRecordingId;
+ @ChannelOption int mChannelOption;
+ private long mSelectedChannelId;
+ private int mBackStackCount;
+ private boolean mShowViewScheduleOptionInDialog;
+ private Program mCurrentProgram;
+
+ private String mFragmentTitle;
+ private String mProrityActionTitle;
+ private String mProrityActionHighestText;
+ private String mProrityActionLowestText;
+ private String mChannelsActionTitle;
+ private String mChannelsActionAllText;
+ private LongSparseArray<Channel> mId2Channel = new LongSparseArray<>();
+ private List<Channel> mChannels = new ArrayList<>();
+ private List<Program> mPrograms;
+
+ private GuidedAction mPriorityGuidedAction;
+ private GuidedAction mChannelsGuidedAction;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mBackStackCount = getFragmentManager().getBackStackEntryCount();
+ mDvrDataManager = TvApplication.getSingletons(context).getDvrDataManager();
+ mSeriesRecordingId = getArguments().getLong(DvrSeriesSettingsActivity.SERIES_RECORDING_ID);
+ mSeriesRecording = mDvrDataManager.getSeriesRecording(mSeriesRecordingId);
+ if (mSeriesRecording == null) {
+ getActivity().finish();
+ return;
+ }
+ mShowViewScheduleOptionInDialog = getArguments().getBoolean(
+ DvrSeriesSettingsActivity.SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG);
+ mCurrentProgram = getArguments().getParcelable(DvrSeriesSettingsActivity.CURRENT_PROGRAM);
+ mDvrDataManager.addSeriesRecordingListener(this);
+ mPrograms = (List<Program>) BigArguments.getArgument(
+ DvrSeriesSettingsActivity.PROGRAM_LIST);
+ BigArguments.reset();
+ if (mPrograms == null) {
+ getActivity().finish();
+ return;
+ }
+ Set<Long> channelIds = new HashSet<>();
+ ChannelDataManager channelDataManager =
+ TvApplication.getSingletons(context).getChannelDataManager();
+ for (Program program : mPrograms) {
+ long channelId = program.getChannelId();
+ if (channelIds.add(channelId)) {
+ Channel channel = channelDataManager.getChannel(channelId);
+ if (channel != null) {
+ mId2Channel.put(channel.getId(), channel);
+ mChannels.add(channel);
+ }
+ }
+ }
+ mChannelOption = mSeriesRecording.getChannelOption();
+ mSelectedChannelId = Channel.INVALID_ID;
+ if (mChannelOption == SeriesRecording.OPTION_CHANNEL_ONE) {
+ Channel channel = channelDataManager.getChannel(mSeriesRecording.getChannelId());
+ if (channel != null) {
+ mSelectedChannelId = channel.getId();
+ } else {
+ mChannelOption = SeriesRecording.OPTION_CHANNEL_ALL;
+ }
+ }
+ mChannels.sort(Channel.CHANNEL_NUMBER_COMPARATOR);
+ mFragmentTitle = getString(R.string.dvr_series_settings_title);
+ mProrityActionTitle = getString(R.string.dvr_series_settings_priority);
+ mProrityActionHighestText = getString(R.string.dvr_series_settings_priority_highest);
+ mProrityActionLowestText = getString(R.string.dvr_series_settings_priority_lowest);
+ mChannelsActionTitle = getString(R.string.dvr_series_settings_channels);
+ mChannelsActionAllText = getString(R.string.dvr_series_settings_channels_all);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // To avoid the order of series's priority has changed, but series doesn't get update.
+ updatePriorityGuidedAction();
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mDvrDataManager.removeSeriesRecordingListener(this);
+ }
+
+ @Override
+ public void onDestroy() {
+ if (getFragmentManager().getBackStackEntryCount() == mBackStackCount && getArguments()
+ .getBoolean(DvrSeriesSettingsActivity.REMOVE_EMPTY_SERIES_RECORDING)) {
+ mDvrDataManager.checkAndRemoveEmptySeriesRecording(mSeriesRecordingId);
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String breadcrumb = mSeriesRecording.getTitle();
+ String title = mFragmentTitle;
+ return new Guidance(title, null, breadcrumb, null);
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ mPriorityGuidedAction = new GuidedAction.Builder(getActivity())
+ .id(ACTION_ID_PRIORITY)
+ .title(mProrityActionTitle)
+ .build();
+ actions.add(mPriorityGuidedAction);
+
+ mChannelsGuidedAction = new GuidedAction.Builder(getActivity())
+ .id(ACTION_ID_CHANNEL)
+ .title(mChannelsActionTitle)
+ .subActions(buildChannelSubAction())
+ .build();
+ actions.add(mChannelsGuidedAction);
+ updateChannelsGuidedAction(false);
+ }
+
+ @Override
+ public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder(getActivity())
+ .clickAction(GuidedAction.ACTION_ID_OK)
+ .build());
+ actions.add(new GuidedAction.Builder(getActivity())
+ .clickAction(GuidedAction.ACTION_ID_CANCEL)
+ .build());
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == GuidedAction.ACTION_ID_OK) {
+ if (mChannelOption != mSeriesRecording.getChannelOption()
+ || mSeriesRecording.isStopped()
+ || (mChannelOption == SeriesRecording.OPTION_CHANNEL_ONE
+ && mSeriesRecording.getChannelId() != mSelectedChannelId)) {
+ SeriesRecording.Builder builder = SeriesRecording.buildFrom(mSeriesRecording)
+ .setChannelOption(mChannelOption)
+ .setState(SeriesRecording.STATE_SERIES_NORMAL);
+ if (mSelectedChannelId != Channel.INVALID_ID) {
+ builder.setChannelId(mSelectedChannelId);
+ }
+ DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
+ dvrManager.updateSeriesRecording(builder.build());
+ if (mCurrentProgram != null && (mChannelOption == SeriesRecording.OPTION_CHANNEL_ALL
+ || mSelectedChannelId == mCurrentProgram.getChannelId())) {
+ dvrManager.addSchedule(mCurrentProgram);
+ }
+ updateSchedulesToSeries();
+ showConfirmDialog();
+ } else {
+ showConfirmDialog();
+ }
+ } else if (actionId == GuidedAction.ACTION_ID_CANCEL) {
+ finishGuidedStepFragments();
+ } else if (actionId == ACTION_ID_PRIORITY) {
+ FragmentManager fragmentManager = getFragmentManager();
+ DvrPrioritySettingsFragment fragment = new DvrPrioritySettingsFragment();
+ Bundle args = new Bundle();
+ args.putLong(DvrPrioritySettingsFragment.COME_FROM_SERIES_RECORDING_ID,
+ mSeriesRecording.getId());
+ fragment.setArguments(args);
+ GuidedStepFragment.add(fragmentManager, fragment, R.id.dvr_settings_view_frame);
+ }
+ }
+
+ @Override
+ public boolean onSubGuidedActionClicked(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == SUB_ACTION_ID_CHANNEL_ALL) {
+ mChannelOption = SeriesRecording.OPTION_CHANNEL_ALL;
+ mSelectedChannelId = Channel.INVALID_ID;
+ updateChannelsGuidedAction(true);
+ return true;
+ } else if (actionId > SUB_ACTION_ID_CHANNEL_ONE_BASE) {
+ mChannelOption = SeriesRecording.OPTION_CHANNEL_ONE;
+ mSelectedChannelId = actionId - SUB_ACTION_ID_CHANNEL_ONE_BASE;
+ updateChannelsGuidedAction(true);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public GuidedActionsStylist onCreateButtonActionsStylist() {
+ return new DvrGuidedActionsStylist(true);
+ }
+
+ private void updateChannelsGuidedAction(boolean notifyActionChanged) {
+ if (mChannelOption == SeriesRecording.OPTION_CHANNEL_ALL) {
+ mChannelsGuidedAction.setDescription(mChannelsActionAllText);
+ } else if (mId2Channel.get(mSelectedChannelId) != null){
+ mChannelsGuidedAction.setDescription(mId2Channel.get(mSelectedChannelId)
+ .getDisplayText());
+ }
+ if (notifyActionChanged) {
+ notifyActionChanged(findActionPositionById(ACTION_ID_CHANNEL));
+ }
+ }
+
+ private void updatePriorityGuidedAction() {
+ int totalSeriesCount = 0;
+ int priorityOrder = 0;
+ for (SeriesRecording seriesRecording : mDvrDataManager.getSeriesRecordings()) {
+ if (seriesRecording.getState() == SeriesRecording.STATE_SERIES_NORMAL
+ || seriesRecording.getId() == mSeriesRecording.getId()) {
+ ++totalSeriesCount;
+ }
+ if (seriesRecording.getState() == SeriesRecording.STATE_SERIES_NORMAL
+ && seriesRecording.getId() != mSeriesRecording.getId()
+ && seriesRecording.getPriority() > mSeriesRecording.getPriority()) {
+ ++priorityOrder;
+ }
+ }
+ if (priorityOrder == 0) {
+ mPriorityGuidedAction.setDescription(mProrityActionHighestText);
+ } else if (priorityOrder >= totalSeriesCount - 1) {
+ mPriorityGuidedAction.setDescription(mProrityActionLowestText);
+ } else {
+ mPriorityGuidedAction.setDescription(getString(
+ R.string.dvr_series_settings_priority_rank, priorityOrder + 1));
+ }
+ notifyActionChanged(findActionPositionById(ACTION_ID_PRIORITY));
+ }
+
+ private void updateSchedulesToSeries() {
+ List<Program> recordingCandidates = new ArrayList<>();
+ Set<SeasonEpisodeNumber> scheduledEpisodes = new HashSet<>();
+ for (ScheduledRecording r : mDvrDataManager.getScheduledRecordings(mSeriesRecordingId)) {
+ if (r.getState() != ScheduledRecording.STATE_RECORDING_FAILED
+ && r.getState() != ScheduledRecording.STATE_RECORDING_CLIPPED) {
+ scheduledEpisodes.add(new SeasonEpisodeNumber(
+ r.getSeriesRecordingId(), r.getSeasonNumber(), r.getEpisodeNumber()));
+ }
+ }
+ for (Program program : mPrograms) {
+ // Removes current programs and scheduled episodes out, matches the channel option.
+ if (program.getStartTimeUtcMillis() >= System.currentTimeMillis()
+ && mSeriesRecording.matchProgram(program)
+ && !scheduledEpisodes.contains(new SeasonEpisodeNumber(
+ mSeriesRecordingId, program.getSeasonNumber(), program.getEpisodeNumber()))) {
+ recordingCandidates.add(program);
+ }
+ }
+ if (recordingCandidates.isEmpty()) {
+ return;
+ }
+ List<Program> programsToSchedule = SeriesRecordingScheduler.pickOneProgramPerEpisode(
+ mDvrDataManager, Collections.singletonList(mSeriesRecording), recordingCandidates)
+ .get(mSeriesRecordingId);
+ if (!programsToSchedule.isEmpty()) {
+ TvApplication.getSingletons(getContext()).getDvrManager()
+ .addScheduleToSeriesRecording(mSeriesRecording, programsToSchedule);
+ }
+ }
+
+ private List<GuidedAction> buildChannelSubAction() {
+ List<GuidedAction> channelSubActions = new ArrayList<>();
+ channelSubActions.add(new GuidedAction.Builder(getActivity())
+ .id(SUB_ACTION_ID_CHANNEL_ALL)
+ .title(mChannelsActionAllText)
+ .build());
+ for (Channel channel : mChannels) {
+ channelSubActions.add(new GuidedAction.Builder(getActivity())
+ .id(SUB_ACTION_ID_CHANNEL_ONE_BASE + channel.getId())
+ .title(channel.getDisplayText())
+ .build());
+ }
+ return channelSubActions;
+ }
+
+ private void showConfirmDialog() {
+ DvrUiHelper.StartSeriesScheduledDialogActivity(getContext(), mSeriesRecording,
+ mShowViewScheduleOptionInDialog, mPrograms);
+ finishGuidedStepFragments();
+ }
+
+ @Override
+ public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) { }
+
+ @Override
+ public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) {
+ for (SeriesRecording series : seriesRecordings) {
+ if (series.getId() == mSeriesRecording.getId()) {
+ finishGuidedStepFragments();
+ return;
+ }
+ }
+ }
+
+ @Override
+ public void onSeriesRecordingChanged(SeriesRecording... seriesRecordings) {
+ for (SeriesRecording seriesRecording : seriesRecordings) {
+ if (seriesRecording.getId() == mSeriesRecordingId) {
+ mSeriesRecording = seriesRecording;
+ updatePriorityGuidedAction();
+ return;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java b/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
index c3867886..baa45793 100644
--- a/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopRecordingFragment.java
@@ -25,15 +25,12 @@ import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
import android.support.v17.leanback.widget.GuidedAction;
-import android.text.TextUtils;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -131,15 +128,8 @@ public class DvrStopRecordingFragment extends DvrGuidedStepFragment {
String title = getString(R.string.dvr_stop_recording_dialog_title);
String description;
if (mStopReason == REASON_ON_CONFLICT) {
- String programTitle = mSchedule.getProgramTitle();
- if (TextUtils.isEmpty(programTitle)) {
- ChannelDataManager channelDataManager =
- TvApplication.getSingletons(getActivity()).getChannelDataManager();
- Channel channel = channelDataManager.getChannel(mSchedule.getChannelId());
- programTitle = channel.getDisplayName();
- }
description = getString(R.string.dvr_stop_recording_dialog_description_on_conflict,
- mSchedule.getProgramTitle());
+ mSchedule.getProgramDisplayTitle(getContext()));
} else {
description = getString(R.string.dvr_stop_recording_dialog_description);
}
@@ -158,4 +148,19 @@ public class DvrStopRecordingFragment extends DvrGuidedStepFragment {
.clickAction(GuidedAction.ACTION_ID_CANCEL)
.build());
}
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrStopRecordingFragment";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_STOP) {
+ return "stop";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
index feaa2357..7b56cfc1 100644
--- a/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
+++ b/src/com/android/tv/dvr/ui/DvrStopSeriesRecordingFragment.java
@@ -31,8 +31,8 @@ import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
import java.util.ArrayList;
import java.util.List;
@@ -78,7 +78,7 @@ public class DvrStopSeriesRecordingFragment extends DvrGuidedStepFragment {
}
@Override
- public void onGuidedActionClicked(GuidedAction action) {
+ public void onTrackedGuidedActionClicked(GuidedAction action) {
if (action.getId() == ACTION_STOP_SERIES_RECORDING) {
ApplicationSingletons singletons = TvApplication.getSingletons(getContext());
DvrManager dvrManager = singletons.getDvrManager();
@@ -101,4 +101,18 @@ public class DvrStopSeriesRecordingFragment extends DvrGuidedStepFragment {
}
dismissDialog();
}
+
+ @Override
+ public String getTrackerPrefix() {
+ return "DvrStopSeriesRecordingFragment";
+ }
+
+ @Override
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ if (action.getId() == ACTION_STOP_SERIES_RECORDING) {
+ return "stop";
+ } else {
+ return super.getTrackerLabelForGuidedAction(action);
+ }
+ }
}
diff --git a/src/com/android/tv/dvr/ui/DvrUiHelper.java b/src/com/android/tv/dvr/ui/DvrUiHelper.java
new file mode 100644
index 00000000..302fd6cd
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/DvrUiHelper.java
@@ -0,0 +1,649 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.ui;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.media.tv.TvInputManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.ActivityOptionsCompat;
+import android.text.Html;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.text.style.TextAppearanceSpan;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import com.android.tv.MainActivity;
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.data.BaseProgram;
+import com.android.tv.data.Channel;
+import com.android.tv.data.Program;
+import com.android.tv.dialog.HalfSizedDialogFragment;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.DvrStorageStatusManager;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrAlreadyRecordedDialogFragment;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrAlreadyScheduledDialogFragment;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrChannelRecordDurationOptionDialogFragment;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrChannelWatchConflictDialogFragment;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrInsufficientSpaceErrorDialogFragment;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrMissingStorageErrorDialogFragment;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrNoFreeSpaceErrorDialogFragment;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrProgramConflictDialogFragment;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrScheduleDialogFragment;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrSmallSizedStorageErrorDialogFragment;
+import com.android.tv.dvr.ui.DvrHalfSizedDialogFragment.DvrStopRecordingDialogFragment;
+import com.android.tv.dvr.ui.browse.DvrBrowseActivity;
+import com.android.tv.dvr.ui.browse.DvrDetailsActivity;
+import com.android.tv.dvr.ui.list.DvrSchedulesActivity;
+import com.android.tv.dvr.ui.list.DvrSchedulesFragment;
+import com.android.tv.dvr.ui.list.DvrSeriesSchedulesFragment;
+import com.android.tv.dvr.ui.playback.DvrPlaybackActivity;
+import com.android.tv.util.ToastUtils;
+import com.android.tv.util.Utils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A helper class for DVR UI.
+ */
+@MainThread
+@TargetApi(Build.VERSION_CODES.N)
+public class DvrUiHelper {
+ private static final String TAG = "DvrUiHelper";
+
+ private static ProgressDialog sProgressDialog = null;
+
+ /**
+ * Checks if the storage status is good for recording and shows error messages if needed.
+ *
+ * @param recordingRequestRunnable if the storage status is OK to record or users choose to
+ * perform the operation anyway, this Runnable will run.
+ */
+ public static void checkStorageStatusAndShowErrorMessage(Activity activity, String inputId,
+ Runnable recordingRequestRunnable) {
+ if (Utils.isBundledInput(inputId)) {
+ switch (TvApplication.getSingletons(activity).getDvrStorageStatusManager()
+ .getDvrStorageStatus()) {
+ case DvrStorageStatusManager.STORAGE_STATUS_TOTAL_CAPACITY_TOO_SMALL:
+ showDvrSmallSizedStorageErrorDialog(activity);
+ return;
+ case DvrStorageStatusManager.STORAGE_STATUS_MISSING:
+ showDvrMissingStorageErrorDialog(activity);
+ return;
+ case DvrStorageStatusManager.STORAGE_STATUS_FREE_SPACE_INSUFFICIENT:
+ showDvrNoFreeSpaceErrorDialog(activity, recordingRequestRunnable);
+ return;
+ }
+ }
+ recordingRequestRunnable.run();
+ }
+
+ /**
+ * Shows the schedule dialog.
+ */
+ public static void showScheduleDialog(Activity activity, Program program,
+ boolean addCurrentProgramToSeries) {
+ if (SoftPreconditions.checkNotNull(program) == null) {
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
+ args.putBoolean(DvrScheduleFragment.KEY_ADD_CURRENT_PROGRAM_TO_SERIES,
+ addCurrentProgramToSeries);
+ showDialogFragment(activity, new DvrScheduleDialogFragment(), args, true, true);
+ }
+
+ /**
+ * Shows the recording duration options dialog.
+ */
+ public static void showChannelRecordDurationOptions(Activity activity, Channel channel) {
+ if (SoftPreconditions.checkNotNull(channel) == null) {
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putLong(DvrHalfSizedDialogFragment.KEY_CHANNEL_ID, channel.getId());
+ showDialogFragment(activity, new DvrChannelRecordDurationOptionDialogFragment(), args);
+ }
+
+ /**
+ * Shows the dialog which says that the new schedule conflicts with others.
+ */
+ public static void showScheduleConflictDialog(Activity activity, Program program) {
+ if (program == null) {
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
+ showDialogFragment(activity, new DvrProgramConflictDialogFragment(), args, false, true);
+ }
+
+ /**
+ * Shows the conflict dialog for the channel watching.
+ */
+ public static void showChannelWatchConflictDialog(MainActivity activity, Channel channel) {
+ if (channel == null) {
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putLong(DvrHalfSizedDialogFragment.KEY_CHANNEL_ID, channel.getId());
+ showDialogFragment(activity, new DvrChannelWatchConflictDialogFragment(), args);
+ }
+
+ /**
+ * Shows DVR insufficient space error dialog.
+ */
+ public static void showDvrInsufficientSpaceErrorDialog(MainActivity activity,
+ Set<String> failedScheduledRecordingInfoSet) {
+ Bundle args = new Bundle();
+ ArrayList<String> failedScheduledRecordingInfoArray =
+ new ArrayList<>(failedScheduledRecordingInfoSet);
+ args.putStringArrayList(DvrInsufficientSpaceErrorFragment.FAILED_SCHEDULED_RECORDING_INFOS,
+ failedScheduledRecordingInfoArray);
+ showDialogFragment(activity, new DvrInsufficientSpaceErrorDialogFragment(), args);
+ Utils.clearRecordingFailedReason(activity,
+ TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE);
+ Utils.clearFailedScheduledRecordingInfoSet(activity);
+ }
+
+ /**
+ * Shows DVR no free space error dialog.
+ *
+ * @param recordingRequestRunnable the recording request to be executed when users choose
+ * {@link DvrGuidedStepFragment#ACTION_RECORD_ANYWAY}.
+ */
+ public static void showDvrNoFreeSpaceErrorDialog(Activity activity,
+ Runnable recordingRequestRunnable) {
+ DvrHalfSizedDialogFragment fragment = new DvrNoFreeSpaceErrorDialogFragment();
+ fragment.setOnActionClickListener(new HalfSizedDialogFragment.OnActionClickListener() {
+ @Override
+ public void onActionClick(long actionId) {
+ if (actionId == DvrGuidedStepFragment.ACTION_RECORD_ANYWAY) {
+ recordingRequestRunnable.run();
+ } else if (actionId == DvrGuidedStepFragment.ACTION_DELETE_RECORDINGS) {
+ Intent intent = new Intent(activity, DvrBrowseActivity.class);
+ activity.startActivity(intent);
+ }
+ }
+ });
+ showDialogFragment(activity, fragment, null);
+ }
+
+ /**
+ * Shows DVR missing storage error dialog.
+ */
+ private static void showDvrMissingStorageErrorDialog(Activity activity) {
+ showDialogFragment(activity, new DvrMissingStorageErrorDialogFragment(), null);
+ }
+
+ /**
+ * Shows DVR small sized storage error dialog.
+ */
+ public static void showDvrSmallSizedStorageErrorDialog(Activity activity) {
+ showDialogFragment(activity, new DvrSmallSizedStorageErrorDialogFragment(), null);
+ }
+
+ /**
+ * Shows stop recording dialog.
+ */
+ public static void showStopRecordingDialog(Activity activity, long channelId, int reason,
+ HalfSizedDialogFragment.OnActionClickListener listener) {
+ Bundle args = new Bundle();
+ args.putLong(DvrHalfSizedDialogFragment.KEY_CHANNEL_ID, channelId);
+ args.putInt(DvrStopRecordingFragment.KEY_REASON, reason);
+ DvrHalfSizedDialogFragment fragment = new DvrStopRecordingDialogFragment();
+ fragment.setOnActionClickListener(listener);
+ showDialogFragment(activity, fragment, args);
+ }
+
+ /**
+ * Shows "already scheduled" dialog.
+ */
+ public static void showAlreadyScheduleDialog(Activity activity, Program program) {
+ if (program == null) {
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
+ showDialogFragment(activity, new DvrAlreadyScheduledDialogFragment(), args, false, true);
+ }
+
+ /**
+ * Shows "already recorded" dialog.
+ */
+ public static void showAlreadyRecordedDialog(Activity activity, Program program) {
+ if (program == null) {
+ return;
+ }
+ Bundle args = new Bundle();
+ args.putParcelable(DvrHalfSizedDialogFragment.KEY_PROGRAM, program);
+ showDialogFragment(activity, new DvrAlreadyRecordedDialogFragment(), args, false, true);
+ }
+
+ /**
+ * Handle the request of recording a current program. It will handle creating schedules and
+ * shows the proper dialog and toast message respectively for timed-recording and program
+ * recording cases.
+ *
+ * @param addProgramToSeries denotes whether the program to be recorded should be added into
+ * the series recording when users choose to record the entire series.
+ */
+ public static void requestRecordingCurrentProgram(Activity activity,
+ Channel channel, Program program, boolean addProgramToSeries) {
+ if (program == null) {
+ DvrUiHelper.showChannelRecordDurationOptions(activity, channel);
+ } else if (DvrUiHelper.handleCreateSchedule(activity, program, addProgramToSeries)) {
+ String msg = activity.getString(R.string.dvr_msg_current_program_scheduled,
+ program.getTitle(), Utils.toTimeString(program.getEndTimeUtcMillis(), false));
+ Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ /**
+ * Handle the request of recording a future program. It will handle creating schedules and
+ * shows the proper toast message.
+ *
+ * @param addProgramToSeries denotes whether the program to be recorded should be added into
+ * the series recording when users choose to record the entire series.
+ */
+ public static void requestRecordingFutureProgram(Activity activity,
+ Program program, boolean addProgramToSeries) {
+ if (DvrUiHelper.handleCreateSchedule(activity, program, addProgramToSeries)) {
+ String msg = activity.getString(
+ R.string.dvr_msg_program_scheduled, program.getTitle());
+ ToastUtils.show(activity, msg, Toast.LENGTH_SHORT);
+ }
+ }
+
+ /**
+ * Handles the action to create the new schedule. It returns {@code true} if the schedule is
+ * added and there's no additional UI, otherwise {@code false}.
+ */
+ private static boolean handleCreateSchedule(Activity activity, Program program,
+ boolean addProgramToSeries) {
+ if (program == null) {
+ return false;
+ }
+ DvrManager dvrManager = TvApplication.getSingletons(activity).getDvrManager();
+ if (!program.isEpisodic()) {
+ // One time recording.
+ dvrManager.addSchedule(program);
+ if (!dvrManager.getConflictingSchedules(program).isEmpty()) {
+ DvrUiHelper.showScheduleConflictDialog(activity, program);
+ return false;
+ }
+ } else {
+ // Show recorded program rather than the schedule.
+ RecordedProgram recordedProgram = dvrManager.getRecordedProgram(program.getTitle(),
+ program.getSeasonNumber(), program.getEpisodeNumber());
+ if (recordedProgram != null) {
+ DvrUiHelper.showAlreadyRecordedDialog(activity, program);
+ return false;
+ }
+ ScheduledRecording duplicate = dvrManager.getScheduledRecording(program.getTitle(),
+ program.getSeasonNumber(), program.getEpisodeNumber());
+ if (duplicate != null
+ && (duplicate.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED
+ || duplicate.getState()
+ == ScheduledRecording.STATE_RECORDING_IN_PROGRESS)) {
+ DvrUiHelper.showAlreadyScheduleDialog(activity, program);
+ return false;
+ }
+ SeriesRecording seriesRecording = dvrManager.getSeriesRecording(program);
+ if (seriesRecording == null || seriesRecording.isStopped()) {
+ DvrUiHelper.showScheduleDialog(activity, program, addProgramToSeries);
+ return false;
+ } else {
+ // Just add the schedule.
+ dvrManager.addSchedule(program);
+ }
+ }
+ return true;
+ }
+
+ private static void showDialogFragment(Activity activity,
+ DvrHalfSizedDialogFragment dialogFragment, Bundle args) {
+ showDialogFragment(activity, dialogFragment, args, false, false);
+ }
+
+ private static void showDialogFragment(Activity activity,
+ DvrHalfSizedDialogFragment dialogFragment, Bundle args, boolean keepSidePanelHistory,
+ boolean keepProgramGuide) {
+ dialogFragment.setArguments(args);
+ if (activity instanceof MainActivity) {
+ ((MainActivity) activity).getOverlayManager()
+ .showDialogFragment(DvrHalfSizedDialogFragment.DIALOG_TAG, dialogFragment,
+ keepSidePanelHistory, keepProgramGuide);
+ } else {
+ dialogFragment.show(activity.getFragmentManager(),
+ DvrHalfSizedDialogFragment.DIALOG_TAG);
+ }
+ }
+
+ /**
+ * Checks whether channel watch conflict dialog is open or not.
+ */
+ public static boolean isChannelWatchConflictDialogShown(MainActivity activity) {
+ return activity.getOverlayManager().getCurrentDialog() instanceof
+ DvrChannelWatchConflictDialogFragment;
+ }
+
+ private static ScheduledRecording getEarliestScheduledRecording(List<ScheduledRecording>
+ recordings) {
+ ScheduledRecording earlistScheduledRecording = null;
+ if (!recordings.isEmpty()) {
+ Collections.sort(recordings,
+ ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR);
+ earlistScheduledRecording = recordings.get(0);
+ }
+ return earlistScheduledRecording;
+ }
+
+ /**
+ * Launches DVR playback activity for the give recorded program.
+ *
+ * @param programId the ID of the recorded program going to be played.
+ * @param seekTimeMs the seek position to initial playback.
+ * @param pinChecked {@code true} if the pin code for parental controls has already been
+ * verified, otherwise {@code false}.
+ */
+ public static void startPlaybackActivity(Context context, long programId,
+ long seekTimeMs, boolean pinChecked) {
+ Intent intent = new Intent(context, DvrPlaybackActivity.class);
+ intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, programId);
+ if (seekTimeMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
+ intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_SEEK_TIME, seekTimeMs);
+ }
+ intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_PIN_CHECKED, pinChecked);
+ context.startActivity(intent);
+ }
+
+ /**
+ * Shows the schedules activity to resolve the tune conflict.
+ */
+ public static void startSchedulesActivityForTuneConflict(Context context, Channel channel) {
+ if (channel == null) {
+ return;
+ }
+ List<ScheduledRecording> conflicts = TvApplication.getSingletons(context).getDvrManager()
+ .getConflictingSchedulesForTune(channel.getId());
+ startSchedulesActivity(context, getEarliestScheduledRecording(conflicts));
+ }
+
+ /**
+ * Shows the schedules activity to resolve the one time recording conflict.
+ */
+ public static void startSchedulesActivityForOneTimeRecordingConflict(Context context,
+ List<ScheduledRecording> conflicts) {
+ startSchedulesActivity(context, getEarliestScheduledRecording(conflicts));
+ }
+
+ /**
+ * Shows the schedules activity with full schedule.
+ */
+ public static void startSchedulesActivity(Context context, ScheduledRecording
+ focusedScheduledRecording) {
+ Intent intent = new Intent(context, DvrSchedulesActivity.class);
+ intent.putExtra(DvrSchedulesActivity.KEY_SCHEDULES_TYPE,
+ DvrSchedulesActivity.TYPE_FULL_SCHEDULE);
+ if (focusedScheduledRecording != null) {
+ intent.putExtra(DvrSchedulesFragment.SCHEDULES_KEY_SCHEDULED_RECORDING,
+ focusedScheduledRecording);
+ }
+ context.startActivity(intent);
+ }
+
+ /**
+ * Shows the schedules activity for series recording.
+ */
+ public static void startSchedulesActivityForSeries(Context context,
+ SeriesRecording seriesRecording) {
+ Intent intent = new Intent(context, DvrSchedulesActivity.class);
+ intent.putExtra(DvrSchedulesActivity.KEY_SCHEDULES_TYPE,
+ DvrSchedulesActivity.TYPE_SERIES_SCHEDULE);
+ intent.putExtra(DvrSeriesSchedulesFragment.SERIES_SCHEDULES_KEY_SERIES_RECORDING,
+ seriesRecording);
+ context.startActivity(intent);
+ }
+
+ /**
+ * Shows the series settings activity.
+ *
+ * @param programs list of programs which belong to the series.
+ */
+ public static void startSeriesSettingsActivity(Context context, long seriesRecordingId,
+ @Nullable List<Program> programs, boolean removeEmptySeriesSchedule,
+ boolean isWindowTranslucent, boolean showViewScheduleOptionInDialog,
+ Program currentProgram) {
+ SeriesRecording series = TvApplication.getSingletons(context).getDvrDataManager()
+ .getSeriesRecording(seriesRecordingId);
+ if (series == null) {
+ return;
+ }
+ if (programs != null) {
+ startSeriesSettingsActivityInternal(context, seriesRecordingId, programs,
+ removeEmptySeriesSchedule, isWindowTranslucent,
+ showViewScheduleOptionInDialog, currentProgram);
+ } else {
+ EpisodicProgramLoadTask episodicProgramLoadTask =
+ new EpisodicProgramLoadTask(context, series) {
+ @Override
+ protected void onPostExecute(List<Program> loadedPrograms) {
+ sProgressDialog.dismiss();
+ sProgressDialog = null;
+ startSeriesSettingsActivityInternal(context, seriesRecordingId,
+ loadedPrograms == null ? Collections.EMPTY_LIST : loadedPrograms,
+ removeEmptySeriesSchedule, isWindowTranslucent,
+ showViewScheduleOptionInDialog, currentProgram);
+ }
+ }.setLoadCurrentProgram(true)
+ .setLoadDisallowedProgram(true)
+ .setLoadScheduledEpisode(true)
+ .setIgnoreChannelOption(true);
+ sProgressDialog = ProgressDialog.show(context, null, context.getString(
+ R.string.dvr_series_progress_message_reading_programs), true, true,
+ new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialogInterface) {
+ episodicProgramLoadTask.cancel(true);
+ sProgressDialog = null;
+ }
+ });
+ episodicProgramLoadTask.execute();
+ }
+ }
+
+ private static void startSeriesSettingsActivityInternal(Context context, long seriesRecordingId,
+ @NonNull List<Program> programs, boolean removeEmptySeriesSchedule,
+ boolean isWindowTranslucent, boolean showViewScheduleOptionInDialog,
+ Program currentProgram) {
+ SoftPreconditions.checkState(programs != null,
+ TAG, "Start series settings activity but programs is null");
+ Intent intent = new Intent(context, DvrSeriesSettingsActivity.class);
+ intent.putExtra(DvrSeriesSettingsActivity.SERIES_RECORDING_ID, seriesRecordingId);
+ BigArguments.reset();
+ BigArguments.setArgument(DvrSeriesSettingsActivity.PROGRAM_LIST, programs);
+ intent.putExtra(DvrSeriesSettingsActivity.REMOVE_EMPTY_SERIES_RECORDING,
+ removeEmptySeriesSchedule);
+ intent.putExtra(DvrSeriesSettingsActivity.IS_WINDOW_TRANSLUCENT, isWindowTranslucent);
+ intent.putExtra(DvrSeriesSettingsActivity.SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG,
+ showViewScheduleOptionInDialog);
+ intent.putExtra(DvrSeriesSettingsActivity.CURRENT_PROGRAM, currentProgram);
+ context.startActivity(intent);
+ }
+
+ /**
+ * Shows "series recording scheduled" dialog activity.
+ */
+ public static void StartSeriesScheduledDialogActivity(Context context,
+ SeriesRecording seriesRecording, boolean showViewScheduleOptionInDialog,
+ List<Program> programs) {
+ if (seriesRecording == null) {
+ return;
+ }
+ Intent intent = new Intent(context, DvrSeriesScheduledDialogActivity.class);
+ intent.putExtra(DvrSeriesScheduledDialogActivity.SERIES_RECORDING_ID,
+ seriesRecording.getId());
+ intent.putExtra(DvrSeriesScheduledDialogActivity.SHOW_VIEW_SCHEDULE_OPTION,
+ showViewScheduleOptionInDialog);
+ BigArguments.reset();
+ BigArguments.setArgument(DvrSeriesScheduledFragment.SERIES_SCHEDULED_KEY_PROGRAMS,
+ programs);
+ context.startActivity(intent);
+ }
+
+ /**
+ * Shows the details activity for the DVR items. The type of DVR items may be
+ * {@link ScheduledRecording}, {@link RecordedProgram}, or {@link SeriesRecording}.
+ */
+ public static void startDetailsActivity(Activity activity, Object dvrItem,
+ @Nullable ImageView imageView, boolean hideViewSchedule) {
+ if (dvrItem == null) {
+ return;
+ }
+ Intent intent = new Intent(activity, DvrDetailsActivity.class);
+ long recordingId;
+ int viewType;
+ if (dvrItem instanceof ScheduledRecording) {
+ ScheduledRecording schedule = (ScheduledRecording) dvrItem;
+ recordingId = schedule.getId();
+ if (schedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED) {
+ viewType = DvrDetailsActivity.SCHEDULED_RECORDING_VIEW;
+ } else if (schedule.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS) {
+ viewType = DvrDetailsActivity.CURRENT_RECORDING_VIEW;
+ } else {
+ return;
+ }
+ } else if (dvrItem instanceof RecordedProgram) {
+ recordingId = ((RecordedProgram) dvrItem).getId();
+ viewType = DvrDetailsActivity.RECORDED_PROGRAM_VIEW;
+ } else if (dvrItem instanceof SeriesRecording) {
+ recordingId = ((SeriesRecording) dvrItem).getId();
+ viewType = DvrDetailsActivity.SERIES_RECORDING_VIEW;
+ } else {
+ return;
+ }
+ intent.putExtra(DvrDetailsActivity.RECORDING_ID, recordingId);
+ intent.putExtra(DvrDetailsActivity.DETAILS_VIEW_TYPE, viewType);
+ intent.putExtra(DvrDetailsActivity.HIDE_VIEW_SCHEDULE, hideViewSchedule);
+ Bundle bundle = null;
+ if (imageView != null) {
+ bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, imageView,
+ DvrDetailsActivity.SHARED_ELEMENT_NAME).toBundle();
+ }
+ activity.startActivity(intent, bundle);
+ }
+
+ /**
+ * Shows the cancel all dialog for series schedules list.
+ */
+ public static void showCancelAllSeriesRecordingDialog(DvrSchedulesActivity activity,
+ SeriesRecording seriesRecording) {
+ DvrStopSeriesRecordingDialogFragment dvrStopSeriesRecordingDialogFragment =
+ new DvrStopSeriesRecordingDialogFragment();
+ Bundle arguments = new Bundle();
+ arguments.putParcelable(DvrStopSeriesRecordingFragment.KEY_SERIES_RECORDING,
+ seriesRecording);
+ dvrStopSeriesRecordingDialogFragment.setArguments(arguments);
+ dvrStopSeriesRecordingDialogFragment.show(activity.getFragmentManager(),
+ DvrStopSeriesRecordingDialogFragment.DIALOG_TAG);
+ }
+
+ /**
+ * Shows the series deletion activity.
+ */
+ public static void startSeriesDeletionActivity(Context context, long seriesRecordingId) {
+ Intent intent = new Intent(context, DvrSeriesDeletionActivity.class);
+ intent.putExtra(DvrSeriesDeletionActivity.SERIES_RECORDING_ID, seriesRecordingId);
+ context.startActivity(intent);
+ }
+
+ public static void showAddScheduleToast(Context context,
+ String title, long startTimeMs, long endTimeMs) {
+ String msg = (startTimeMs > System.currentTimeMillis()) ?
+ context.getString(R.string.dvr_msg_program_scheduled, title)
+ : context.getString(R.string.dvr_msg_current_program_scheduled, title,
+ Utils.toTimeString(endTimeMs, false));
+ Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+ }
+
+ /**
+ * Returns the styled schedule's title with its season and episode number.
+ */
+ public static CharSequence getStyledTitleWithEpisodeNumber(Context context,
+ ScheduledRecording schedule, int episodeNumberStyleResId) {
+ return getStyledTitleWithEpisodeNumber(context, schedule.getProgramTitle(),
+ schedule.getSeasonNumber(), schedule.getEpisodeNumber(), episodeNumberStyleResId);
+ }
+
+ /**
+ * Returns the styled program's title with its season and episode number.
+ */
+ public static CharSequence getStyledTitleWithEpisodeNumber(Context context,
+ BaseProgram program, int episodeNumberStyleResId) {
+ return getStyledTitleWithEpisodeNumber(context, program.getTitle(),
+ program.getSeasonNumber(), program.getEpisodeNumber(), episodeNumberStyleResId);
+ }
+
+ @NonNull
+ public static CharSequence getStyledTitleWithEpisodeNumber(Context context, String title,
+ String seasonNumber, String episodeNumber, int episodeNumberStyleResId) {
+ if (TextUtils.isEmpty(title)) {
+ return "";
+ }
+ SpannableStringBuilder builder;
+ if (TextUtils.isEmpty(seasonNumber) || seasonNumber.equals("0")) {
+ builder = TextUtils.isEmpty(episodeNumber) ? new SpannableStringBuilder(title) :
+ new SpannableStringBuilder(Html.fromHtml(
+ context.getString(R.string.program_title_with_episode_number_no_season,
+ title, episodeNumber)));
+ } else {
+ builder = new SpannableStringBuilder(Html.fromHtml(
+ context.getString(R.string.program_title_with_episode_number,
+ title, seasonNumber, episodeNumber)));
+ }
+ Object[] spans = builder.getSpans(0, builder.length(), Object.class);
+ if (spans.length > 0) {
+ if (episodeNumberStyleResId != 0) {
+ builder.setSpan(new TextAppearanceSpan(context, episodeNumberStyleResId),
+ builder.getSpanStart(spans[0]), builder.getSpanEnd(spans[0]),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ builder.removeSpan(spans[0]);
+ }
+ return new SpannableString(builder);
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/FadeBackground.java b/src/com/android/tv/dvr/ui/FadeBackground.java
new file mode 100644
index 00000000..4f06ebcf
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/FadeBackground.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.transition.Transition;
+import android.transition.TransitionValues;
+import android.transition.Visibility;
+import android.util.AttributeSet;
+import android.view.ViewGroup;
+
+import com.android.tv.R;
+
+/**
+ * This transition fades in/out of the background of the view by changing the background color.
+ */
+public class FadeBackground extends Transition {
+ private final int mMode;
+
+ public FadeBackground(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FadeBackground);
+ mMode = a.getInt(R.styleable.FadeBackground_fadingMode, Visibility.MODE_IN);
+ a.recycle();
+ }
+
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) { }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) { }
+
+ @Override
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return null;
+ }
+ Drawable background = endValues.view.getBackground();
+ if (background instanceof ColorDrawable) {
+ int color = ((ColorDrawable) background).getColor();
+ int transparentColor = Color.argb(0, Color.red(color), Color.green(color),
+ Color.blue(color));
+ return mMode == Visibility.MODE_OUT
+ ? ObjectAnimator.ofArgb(background, "color", transparentColor)
+ : ObjectAnimator.ofArgb(background, "color", transparentColor, color);
+ }
+ return null;
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/FullScheduleCardHolder.java b/src/com/android/tv/dvr/ui/FullScheduleCardHolder.java
deleted file mode 100644
index d4d4d8ab..00000000
--- a/src/com/android/tv/dvr/ui/FullScheduleCardHolder.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-/**
- * Special object for schedule preview;
- */
-final class FullScheduleCardHolder {
- /**
- * Full schedule card holder.
- */
- static final FullScheduleCardHolder FULL_SCHEDULE_CARD_HOLDER = new FullScheduleCardHolder();
-
- private FullScheduleCardHolder() { }
-}
diff --git a/src/com/android/tv/dvr/ui/FullSchedulesCardPresenter.java b/src/com/android/tv/dvr/ui/FullSchedulesCardPresenter.java
deleted file mode 100644
index 7dd85f45..00000000
--- a/src/com/android/tv/dvr/ui/FullSchedulesCardPresenter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.content.Context;
-import android.support.v17.leanback.widget.Presenter;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.util.Utils;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Presents a {@link ScheduledRecording} in the {@link DvrBrowseFragment}.
- */
-public class FullSchedulesCardPresenter extends Presenter {
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent) {
- Context context = parent.getContext();
- RecordingCardView view = new RecordingCardView(context);
- return new ScheduledRecordingViewHolder(view);
- }
-
- @Override
- public void onBindViewHolder(ViewHolder baseHolder, Object o) {
- final ScheduledRecordingViewHolder viewHolder = (ScheduledRecordingViewHolder) baseHolder;
- final RecordingCardView cardView = (RecordingCardView) viewHolder.view;
- final Context context = viewHolder.view.getContext();
-
- cardView.setImage(context.getDrawable(R.drawable.dvr_full_schedule));
- cardView.setTitle(context.getString(R.string.dvr_full_schedule_card_view_title));
- List<ScheduledRecording> scheduledRecordings = TvApplication.getSingletons(context)
- .getDvrDataManager().getAvailableScheduledRecordings();
- int fullDays = 0;
- if (!scheduledRecordings.isEmpty()) {
- fullDays = Utils.computeDateDifference(System.currentTimeMillis(),
- Collections.max(scheduledRecordings, ScheduledRecording.START_TIME_COMPARATOR)
- .getStartTimeMs()) + 1;
- }
- cardView.setContent(context.getResources().getQuantityString(
- R.plurals.dvr_full_schedule_card_view_content, fullDays, fullDays), null);
-
- View.OnClickListener clickListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- DvrUiHelper.startSchedulesActivity(context, null);
- }
- };
- baseHolder.view.setOnClickListener(clickListener);
- }
-
- @Override
- public void onUnbindViewHolder(ViewHolder baseHolder) {
- ScheduledRecordingViewHolder viewHolder = (ScheduledRecordingViewHolder) baseHolder;
- final RecordingCardView cardView = (RecordingCardView) viewHolder.view;
- cardView.reset();
- }
-
- private static final class ScheduledRecordingViewHolder extends ViewHolder {
- ScheduledRecordingViewHolder(RecordingCardView view) {
- super(view);
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/HalfSizedDialogFragment.java b/src/com/android/tv/dvr/ui/HalfSizedDialogFragment.java
deleted file mode 100644
index d320816e..00000000
--- a/src/com/android/tv/dvr/ui/HalfSizedDialogFragment.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.tv.R;
-import com.android.tv.dialog.SafeDismissDialogFragment;
-
-import java.util.concurrent.TimeUnit;
-
-public class HalfSizedDialogFragment extends SafeDismissDialogFragment {
- public static final String DIALOG_TAG = HalfSizedDialogFragment.class.getSimpleName();
- public static final String TRACKER_LABEL = "Half sized dialog";
-
- private static final long AUTO_DISMISS_TIME_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30);
-
- private OnActionClickListener mOnActionClickListener;
-
- private Handler mHandler = new Handler();
- private Runnable mAutoDismisser = new Runnable() {
- @Override
- public void run() {
- dismiss();
- }
- };
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- return inflater.inflate(R.layout.halfsized_dialog, container, false);
- }
-
- @Override
- public void onStart() {
- super.onStart();
- getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
- public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent keyEvent) {
- mHandler.removeCallbacks(mAutoDismisser);
- mHandler.postDelayed(mAutoDismisser, AUTO_DISMISS_TIME_THRESHOLD_MS);
- return false;
- }
- });
- mHandler.postDelayed(mAutoDismisser, AUTO_DISMISS_TIME_THRESHOLD_MS);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- if (mOnActionClickListener != null) {
- // Dismisses the dialog to prevent the callback being forgotten during
- // fragment re-creating.
- dismiss();
- }
- }
-
- @Override
- public void onStop() {
- super.onStop();
- mHandler.removeCallbacks(mAutoDismisser);
- }
-
- @Override
- public int getTheme() {
- return R.style.Theme_TV_dialog_HalfSizedDialog;
- }
-
- @Override
- public String getTrackerLabel() {
- return TRACKER_LABEL;
- }
-
- /**
- * Sets {@link OnActionClickListener} for the dialog fragment. If listener is set, the dialog
- * will be automatically closed when it's paused to prevent the fragment being re-created by
- * the framework, which will result the listener being forgotten.
- */
- public void setOnActionClickListener(OnActionClickListener listener) {
- mOnActionClickListener = listener;
- }
-
- /**
- * Returns {@link OnActionClickListener} for sub-classes or any inner fragments.
- */
- protected OnActionClickListener getOnActionClickListener() {
- return mOnActionClickListener;
- }
-
- /**
- * An interface to provide callbacks for half-sized dialogs. Subclasses or inner fragments
- * should invoke {@link OnActionClickListener#onActionClick(long)} and provide the identifier
- * of the action user clicked.
- */
- public interface OnActionClickListener {
- void onActionClick(long actionId);
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/PrioritySettingsFragment.java b/src/com/android/tv/dvr/ui/PrioritySettingsFragment.java
deleted file mode 100644
index 158bd824..00000000
--- a/src/com/android/tv/dvr/ui/PrioritySettingsFragment.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.FragmentManager;
-import android.content.Context;
-import android.graphics.Typeface;
-import android.os.Bundle;
-import android.support.v17.leanback.app.GuidedStepFragment;
-import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
-import android.support.v17.leanback.widget.GuidedAction;
-import android.support.v17.leanback.widget.GuidedActionsStylist;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.SeriesRecording;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Fragment for DVR series recording settings.
- */
-public class PrioritySettingsFragment extends GuidedStepFragment {
- /**
- * Name of series recording id starting the fragment.
- * Type: Long
- */
- public static final String COME_FROM_SERIES_RECORDING_ID = "series_recording_id";
-
- private static final int ONE_TIME_RECORDING_ID = 0;
- // button action's IDs are negative.
- private static final long ACTION_ID_SAVE = -100L;
-
- private final List<SeriesRecording> mSeriesRecordings = new ArrayList<>();
-
- private SeriesRecording mSelectedRecording;
- private SeriesRecording mComeFromSeriesRecording;
- private float mSelectedActionElevation;
- private int mActionColor;
- private int mSelectedActionColor;
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- mSeriesRecordings.clear();
- mSeriesRecordings.add(new SeriesRecording.Builder()
- .setTitle(getString(R.string.dvr_priority_action_one_time_recording))
- .setPriority(Long.MAX_VALUE)
- .setId(ONE_TIME_RECORDING_ID)
- .build());
- DvrDataManager dvrDataManager = TvApplication.getSingletons(context).getDvrDataManager();
- long comeFromSeriesRecordingId =
- getArguments().getLong(COME_FROM_SERIES_RECORDING_ID, -1);
- for (SeriesRecording series : dvrDataManager.getSeriesRecordings()) {
- if (series.getState() == SeriesRecording.STATE_SERIES_NORMAL
- || series.getId() == comeFromSeriesRecordingId) {
- mSeriesRecordings.add(series);
- }
- }
- mSeriesRecordings.sort(SeriesRecording.PRIORITY_COMPARATOR);
- mComeFromSeriesRecording = dvrDataManager.getSeriesRecording(comeFromSeriesRecordingId);
- mSelectedActionElevation = getResources().getDimension(R.dimen.card_elevation_normal);
- mActionColor = getResources().getColor(R.color.dvr_guided_step_action_text_color, null);
- mSelectedActionColor =
- getResources().getColor(R.color.dvr_guided_step_action_text_color_selected, null);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- setSelectedActionPosition(mComeFromSeriesRecording == null ? 1
- : mSeriesRecordings.indexOf(mComeFromSeriesRecording));
- }
-
- @Override
- public Guidance onCreateGuidance(Bundle savedInstanceState) {
- String breadcrumb = mComeFromSeriesRecording == null ? null
- : mComeFromSeriesRecording.getTitle();
- return new Guidance(getString(R.string.dvr_priority_title),
- getString(R.string.dvr_priority_description), breadcrumb, null);
- }
-
- @Override
- public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- int position = 0;
- for (SeriesRecording seriesRecording : mSeriesRecordings) {
- actions.add(new GuidedAction.Builder(getActivity())
- .id(position++)
- .title(seriesRecording.getTitle())
- .build());
- }
- }
-
- @Override
- public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- actions.add(new GuidedAction.Builder(getActivity())
- .id(ACTION_ID_SAVE)
- .title(getString(R.string.dvr_priority_button_action_save))
- .build());
- actions.add(new GuidedAction.Builder(getActivity())
- .clickAction(GuidedAction.ACTION_ID_CANCEL)
- .build());
- }
-
- @Override
- public void onGuidedActionClicked(GuidedAction action) {
- long actionId = action.getId();
- if (actionId == ACTION_ID_SAVE) {
- DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
- int size = mSeriesRecordings.size();
- for (int i = 1; i < size; ++i) {
- long priority = DvrScheduleManager.suggestSeriesPriority(size - i);
- SeriesRecording seriesRecording = mSeriesRecordings.get(i);
- if (seriesRecording.getPriority() != priority) {
- dvrManager.updateSeriesRecording(SeriesRecording.buildFrom(seriesRecording)
- .setPriority(priority).build());
- }
- }
- FragmentManager fragmentManager = getFragmentManager();
- fragmentManager.popBackStack();
- } else if (actionId == GuidedAction.ACTION_ID_CANCEL) {
- FragmentManager fragmentManager = getFragmentManager();
- fragmentManager.popBackStack();
- } else if (mSelectedRecording == null) {
- mSelectedRecording = mSeriesRecordings.get((int) actionId);
- for (int i = 0; i < mSeriesRecordings.size(); ++i) {
- updateItem(i);
- }
- } else {
- mSelectedRecording = null;
- for (int i = 0; i < mSeriesRecordings.size(); ++i) {
- updateItem(i);
- }
- }
- }
-
- @Override
- public void onGuidedActionFocused(GuidedAction action) {
- super.onGuidedActionFocused(action);
- if (mSelectedRecording == null) {
- return;
- }
- if (action.getId() < 0) {
- int selectedPosition = mSeriesRecordings.indexOf(mSelectedRecording);
- mSelectedRecording = null;
- for (int i = 0; i < mSeriesRecordings.size(); ++i) {
- updateItem(i);
- }
- return;
- }
- int position = (int) action.getId();
- int previousPosition = mSeriesRecordings.indexOf(mSelectedRecording);
- mSeriesRecordings.remove(mSelectedRecording);
- mSeriesRecordings.add(position, mSelectedRecording);
- updateItem(previousPosition);
- updateItem(position);
- notifyActionChanged(previousPosition);
- notifyActionChanged(position);
- }
-
- @Override
- public GuidedActionsStylist onCreateButtonActionsStylist() {
- return new DvrGuidedActionsStylist(true);
- }
-
- @Override
- public GuidedActionsStylist onCreateActionsStylist() {
- return new DvrGuidedActionsStylist(false) {
- @Override
- public void onBindViewHolder(ViewHolder vh, GuidedAction action) {
- super.onBindViewHolder(vh, action);
- updateItem(vh.itemView, (int) action.getId());
- }
-
- @Override
- public int onProvideItemLayoutId() {
- return R.layout.priority_settings_action_item;
- }
- };
- }
-
- private void updateItem(int position) {
- View itemView = getActionItemView(position);
- if (itemView == null) {
- return;
- }
- updateItem(itemView, position);
- }
-
- private void updateItem(View itemView, int position) {
- GuidedAction action = getActions().get(position);
- action.setTitle(mSeriesRecordings.get(position).getTitle());
- boolean selected = mSelectedRecording != null
- && mSeriesRecordings.indexOf(mSelectedRecording) == position;
- TextView titleView = (TextView) itemView.findViewById(R.id.guidedactions_item_title);
- ImageView imageView = (ImageView) itemView.findViewById(R.id.guidedactions_item_tail_image);
- if (position == 0) {
- // one-time recording
- itemView.setBackgroundResource(R.drawable.setup_selector_background);
- imageView.setVisibility(View.GONE);
- itemView.setFocusable(false);
- itemView.setElevation(0);
- // strings.xml <i> tag doesn't work.
- titleView.setTypeface(titleView.getTypeface(), Typeface.ITALIC);
- } else if (mSelectedRecording == null) {
- titleView.setTextColor(mActionColor);
- itemView.setBackgroundResource(R.drawable.setup_selector_background);
- imageView.setImageResource(R.drawable.ic_draggable_white);
- imageView.setVisibility(View.VISIBLE);
- itemView.setFocusable(true);
- itemView.setElevation(0);
- titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL);
- } else if (selected) {
- titleView.setTextColor(mSelectedActionColor);
- itemView.setBackgroundResource(R.drawable.priority_settings_action_item_selected);
- imageView.setImageResource(R.drawable.ic_dragging_grey);
- imageView.setVisibility(View.VISIBLE);
- itemView.setFocusable(true);
- itemView.setElevation(mSelectedActionElevation);
- titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL);
- } else {
- titleView.setTextColor(mActionColor);
- itemView.setBackgroundResource(R.drawable.setup_selector_background);
- imageView.setVisibility(View.INVISIBLE);
- itemView.setFocusable(true);
- itemView.setElevation(0);
- titleView.setTypeface(titleView.getTypeface(), Typeface.NORMAL);
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/RecordedProgramDetailsFragment.java b/src/com/android/tv/dvr/ui/RecordedProgramDetailsFragment.java
deleted file mode 100644
index e698b8a2..00000000
--- a/src/com/android/tv/dvr/ui/RecordedProgramDetailsFragment.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.content.res.Resources;
-import android.media.tv.TvInputManager;
-import android.os.Bundle;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.text.TextUtils;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.Channel;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrWatchedPositionManager;
-import com.android.tv.dvr.RecordedProgram;
-
-/**
- * {@link DetailsFragment} for recorded program in DVR.
- */
-public class RecordedProgramDetailsFragment extends DvrDetailsFragment
- implements DvrDataManager.RecordedProgramListener {
- private static final int ACTION_RESUME_PLAYING = 1;
- private static final int ACTION_PLAY_FROM_BEGINNING = 2;
- private static final int ACTION_DELETE_RECORDING = 3;
-
- private DvrWatchedPositionManager mDvrWatchedPositionManager;
-
- private RecordedProgram mRecordedProgram;
- private DetailsContent mDetailsContent;
- private boolean mPaused;
- private DvrDataManager mDvrDataManager;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- mDvrDataManager = TvApplication.getSingletons(getContext()).getDvrDataManager();
- mDvrDataManager.addRecordedProgramListener(this);
- super.onCreate(savedInstanceState);
- }
-
- @Override
- public void onCreateInternal() {
- mDvrWatchedPositionManager = TvApplication.getSingletons(getActivity())
- .getDvrWatchedPositionManager();
- setDetailsOverviewRow(mDetailsContent);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (mPaused) {
- updateActions();
- mPaused = false;
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mPaused = true;
- }
-
- @Override
- public void onDestroy() {
- mDvrDataManager.removeRecordedProgramListener(this);
- super.onDestroy();
- }
-
- @Override
- protected boolean onLoadRecordingDetails(Bundle args) {
- long recordedProgramId = args.getLong(DvrDetailsActivity.RECORDING_ID);
- mRecordedProgram = mDvrDataManager.getRecordedProgram(recordedProgramId);
- if (mRecordedProgram == null) {
- // notify super class to end activity before initializing anything
- return false;
- }
- mDetailsContent = createDetailsContent();
- return true;
- }
-
- private DetailsContent createDetailsContent() {
- Channel channel = TvApplication.getSingletons(getContext()).getChannelDataManager()
- .getChannel(mRecordedProgram.getChannelId());
- String description = TextUtils.isEmpty(mRecordedProgram.getLongDescription())
- ? mRecordedProgram.getDescription() : mRecordedProgram.getLongDescription();
- return new DetailsContent.Builder()
- .setTitle(getTitleFromProgram(mRecordedProgram, channel))
- .setStartTimeUtcMillis(mRecordedProgram.getStartTimeUtcMillis())
- .setEndTimeUtcMillis(mRecordedProgram.getEndTimeUtcMillis())
- .setDescription(description)
- .setImageUris(mRecordedProgram, channel)
- .build();
- }
-
- @Override
- protected SparseArrayObjectAdapter onCreateActionsAdapter() {
- SparseArrayObjectAdapter adapter =
- new SparseArrayObjectAdapter(new ActionPresenterSelector());
- Resources res = getResources();
- if (mDvrWatchedPositionManager.getWatchedStatus(mRecordedProgram)
- == DvrWatchedPositionManager.DVR_WATCHED_STATUS_WATCHING) {
- adapter.set(ACTION_RESUME_PLAYING, new Action(ACTION_RESUME_PLAYING,
- res.getString(R.string.dvr_detail_resume_play), null,
- res.getDrawable(R.drawable.lb_ic_play)));
- adapter.set(ACTION_PLAY_FROM_BEGINNING, new Action(ACTION_PLAY_FROM_BEGINNING,
- res.getString(R.string.dvr_detail_play_from_beginning), null,
- res.getDrawable(R.drawable.lb_ic_replay)));
- } else {
- adapter.set(ACTION_PLAY_FROM_BEGINNING, new Action(ACTION_PLAY_FROM_BEGINNING,
- res.getString(R.string.dvr_detail_watch), null,
- res.getDrawable(R.drawable.lb_ic_play)));
- }
- adapter.set(ACTION_DELETE_RECORDING, new Action(ACTION_DELETE_RECORDING,
- res.getString(R.string.dvr_detail_delete), null,
- res.getDrawable(R.drawable.ic_delete_32dp)));
- return adapter;
- }
-
- @Override
- protected OnActionClickedListener onCreateOnActionClickedListener() {
- return new OnActionClickedListener() {
- @Override
- public void onActionClicked(Action action) {
- if (action.getId() == ACTION_PLAY_FROM_BEGINNING) {
- startPlayback(mRecordedProgram, TvInputManager.TIME_SHIFT_INVALID_TIME);
- } else if (action.getId() == ACTION_RESUME_PLAYING) {
- startPlayback(mRecordedProgram, mDvrWatchedPositionManager
- .getWatchedPosition(mRecordedProgram.getId()));
- } else if (action.getId() == ACTION_DELETE_RECORDING) {
- DvrManager dvrManager = TvApplication
- .getSingletons(getActivity()).getDvrManager();
- dvrManager.removeRecordedProgram(mRecordedProgram);
- getActivity().finish();
- }
- }
- };
- }
-
- @Override
- public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) { }
-
- @Override
- public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) { }
-
- @Override
- public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) {
- for (RecordedProgram recordedProgram : recordedPrograms) {
- if (recordedProgram.getId() == mRecordedProgram.getId()) {
- getActivity().finish();
- }
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/RecordedProgramPresenter.java b/src/com/android/tv/dvr/ui/RecordedProgramPresenter.java
deleted file mode 100644
index 1bf34310..00000000
--- a/src/com/android/tv/dvr/ui/RecordedProgramPresenter.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.content.Context;
-import android.media.tv.TvContract;
-import android.media.tv.TvInputManager;
-import android.net.Uri;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.text.style.TextAppearanceSpan;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.dvr.RecordedProgram;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dvr.DvrWatchedPositionManager;
-import com.android.tv.dvr.DvrWatchedPositionManager.WatchedPositionChangedListener;
-import com.android.tv.util.Utils;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Presents a {@link RecordedProgram} in the {@link DvrBrowseFragment}.
- */
-public class RecordedProgramPresenter extends DvrItemPresenter {
- private final ChannelDataManager mChannelDataManager;
- private final DvrWatchedPositionManager mDvrWatchedPositionManager;
- private final Context mContext;
- private String mTodayString;
- private String mYesterdayString;
- private final int mProgressBarColor;
- private final boolean mShowEpisodeTitle;
-
- private static final class RecordedProgramViewHolder extends ViewHolder
- implements WatchedPositionChangedListener {
- private RecordedProgram mProgram;
-
- RecordedProgramViewHolder(RecordingCardView view, int progressColor) {
- super(view);
- view.setProgressBarColor(progressColor);
- }
-
- private void setProgram(RecordedProgram program) {
- mProgram = program;
- }
-
- private void setProgressBar(long watchedPositionMs) {
- ((RecordingCardView) view).setProgressBar(
- (watchedPositionMs == TvInputManager.TIME_SHIFT_INVALID_TIME) ? null
- : Math.min(100, (int) (100.0f * watchedPositionMs
- / mProgram.getDurationMillis())));
- }
-
- @Override
- public void onWatchedPositionChanged(long programId, long positionMs) {
- if (programId == mProgram.getId()) {
- setProgressBar(positionMs);
- }
- }
- }
-
- public RecordedProgramPresenter(Context context, boolean showEpisodeTitle) {
- mContext = context;
- mChannelDataManager = TvApplication.getSingletons(context).getChannelDataManager();
- mTodayString = context.getString(R.string.dvr_date_today);
- mYesterdayString = context.getString(R.string.dvr_date_yesterday);
- mDvrWatchedPositionManager =
- TvApplication.getSingletons(context).getDvrWatchedPositionManager();
- mProgressBarColor = context.getResources()
- .getColor(R.color.play_controls_progress_bar_watched);
- mShowEpisodeTitle = showEpisodeTitle;
- }
-
- public RecordedProgramPresenter(Context context) {
- this(context, false);
- }
-
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent) {
- RecordingCardView view = new RecordingCardView(mContext);
- return new RecordedProgramViewHolder(view, mProgressBarColor);
- }
-
- @Override
- public void onBindViewHolder(ViewHolder viewHolder, Object o) {
- final RecordedProgram program = (RecordedProgram) o;
- final RecordingCardView cardView = (RecordingCardView) viewHolder.view;
- Channel channel = mChannelDataManager.getChannel(program.getChannelId());
- String titleString = mShowEpisodeTitle ? program.getEpisodeDisplayTitle(mContext)
- : program.getTitleWithEpisodeNumber(mContext);
- SpannableString title = titleString == null ? null : new SpannableString(titleString);
- if (TextUtils.isEmpty(title)) {
- title = new SpannableString(channel != null ? channel.getDisplayName()
- : mContext.getResources().getString(R.string.no_program_information));
- } else if (!mShowEpisodeTitle) {
- // TODO: Some translation may add delimiters in-between program titles, we should use
- // a more robust way to get the span range.
- String programTitle = program.getTitle();
- title.setSpan(new TextAppearanceSpan(mContext,
- R.style.text_appearance_card_view_episode_number), programTitle == null ? 0
- : programTitle.length(), title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- cardView.setTitle(title);
- String imageUri = null;
- boolean isChannelLogo = false;
- if (program.getPosterArtUri() != null) {
- imageUri = program.getPosterArtUri();
- } else if (program.getThumbnailUri() != null) {
- imageUri = program.getThumbnailUri();
- } else if (channel != null) {
- imageUri = TvContract.buildChannelLogoUri(channel.getId()).toString();
- isChannelLogo = true;
- }
- cardView.setImageUri(imageUri, isChannelLogo);
- int durationMinutes =
- Math.max(1, (int) TimeUnit.MILLISECONDS.toMinutes(program.getDurationMillis()));
- String durationString = getContext().getResources().getQuantityString(
- R.plurals.dvr_program_duration, durationMinutes, durationMinutes);
- cardView.setContent(getDescription(program), durationString);
- if (viewHolder instanceof RecordedProgramViewHolder) {
- RecordedProgramViewHolder cardViewHolder = (RecordedProgramViewHolder) viewHolder;
- cardViewHolder.setProgram(program);
- mDvrWatchedPositionManager.addListener(cardViewHolder, program.getId());
- cardViewHolder
- .setProgressBar(mDvrWatchedPositionManager.getWatchedPosition(program.getId()));
- }
- super.onBindViewHolder(viewHolder, o);
- }
-
- @Override
- public void onUnbindViewHolder(ViewHolder viewHolder) {
- if (viewHolder instanceof RecordedProgramViewHolder) {
- mDvrWatchedPositionManager.removeListener((RecordedProgramViewHolder) viewHolder,
- ((RecordedProgramViewHolder) viewHolder).mProgram.getId());
- }
- ((RecordingCardView) viewHolder.view).reset();
- super.onUnbindViewHolder(viewHolder);
- }
-
- /**
- * Returns description would be used in its card view.
- */
- protected String getDescription(RecordedProgram recording) {
- int dateDifference = Utils.computeDateDifference(recording.getStartTimeUtcMillis(),
- System.currentTimeMillis());
- if (dateDifference == 0) {
- return mTodayString;
- } else if (dateDifference == 1) {
- return mYesterdayString;
- } else {
- return Utils.getDurationString(mContext, recording.getStartTimeUtcMillis(),
- recording.getStartTimeUtcMillis(), false, true, false, 0);
- }
- }
-
- /**
- * Returns context.
- */
- protected Context getContext() {
- return mContext;
- }
-}
diff --git a/src/com/android/tv/dvr/ui/RecordingCardView.java b/src/com/android/tv/dvr/ui/RecordingCardView.java
deleted file mode 100644
index 51c3b03b..00000000
--- a/src/com/android/tv/dvr/ui/RecordingCardView.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.support.annotation.Nullable;
-import android.support.v17.leanback.widget.BaseCardView;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.android.tv.R;
-import com.android.tv.dvr.RecordedProgram;
-import com.android.tv.util.ImageLoader;
-
-/**
- * A CardView for displaying info about a {@link com.android.tv.dvr.ScheduledRecording} or
- * {@link RecordedProgram} or
- * {@link com.android.tv.dvr.SeriesRecording}.
- */
-class RecordingCardView extends BaseCardView {
- private final ImageView mImageView;
- private final int mImageWidth;
- private final int mImageHeight;
- private String mImageUri;
- private final TextView mTitleView;
- private final TextView mMajorContentView;
- private final TextView mMinorContentView;
- private final ProgressBar mProgressBar;
- private final View mAffiliatedIconContainer;
- private final ImageView mAffiliatedIcon;
- private final Drawable mDefaultImage;
-
- RecordingCardView(Context context) {
- this(context,
- context.getResources().getDimensionPixelSize(R.dimen.dvr_card_image_layout_width),
- context.getResources().getDimensionPixelSize(R.dimen.dvr_card_image_layout_height));
- }
-
- RecordingCardView(Context context, int imageWidth, int imageHeight) {
- super(context);
- //TODO(dvr): move these to the layout XML.
- setCardType(BaseCardView.CARD_TYPE_INFO_UNDER_WITH_EXTRA);
- setInfoVisibility(BaseCardView.CARD_REGION_VISIBLE_ALWAYS);
- setFocusable(true);
- setFocusableInTouchMode(true);
- mDefaultImage = getResources().getDrawable(R.drawable.dvr_default_poster, null);
-
- LayoutInflater inflater = LayoutInflater.from(getContext());
- inflater.inflate(R.layout.dvr_recording_card_view, this);
- mImageView = (ImageView) findViewById(R.id.image);
- mImageWidth = imageWidth;
- mImageHeight = imageHeight;
- mProgressBar = (ProgressBar) findViewById(R.id.recording_progress);
- mAffiliatedIconContainer = findViewById(R.id.affiliated_icon_container);
- mAffiliatedIcon = (ImageView) findViewById(R.id.affiliated_icon);
- mTitleView = (TextView) findViewById(R.id.title);
- mMajorContentView = (TextView) findViewById(R.id.content_major);
- mMinorContentView = (TextView) findViewById(R.id.content_minor);
- }
-
- void setTitle(CharSequence title) {
- mTitleView.setText(title);
- }
-
- void setContent(CharSequence majorContent, CharSequence minorContent) {
- if (!TextUtils.isEmpty(majorContent)) {
- mMajorContentView.setText(majorContent);
- mMajorContentView.setVisibility(View.VISIBLE);
- } else {
- mMajorContentView.setVisibility(View.GONE);
- }
- if (!TextUtils.isEmpty(minorContent)) {
- mMinorContentView.setText(minorContent);
- mMinorContentView.setVisibility(View.VISIBLE);
- } else {
- mMinorContentView.setVisibility(View.GONE);
- }
- }
-
- /**
- * Sets progress bar. If progress is {@code null}, hides progress bar.
- */
- void setProgressBar(Integer progress) {
- if (progress == null) {
- mProgressBar.setVisibility(View.GONE);
- } else {
- mProgressBar.setProgress(progress);
- mProgressBar.setVisibility(View.VISIBLE);
- }
- }
-
- /**
- * Sets the color of progress bar.
- */
- void setProgressBarColor(int color) {
- mProgressBar.getProgressDrawable().setTint(color);
- }
-
- void setImageUri(String uri, boolean isChannelLogo) {
- if (isChannelLogo) {
- mImageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
- } else {
- mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
- }
- mImageUri = uri;
- if (TextUtils.isEmpty(uri)) {
- mImageView.setImageDrawable(mDefaultImage);
- } else {
- ImageLoader.loadBitmap(getContext(), uri, mImageWidth, mImageHeight,
- new RecordingCardImageLoaderCallback(this, uri));
- }
- }
-
- /**
- * Set image to card view.
- */
- public void setImage(Drawable image) {
- if (image != null) {
- mImageView.setImageDrawable(image);
- }
- }
-
- public void setAffiliatedIcon(int imageResId) {
- if (imageResId > 0) {
- mAffiliatedIconContainer.setVisibility(View.VISIBLE);
- mAffiliatedIcon.setImageResource(imageResId);
- } else {
- mAffiliatedIconContainer.setVisibility(View.INVISIBLE);
- }
- }
-
- /**
- * Returns image view.
- */
- public ImageView getImageView() {
- return mImageView;
- }
-
- private static class RecordingCardImageLoaderCallback
- extends ImageLoader.ImageLoaderCallback<RecordingCardView> {
- private final String mUri;
-
- RecordingCardImageLoaderCallback(RecordingCardView referent, String uri) {
- super(referent);
- mUri = uri;
- }
-
- @Override
- public void onBitmapLoaded(RecordingCardView view, @Nullable Bitmap bitmap) {
- if (bitmap == null || !mUri.equals(view.mImageUri)) {
- view.mImageView.setImageDrawable(view.mDefaultImage);
- } else {
- view.mImageView.setImageDrawable(new BitmapDrawable(view.getResources(), bitmap));
- }
- }
- }
-
- public void reset() {
- mTitleView.setText(null);
- setContent(null, null);
- mImageView.setImageDrawable(mDefaultImage);
- }
-}
diff --git a/src/com/android/tv/dvr/ui/RecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/RecordingDetailsFragment.java
deleted file mode 100644
index 4e19ec3f..00000000
--- a/src/com/android/tv/dvr/ui/RecordingDetailsFragment.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.os.Bundle;
-import android.support.v17.leanback.app.DetailsFragment;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.text.style.TextAppearanceSpan;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.Channel;
-import com.android.tv.dvr.ScheduledRecording;
-
-/**
- * {@link DetailsFragment} for recordings in DVR.
- */
-abstract class RecordingDetailsFragment extends DvrDetailsFragment {
- private ScheduledRecording mRecording;
-
- @Override
- protected void onCreateInternal() {
- setDetailsOverviewRow(createDetailsContent());
- }
-
- @Override
- protected boolean onLoadRecordingDetails(Bundle args) {
- long scheduledRecordingId = args.getLong(DvrDetailsActivity.RECORDING_ID);
- mRecording = TvApplication.getSingletons(getContext()).getDvrDataManager()
- .getScheduledRecording(scheduledRecordingId);
- return mRecording != null;
- }
-
- /**
- * Returns {@link ScheduledRecording} for the current fragment.
- */
- public ScheduledRecording getRecording() {
- return mRecording;
- }
-
- private DetailsContent createDetailsContent() {
- Channel channel = TvApplication.getSingletons(getContext()).getChannelDataManager()
- .getChannel(mRecording.getChannelId());
- SpannableString title = mRecording.getProgramTitleWithEpisodeNumber(getContext()) == null ?
- null : new SpannableString(mRecording
- .getProgramTitleWithEpisodeNumber(getContext()));
- if (TextUtils.isEmpty(title)) {
- title = new SpannableString(channel != null ? channel.getDisplayName()
- : getContext().getResources().getString(
- R.string.no_program_information));
- } else {
- String programTitle = mRecording.getProgramTitle();
- title.setSpan(new TextAppearanceSpan(getContext(),
- R.style.text_appearance_card_view_episode_number), programTitle == null ? 0
- : programTitle.length(), title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- String description = !TextUtils.isEmpty(mRecording.getProgramDescription()) ?
- mRecording.getProgramDescription() : mRecording.getProgramLongDescription();
- if (TextUtils.isEmpty(description)) {
- description = channel != null ? channel.getDescription() : null;
- }
- return new DetailsContent.Builder()
- .setTitle(title)
- .setStartTimeUtcMillis(mRecording.getStartTimeMs())
- .setEndTimeUtcMillis(mRecording.getEndTimeMs())
- .setDescription(description)
- .setImageUris(mRecording.getProgramPosterArtUri(),
- mRecording.getProgramThumbnailUri(), channel)
- .build();
- }
-}
diff --git a/src/com/android/tv/dvr/ui/ScheduledRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/ScheduledRecordingDetailsFragment.java
deleted file mode 100644
index 60816bb5..00000000
--- a/src/com/android/tv/dvr/ui/ScheduledRecordingDetailsFragment.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.text.TextUtils;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrUiHelper;
-
-/**
- * {@link RecordingDetailsFragment} for scheduled recording in DVR.
- */
-public class ScheduledRecordingDetailsFragment extends RecordingDetailsFragment {
- private static final int ACTION_VIEW_SCHEDULE = 1;
- private static final int ACTION_CANCEL = 2;
-
- private DvrManager mDvrManager;
- private Action mScheduleAction;
- private boolean mHideViewSchedule;
-
- @Override
- public void onCreate(Bundle savedInstance) {
- mDvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
- mHideViewSchedule = getArguments().getBoolean(DvrDetailsActivity.HIDE_VIEW_SCHEDULE);
- super.onCreate(savedInstance);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (mScheduleAction != null) {
- mScheduleAction.setIcon(getResources().getDrawable(getScheduleIconId()));
- }
- }
-
- @Override
- protected SparseArrayObjectAdapter onCreateActionsAdapter() {
- SparseArrayObjectAdapter adapter =
- new SparseArrayObjectAdapter(new ActionPresenterSelector());
- Resources res = getResources();
- if (!mHideViewSchedule) {
- mScheduleAction = new Action(ACTION_VIEW_SCHEDULE,
- res.getString(R.string.dvr_detail_view_schedule), null,
- res.getDrawable(getScheduleIconId()));
- adapter.set(ACTION_VIEW_SCHEDULE, mScheduleAction);
- }
- adapter.set(ACTION_CANCEL, new Action(ACTION_CANCEL,
- res.getString(R.string.epg_dvr_dialog_message_remove_recording_schedule), null,
- res.getDrawable(R.drawable.ic_dvr_cancel_32dp)));
- return adapter;
- }
-
- @Override
- protected OnActionClickedListener onCreateOnActionClickedListener() {
- return new OnActionClickedListener() {
- @Override
- public void onActionClicked(Action action) {
- long actionId = action.getId();
- if (actionId == ACTION_VIEW_SCHEDULE) {
- DvrUiHelper.startSchedulesActivity(getContext(), getRecording());
- } else if (actionId == ACTION_CANCEL) {
- mDvrManager.removeScheduledRecording(getRecording());
- getActivity().finish();
- }
- }
- };
- }
-
- private int getScheduleIconId() {
- if (mDvrManager.isConflicting(getRecording())) {
- return R.drawable.ic_warning_white_32dp;
- } else {
- return R.drawable.ic_schedule_32dp;
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/ScheduledRecordingPresenter.java b/src/com/android/tv/dvr/ui/ScheduledRecordingPresenter.java
deleted file mode 100644
index 5f447f13..00000000
--- a/src/com/android/tv/dvr/ui/ScheduledRecordingPresenter.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.content.Context;
-import android.media.tv.TvContract;
-import android.os.Handler;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.text.style.TextAppearanceSpan;
-import android.view.ViewGroup;
-
-import com.android.tv.ApplicationSingletons;
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.util.Utils;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Presents a {@link ScheduledRecording} in the {@link DvrBrowseFragment}.
- */
-public class ScheduledRecordingPresenter extends DvrItemPresenter {
- private static final long PROGRESS_UPDATE_INTERVAL_MS = TimeUnit.SECONDS.toMillis(5);
-
- private final ChannelDataManager mChannelDataManager;
- private final DvrManager mDvrManager;
- private final Context mContext;
- private final int mProgressBarColor;
-
- private static final class ScheduledRecordingViewHolder extends ViewHolder {
- private final Handler mHandler = new Handler();
- private ScheduledRecording mScheduledRecording;
- private final Runnable mProgressBarUpdater = new Runnable() {
- @Override
- public void run() {
- updateProgressBar();
- mHandler.postDelayed(this, PROGRESS_UPDATE_INTERVAL_MS);
- }
- };
-
- ScheduledRecordingViewHolder(RecordingCardView view, int progressBarColor) {
- super(view);
- view.setProgressBarColor(progressBarColor);
- }
-
- private void updateProgressBar() {
- if (mScheduledRecording == null) {
- return;
- }
- int recordingState = mScheduledRecording.getState();
- RecordingCardView cardView = (RecordingCardView) view;
- if (recordingState == ScheduledRecording.STATE_RECORDING_IN_PROGRESS) {
- cardView.setProgressBar(Math.max(0, Math.min((int) (100 *
- (System.currentTimeMillis() - mScheduledRecording.getStartTimeMs())
- / mScheduledRecording.getDuration()), 100)));
- } else if (recordingState == ScheduledRecording.STATE_RECORDING_FINISHED) {
- cardView.setProgressBar(100);
- } else {
- // Hides progress bar.
- cardView.setProgressBar(null);
- }
- }
-
- private void startUpdateProgressBar() {
- mHandler.post(mProgressBarUpdater);
- }
-
- private void stopUpdateProgressBar() {
- mHandler.removeCallbacks(mProgressBarUpdater);
- }
- }
-
- public ScheduledRecordingPresenter(Context context) {
- ApplicationSingletons singletons = TvApplication.getSingletons(context);
- mChannelDataManager = singletons.getChannelDataManager();
- mDvrManager = singletons.getDvrManager();
- mContext = context;
- mProgressBarColor = context.getResources()
- .getColor(R.color.play_controls_recording_icon_color_on_focus);
- }
-
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent) {
- Context context = parent.getContext();
- RecordingCardView view = new RecordingCardView(context);
- return new ScheduledRecordingViewHolder(view, mProgressBarColor);
- }
-
- @Override
- public void onBindViewHolder(ViewHolder baseHolder, Object o) {
- final ScheduledRecordingViewHolder viewHolder = (ScheduledRecordingViewHolder) baseHolder;
- final ScheduledRecording recording = (ScheduledRecording) o;
- final RecordingCardView cardView = (RecordingCardView) viewHolder.view;
- final Context context = viewHolder.view.getContext();
-
- setTitleAndImage(cardView, recording);
- int dateDifference = Utils.computeDateDifference(System.currentTimeMillis(),
- recording.getStartTimeMs());
- if (dateDifference <= 0) {
- cardView.setContent(mContext.getString(R.string.dvr_date_today_time,
- Utils.getDurationString(context, recording.getStartTimeMs(),
- recording.getEndTimeMs(), false, false, true, 0)), null);
- } else if (dateDifference == 1) {
- cardView.setContent(mContext.getString(R.string.dvr_date_tomorrow_time,
- Utils.getDurationString(context, recording.getStartTimeMs(),
- recording.getEndTimeMs(), false, false, true, 0)), null);
- } else {
- cardView.setContent(Utils.getDurationString(context, recording.getStartTimeMs(),
- recording.getStartTimeMs(), false, true, false, 0), null);
- }
- if (mDvrManager.isConflicting(recording)) {
- cardView.setAffiliatedIcon(R.drawable.ic_warning_white_32dp);
- } else {
- cardView.setAffiliatedIcon(0);
- }
- viewHolder.updateProgressBar();
- viewHolder.mScheduledRecording = recording;
- viewHolder.startUpdateProgressBar();
- super.onBindViewHolder(viewHolder, o);
- }
-
- @Override
- public void onUnbindViewHolder(ViewHolder baseHolder) {
- ScheduledRecordingViewHolder viewHolder = (ScheduledRecordingViewHolder) baseHolder;
- viewHolder.stopUpdateProgressBar();
- final RecordingCardView cardView = (RecordingCardView) viewHolder.view;
- viewHolder.mScheduledRecording = null;
- cardView.reset();
- super.onUnbindViewHolder(viewHolder);
- }
-
- private void setTitleAndImage(RecordingCardView cardView, ScheduledRecording recording) {
- Channel channel = mChannelDataManager.getChannel(recording.getChannelId());
- SpannableString title = recording.getProgramTitleWithEpisodeNumber(mContext) == null ?
- null : new SpannableString(recording.getProgramTitleWithEpisodeNumber(mContext));
- if (TextUtils.isEmpty(title)) {
- title = new SpannableString(channel != null ? channel.getDisplayName()
- : mContext.getResources().getString(R.string.no_program_information));
- } else {
- String programTitle = recording.getProgramTitle();
- title.setSpan(new TextAppearanceSpan(mContext,
- R.style.text_appearance_card_view_episode_number),
- programTitle == null ? 0 : programTitle.length(), title.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- String imageUri = recording.getProgramPosterArtUri();
- boolean isChannelLogo = false;
- if (TextUtils.isEmpty(imageUri)) {
- imageUri = channel != null ?
- TvContract.buildChannelLogoUri(channel.getId()).toString() : null;
- isChannelLogo = true;
- }
- cardView.setTitle(title);
- cardView.setImageUri(imageUri, isChannelLogo);
- }
-}
diff --git a/src/com/android/tv/dvr/ui/SeriesDeletionFragment.java b/src/com/android/tv/dvr/ui/SeriesDeletionFragment.java
deleted file mode 100644
index 36e3cfc1..00000000
--- a/src/com/android/tv/dvr/ui/SeriesDeletionFragment.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.content.Context;
-import android.media.tv.TvInputManager;
-import android.os.Bundle;
-import android.support.v17.leanback.app.GuidedStepFragment;
-import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
-import android.support.v17.leanback.widget.GuidedAction;
-import android.support.v17.leanback.widget.GuidedActionsStylist;
-import android.text.TextUtils;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.Toast;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrWatchedPositionManager;
-import com.android.tv.dvr.RecordedProgram;
-import com.android.tv.dvr.SeriesRecording;
-import com.android.tv.ui.GuidedActionsStylistWithDivider;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Fragment for DVR series recording settings.
- */
-public class SeriesDeletionFragment extends GuidedStepFragment {
- private static final long WATCHED_TIME_UNIT_THRESHOLD = TimeUnit.MINUTES.toMillis(2);
-
- // Since recordings' IDs are used as its check actions' IDs, which are random positive numbers,
- // negative values are used by other actions to prevent duplicated IDs.
- private static final long ACTION_ID_SELECT_WATCHED = -110;
- private static final long ACTION_ID_SELECT_ALL = -111;
- private static final long ACTION_ID_DELETE = -112;
-
- private DvrDataManager mDvrDataManager;
- private DvrWatchedPositionManager mDvrWatchedPositionManager;
- private List<RecordedProgram> mRecordings;
- private final Set<Long> mWatchedRecordings = new HashSet<>();
- private boolean mAllSelected;
- private long mSeriesRecordingId;
- private int mOneLineActionHeight;
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- mSeriesRecordingId = getArguments()
- .getLong(DvrSeriesDeletionActivity.SERIES_RECORDING_ID, -1);
- SoftPreconditions.checkArgument(mSeriesRecordingId != -1);
- mDvrDataManager = TvApplication.getSingletons(context).getDvrDataManager();
- mDvrWatchedPositionManager =
- TvApplication.getSingletons(context).getDvrWatchedPositionManager();
- mRecordings = mDvrDataManager.getRecordedPrograms(mSeriesRecordingId);
- mOneLineActionHeight = getResources().getDimensionPixelSize(
- R.dimen.dvr_settings_one_line_action_container_height);
- if (mRecordings.isEmpty()) {
- Toast.makeText(getActivity(), getString(R.string.dvr_series_deletion_no_recordings),
- Toast.LENGTH_LONG).show();
- finishGuidedStepFragments();
- return;
- }
- Collections.sort(mRecordings, RecordedProgram.EPISODE_COMPARATOR);
- }
-
- @Override
- public Guidance onCreateGuidance(Bundle savedInstanceState) {
- String breadcrumb = null;
- SeriesRecording series = mDvrDataManager.getSeriesRecording(mSeriesRecordingId);
- if (series != null) {
- breadcrumb = series.getTitle();
- }
- return new Guidance(getString(R.string.dvr_series_deletion_title),
- getString(R.string.dvr_series_deletion_description), breadcrumb, null);
- }
-
- @Override
- public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- actions.add(new GuidedAction.Builder(getActivity())
- .id(ACTION_ID_SELECT_WATCHED)
- .title(getString(R.string.dvr_series_select_watched))
- .build());
- actions.add(new GuidedAction.Builder(getActivity())
- .id(ACTION_ID_SELECT_ALL)
- .title(getString(R.string.dvr_series_select_all))
- .build());
- actions.add(GuidedActionsStylistWithDivider.createDividerAction(getContext()));
- for (RecordedProgram recording : mRecordings) {
- long watchedPositionMs =
- mDvrWatchedPositionManager.getWatchedPosition(recording.getId());
- String title = recording.getEpisodeDisplayTitle(getContext());
- if (TextUtils.isEmpty(title)) {
- title = TextUtils.isEmpty(recording.getTitle()) ?
- getString(R.string.channel_banner_no_title) : recording.getTitle();
- }
- String description;
- if (watchedPositionMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
- description = getWatchedString(watchedPositionMs, recording.getDurationMillis());
- mWatchedRecordings.add(recording.getId());
- } else {
- description = getString(R.string.dvr_series_never_watched);
- }
- actions.add(new GuidedAction.Builder(getActivity())
- .id(recording.getId())
- .title(title)
- .description(description)
- .checkSetId(GuidedAction.CHECKBOX_CHECK_SET_ID)
- .build());
- }
- }
-
- @Override
- public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- actions.add(new GuidedAction.Builder(getActivity())
- .id(ACTION_ID_DELETE)
- .title(getString(R.string.dvr_detail_delete))
- .build());
- actions.add(new GuidedAction.Builder(getActivity())
- .clickAction(GuidedAction.ACTION_ID_CANCEL)
- .build());
- }
-
- @Override
- public void onGuidedActionClicked(GuidedAction action) {
- long actionId = action.getId();
- if (actionId == ACTION_ID_DELETE) {
- List<Long> idsToDelete = new ArrayList<>();
- for (GuidedAction guidedAction : getActions()) {
- if (guidedAction.getCheckSetId() == GuidedAction.CHECKBOX_CHECK_SET_ID
- && guidedAction.isChecked()) {
- idsToDelete.add(guidedAction.getId());
- }
- }
- if (!idsToDelete.isEmpty()) {
- DvrManager dvrManager = TvApplication.getSingletons(getActivity()).getDvrManager();
- dvrManager.removeRecordedPrograms(idsToDelete);
- }
- Toast.makeText(getContext(), getResources().getQuantityString(
- R.plurals.dvr_msg_episodes_deleted, idsToDelete.size(), idsToDelete.size(),
- mRecordings.size()), Toast.LENGTH_LONG).show();
- finishGuidedStepFragments();
- } else if (actionId == GuidedAction.ACTION_ID_CANCEL) {
- finishGuidedStepFragments();
- } else if (actionId == ACTION_ID_SELECT_WATCHED) {
- for (GuidedAction guidedAction : getActions()) {
- if (guidedAction.getCheckSetId() == GuidedAction.CHECKBOX_CHECK_SET_ID) {
- long recordingId = guidedAction.getId();
- if (mWatchedRecordings.contains(recordingId)) {
- guidedAction.setChecked(true);
- } else {
- guidedAction.setChecked(false);
- }
- notifyActionChanged(findActionPositionById(recordingId));
- }
- }
- mAllSelected = updateSelectAllState();
- } else if (actionId == ACTION_ID_SELECT_ALL) {
- mAllSelected = !mAllSelected;
- for (GuidedAction guidedAction : getActions()) {
- if (guidedAction.getCheckSetId() == GuidedAction.CHECKBOX_CHECK_SET_ID) {
- guidedAction.setChecked(mAllSelected);
- notifyActionChanged(findActionPositionById(guidedAction.getId()));
- }
- }
- updateSelectAllState(action, mAllSelected);
- } else {
- mAllSelected = updateSelectAllState();
- }
- }
-
- @Override
- public GuidedActionsStylist onCreateButtonActionsStylist() {
- return new DvrGuidedActionsStylist(true);
- }
-
- @Override
- public GuidedActionsStylist onCreateActionsStylist() {
- return new GuidedActionsStylistWithDivider() {
- @Override
- public void onBindViewHolder(ViewHolder vh, GuidedAction action) {
- super.onBindViewHolder(vh, action);
- if (action.getId() == ACTION_DIVIDER) {
- return;
- }
- LayoutParams lp = vh.itemView.getLayoutParams();
- if (action.getCheckSetId() != GuidedAction.CHECKBOX_CHECK_SET_ID) {
- lp.height = mOneLineActionHeight;
- } else {
- vh.itemView.setLayoutParams(
- new LayoutParams(lp.width, LayoutParams.WRAP_CONTENT));
- }
- }
- };
- }
-
- private String getWatchedString(long watchedPositionMs, long durationMs) {
- if (durationMs > WATCHED_TIME_UNIT_THRESHOLD) {
- return getResources().getString(R.string.dvr_series_watched_info_minutes,
- Math.max(1, TimeUnit.MILLISECONDS.toMinutes(watchedPositionMs)),
- TimeUnit.MILLISECONDS.toMinutes(durationMs));
- } else {
- return getResources().getString(R.string.dvr_series_watched_info_seconds,
- Math.max(1, TimeUnit.MILLISECONDS.toSeconds(watchedPositionMs)),
- TimeUnit.MILLISECONDS.toSeconds(durationMs));
- }
- }
-
- private boolean updateSelectAllState() {
- for (GuidedAction guidedAction : getActions()) {
- if (guidedAction.getCheckSetId() == GuidedAction.CHECKBOX_CHECK_SET_ID) {
- if (!guidedAction.isChecked()) {
- if (mAllSelected) {
- updateSelectAllState(findActionById(ACTION_ID_SELECT_ALL), false);
- }
- return false;
- }
- }
- }
- if (!mAllSelected) {
- updateSelectAllState(findActionById(ACTION_ID_SELECT_ALL), true);
- }
- return true;
- }
-
- private void updateSelectAllState(GuidedAction selectAll, boolean select) {
- selectAll.setTitle(select ? getString(R.string.dvr_series_deselect_all)
- : getString(R.string.dvr_series_select_all));
- notifyActionChanged(findActionPositionById(ACTION_ID_SELECT_ALL));
- }
-}
diff --git a/src/com/android/tv/dvr/ui/SeriesRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/SeriesRecordingDetailsFragment.java
deleted file mode 100644
index e9e391d4..00000000
--- a/src/com/android/tv/dvr/ui/SeriesRecordingDetailsFragment.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.media.tv.TvInputManager;
-import android.os.Bundle;
-import android.support.v17.leanback.app.DetailsFragment;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.support.v17.leanback.widget.DetailsOverviewRow;
-import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
-import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.text.TextUtils;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.BaseProgram;
-import com.android.tv.data.Channel;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.DvrWatchedPositionManager;
-import com.android.tv.dvr.RecordedProgram;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.dvr.SeriesRecording;
-
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * {@link DetailsFragment} for series recording in DVR.
- */
-public class SeriesRecordingDetailsFragment extends DvrDetailsFragment implements
- DvrDataManager.SeriesRecordingListener, DvrDataManager.RecordedProgramListener {
- private static final int ACTION_WATCH = 1;
- private static final int ACTION_SERIES_SCHEDULES = 2;
- private static final int ACTION_DELETE = 3;
-
- private DvrWatchedPositionManager mDvrWatchedPositionManager;
- private DvrDataManager mDvrDataManager;
-
- private SeriesRecording mSeries;
- // NOTICE: mRecordedPrograms should only be used in creating details fragments.
- // After fragments are created, it should be cleared to save resources.
- private List<RecordedProgram> mRecordedPrograms;
- private RecordedProgram mRecommendRecordedProgram;
- private DetailsContent mDetailsContent;
- private int mSeasonRowCount;
- private SparseArrayObjectAdapter mActionsAdapter;
- private Action mDeleteAction;
-
- private boolean mPaused;
- private long mInitialPlaybackPositionMs;
- private String mWatchLabel;
- private String mResumeLabel;
- private Drawable mWatchDrawable;
- private RecordedProgramPresenter mRecordedProgramPresenter;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- mDvrDataManager = TvApplication.getSingletons(getActivity()).getDvrDataManager();
- mWatchLabel = getString(R.string.dvr_detail_watch);
- mResumeLabel = getString(R.string.dvr_detail_series_resume);
- mWatchDrawable = getResources().getDrawable(R.drawable.lb_ic_play, null);
- mRecordedProgramPresenter = new RecordedProgramPresenter(getContext(), true);
- super.onCreate(savedInstanceState);
- }
-
- @Override
- protected void onCreateInternal() {
- mDvrWatchedPositionManager = TvApplication.getSingletons(getActivity())
- .getDvrWatchedPositionManager();
- setDetailsOverviewRow(mDetailsContent);
- setupRecordedProgramsRow();
- mDvrDataManager.addSeriesRecordingListener(this);
- mDvrDataManager.addRecordedProgramListener(this);
- mRecordedPrograms = null;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (mPaused) {
- updateWatchAction();
- mPaused = false;
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mPaused = true;
- }
-
- private void updateWatchAction() {
- List<RecordedProgram> programs = mDvrDataManager.getRecordedPrograms(mSeries.getId());
- Collections.sort(programs, RecordedProgram.EPISODE_COMPARATOR);
- mRecommendRecordedProgram = getRecommendProgram(programs);
- if (mRecommendRecordedProgram == null) {
- mActionsAdapter.clear(ACTION_WATCH);
- } else {
- String episodeStatus;
- if(mDvrWatchedPositionManager.getWatchedStatus(mRecommendRecordedProgram)
- == DvrWatchedPositionManager.DVR_WATCHED_STATUS_WATCHING) {
- episodeStatus = mResumeLabel;
- mInitialPlaybackPositionMs = mDvrWatchedPositionManager
- .getWatchedPosition(mRecommendRecordedProgram.getId());
- } else {
- episodeStatus = mWatchLabel;
- mInitialPlaybackPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
- }
- String episodeDisplayNumber = mRecommendRecordedProgram.getEpisodeDisplayNumber(
- getContext());
- mActionsAdapter.set(ACTION_WATCH, new Action(ACTION_WATCH,
- episodeStatus, episodeDisplayNumber, mWatchDrawable));
- }
- }
-
- @Override
- protected boolean onLoadRecordingDetails(Bundle args) {
- long recordId = args.getLong(DvrDetailsActivity.RECORDING_ID);
- mSeries = TvApplication.getSingletons(getActivity()).getDvrDataManager()
- .getSeriesRecording(recordId);
- if (mSeries == null) {
- return false;
- }
- mRecordedPrograms = mDvrDataManager.getRecordedPrograms(mSeries.getId());
- Collections.sort(mRecordedPrograms, RecordedProgram.SEASON_REVERSED_EPISODE_COMPARATOR);
- mDetailsContent = createDetailsContent();
- return true;
- }
-
- @Override
- protected PresenterSelector onCreatePresenterSelector(
- DetailsOverviewRowPresenter rowPresenter) {
- ClassPresenterSelector presenterSelector = new ClassPresenterSelector();
- presenterSelector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
- presenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter());
- return presenterSelector;
- }
-
- private DetailsContent createDetailsContent() {
- Channel channel = TvApplication.getSingletons(getContext()).getChannelDataManager()
- .getChannel(mSeries.getChannelId());
- String description = TextUtils.isEmpty(mSeries.getLongDescription())
- ? mSeries.getDescription() : mSeries.getLongDescription();
- return new DetailsContent.Builder()
- .setTitle(mSeries.getTitle())
- .setDescription(description)
- .setImageUris(mSeries.getPosterUri(), mSeries.getPhotoUri(), channel)
- .build();
- }
-
- @Override
- protected SparseArrayObjectAdapter onCreateActionsAdapter() {
- mActionsAdapter = new SparseArrayObjectAdapter(new ActionPresenterSelector());
- Resources res = getResources();
- updateWatchAction();
- mActionsAdapter.set(ACTION_SERIES_SCHEDULES, new Action(ACTION_SERIES_SCHEDULES,
- getString(R.string.dvr_detail_view_schedule), null,
- res.getDrawable(R.drawable.ic_schedule_32dp, null)));
- mDeleteAction = new Action(ACTION_DELETE,
- getString(R.string.dvr_detail_series_delete), null,
- res.getDrawable(R.drawable.ic_delete_32dp, null));
- if (!mRecordedPrograms.isEmpty()) {
- mActionsAdapter.set(ACTION_DELETE, mDeleteAction);
- }
- return mActionsAdapter;
- }
-
- private void setupRecordedProgramsRow() {
- for (RecordedProgram program : mRecordedPrograms) {
- addProgram(program);
- }
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mDvrDataManager.removeSeriesRecordingListener(this);
- mDvrDataManager.removeRecordedProgramListener(this);
- if (mSeries != null) {
- DvrManager dvrManager = TvApplication.getSingletons(getActivity()).getDvrManager();
- if (dvrManager.canRemoveSeriesRecording(mSeries.getId())) {
- dvrManager.removeSeriesRecording(mSeries.getId());
- }
- }
- mRecordedProgramPresenter.unbindAllViewHolders();
- }
-
- @Override
- protected OnActionClickedListener onCreateOnActionClickedListener() {
- return new OnActionClickedListener() {
- @Override
- public void onActionClicked(Action action) {
- if (action.getId() == ACTION_WATCH) {
- startPlayback(mRecommendRecordedProgram, mInitialPlaybackPositionMs);
- } else if (action.getId() == ACTION_SERIES_SCHEDULES) {
- DvrUiHelper.startSchedulesActivityForSeries(getContext(), mSeries);
- } else if (action.getId() == ACTION_DELETE) {
- DvrUiHelper.startSeriesDeletionActivity(getContext(), mSeries.getId());
- }
- }
- };
- }
-
- /**
- * The programs are sorted by season number and episode number.
- */
- private RecordedProgram getRecommendProgram(List<RecordedProgram> programs) {
- for (int i = programs.size() - 1 ; i >= 0 ; i--) {
- RecordedProgram program = programs.get(i);
- int watchedStatus = mDvrWatchedPositionManager.getWatchedStatus(program);
- if (watchedStatus == DvrWatchedPositionManager.DVR_WATCHED_STATUS_NEW) {
- continue;
- }
- if (watchedStatus == DvrWatchedPositionManager.DVR_WATCHED_STATUS_WATCHING) {
- return program;
- }
- if (i == programs.size() - 1) {
- return program;
- } else {
- return programs.get(i + 1);
- }
- }
- return programs.isEmpty() ? null : programs.get(0);
- }
-
- @Override
- public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) { }
-
- @Override
- public void onSeriesRecordingChanged(SeriesRecording... seriesRecordings) {
- for (SeriesRecording series : seriesRecordings) {
- if (mSeries.getId() == series.getId()) {
- mSeries = series;
- }
- }
- }
-
- @Override
- public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) {
- for (SeriesRecording series : seriesRecordings) {
- if (series.getId() == mSeries.getId()) {
- mSeries = null;
- getActivity().finish();
- return;
- }
- }
- }
-
- @Override
- public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) {
- for (RecordedProgram recordedProgram : recordedPrograms) {
- if (TextUtils.equals(recordedProgram.getSeriesId(), mSeries.getSeriesId())) {
- addProgram(recordedProgram);
- if (mActionsAdapter.lookup(ACTION_DELETE) == null) {
- mActionsAdapter.set(ACTION_DELETE, mDeleteAction);
- }
- }
- }
- }
-
- @Override
- public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) {
- // Do nothing
- }
-
- @Override
- public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) {
- for (RecordedProgram recordedProgram : recordedPrograms) {
- if (TextUtils.equals(recordedProgram.getSeriesId(), mSeries.getSeriesId())) {
- ListRow row = getSeasonRow(recordedProgram.getSeasonNumber(), false);
- if (row != null) {
- SeasonRowAdapter adapter = (SeasonRowAdapter) row.getAdapter();
- adapter.remove(recordedProgram);
- if (adapter.isEmpty()) {
- getRowsAdapter().remove(row);
- if (getRowsAdapter().size() == 1) {
- // No season rows left. Only DetailsOverviewRow
- mActionsAdapter.clear(ACTION_DELETE);
- }
- }
- }
- if (recordedProgram.getId() == mRecommendRecordedProgram.getId()) {
- updateWatchAction();
- }
- }
- }
- }
-
- private void addProgram(RecordedProgram program) {
- String programSeasonNumber =
- TextUtils.isEmpty(program.getSeasonNumber()) ? "" : program.getSeasonNumber();
- getOrCreateSeasonRowAdapter(programSeasonNumber).add(program);
- }
-
- private SeasonRowAdapter getOrCreateSeasonRowAdapter(String seasonNumber) {
- ListRow row = getSeasonRow(seasonNumber, true);
- return (SeasonRowAdapter) row.getAdapter();
- }
-
- private ListRow getSeasonRow(String seasonNumber, boolean createNewRow) {
- seasonNumber = TextUtils.isEmpty(seasonNumber) ? "" : seasonNumber;
- ArrayObjectAdapter rowsAdaptor = getRowsAdapter();
- for (int i = rowsAdaptor.size() - 1; i >= 0; i--) {
- Object row = rowsAdaptor.get(i);
- if (row instanceof ListRow) {
- int compareResult = BaseProgram.numberCompare(seasonNumber,
- ((SeasonRowAdapter) ((ListRow) row).getAdapter()).mSeasonNumber);
- if (compareResult == 0) {
- return (ListRow) row;
- } else if (compareResult < 0) {
- return createNewRow ? createNewSeasonRow(seasonNumber, i + 1) : null;
- }
- }
- }
- return createNewRow ? createNewSeasonRow(seasonNumber, rowsAdaptor.size()) : null;
- }
-
- private ListRow createNewSeasonRow(String seasonNumber, int position) {
- String seasonTitle = seasonNumber.isEmpty() ? mSeries.getTitle()
- : getString(R.string.dvr_detail_series_season_title, seasonNumber);
- HeaderItem header = new HeaderItem(mSeasonRowCount++, seasonTitle);
- ClassPresenterSelector selector = new ClassPresenterSelector();
- selector.addClassPresenter(RecordedProgram.class, mRecordedProgramPresenter);
- ListRow row = new ListRow(header, new SeasonRowAdapter(selector,
- new Comparator<RecordedProgram>() {
- @Override
- public int compare(RecordedProgram lhs, RecordedProgram rhs) {
- return BaseProgram.EPISODE_COMPARATOR.compare(lhs, rhs);
- }
- }, seasonNumber));
- getRowsAdapter().add(position, row);
- return row;
- }
-
- private class SeasonRowAdapter extends SortedArrayAdapter<RecordedProgram> {
- private String mSeasonNumber;
-
- SeasonRowAdapter(PresenterSelector selector, Comparator<RecordedProgram> comparator,
- String seasonNumber) {
- super(selector, comparator);
- mSeasonNumber = seasonNumber;
- }
-
- @Override
- public long getId(RecordedProgram program) {
- return program.getId();
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/SeriesRecordingPresenter.java b/src/com/android/tv/dvr/ui/SeriesRecordingPresenter.java
deleted file mode 100644
index c2c0f596..00000000
--- a/src/com/android/tv/dvr/ui/SeriesRecordingPresenter.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.Activity;
-import android.content.Context;
-import android.media.tv.TvContract;
-import android.media.tv.TvInputManager;
-import android.text.TextUtils;
-import android.view.ViewGroup;
-
-import com.android.tv.ApplicationSingletons;
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrDataManager.RecordedProgramListener;
-import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrWatchedPositionManager;
-import com.android.tv.dvr.DvrWatchedPositionManager.WatchedPositionChangedListener;
-import com.android.tv.dvr.RecordedProgram;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.dvr.SeriesRecording;
-
-import java.util.List;
-
-/**
- * Presents a {@link SeriesRecording} in {@link DvrBrowseFragment}.
- */
-public class SeriesRecordingPresenter extends DvrItemPresenter {
- private final ChannelDataManager mChannelDataManager;
- private final DvrDataManager mDvrDataManager;
- private final DvrManager mDvrManager;
- private final DvrWatchedPositionManager mWatchedPositionManager;
-
- private static final class SeriesRecordingViewHolder extends ViewHolder implements
- WatchedPositionChangedListener, ScheduledRecordingListener, RecordedProgramListener {
- private SeriesRecording mSeriesRecording;
- private RecordingCardView mCardView;
- private DvrDataManager mDvrDataManager;
- private DvrManager mDvrManager;
- private DvrWatchedPositionManager mWatchedPositionManager;
-
- SeriesRecordingViewHolder(RecordingCardView view, DvrDataManager dvrDataManager,
- DvrManager dvrManager, DvrWatchedPositionManager watchedPositionManager) {
- super(view);
- mCardView = view;
- mDvrDataManager = dvrDataManager;
- mDvrManager = dvrManager;
- mWatchedPositionManager = watchedPositionManager;
- }
-
- @Override
- public void onWatchedPositionChanged(long recordedProgramId, long positionMs) {
- if (positionMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
- mWatchedPositionManager.removeListener(this, recordedProgramId);
- updateCardViewContent();
- }
- }
-
- @Override
- public void onScheduledRecordingAdded(ScheduledRecording... scheduledRecordings) {
- for (ScheduledRecording scheduledRecording : scheduledRecordings) {
- if (scheduledRecording.getSeriesRecordingId() == mSeriesRecording.getId()) {
- updateCardViewContent();
- return;
- }
- }
- }
-
- @Override
- public void onScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings) {
- for (ScheduledRecording scheduledRecording : scheduledRecordings) {
- if (scheduledRecording.getSeriesRecordingId() == mSeriesRecording.getId()) {
- updateCardViewContent();
- return;
- }
- }
- }
-
- @Override
- public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) {
- boolean needToUpdateCardView = false;
- for (RecordedProgram recordedProgram : recordedPrograms) {
- if (TextUtils.equals(recordedProgram.getSeriesId(),
- mSeriesRecording.getSeriesId())) {
- mDvrDataManager.removeScheduledRecordingListener(this);
- mWatchedPositionManager.addListener(this, recordedProgram.getId());
- needToUpdateCardView = true;
- }
- }
- if (needToUpdateCardView) {
- updateCardViewContent();
- }
- }
-
- @Override
- public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) {
- boolean needToUpdateCardView = false;
- for (RecordedProgram recordedProgram : recordedPrograms) {
- if (TextUtils.equals(recordedProgram.getSeriesId(),
- mSeriesRecording.getSeriesId())) {
- if (mWatchedPositionManager.getWatchedPosition(recordedProgram.getId())
- == TvInputManager.TIME_SHIFT_INVALID_TIME) {
- mWatchedPositionManager.removeListener(this, recordedProgram.getId());
- }
- needToUpdateCardView = true;
- }
- }
- if (needToUpdateCardView) {
- updateCardViewContent();
- }
- }
-
- @Override
- public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) {
- // Do nothing
- }
-
- @Override
- public void onScheduledRecordingStatusChanged(ScheduledRecording... scheduledRecordings) {
- // Do nothing
- }
-
- public void onBound(SeriesRecording seriesRecording) {
- mSeriesRecording = seriesRecording;
- mDvrDataManager.addScheduledRecordingListener(this);
- mDvrDataManager.addRecordedProgramListener(this);
- for (RecordedProgram recordedProgram :
- mDvrDataManager.getRecordedPrograms(mSeriesRecording.getId())) {
- if (mWatchedPositionManager.getWatchedPosition(recordedProgram.getId())
- == TvInputManager.TIME_SHIFT_INVALID_TIME) {
- mWatchedPositionManager.addListener(this, recordedProgram.getId());
- }
- }
- updateCardViewContent();
- }
-
- public void onUnbound() {
- mDvrDataManager.removeScheduledRecordingListener(this);
- mDvrDataManager.removeRecordedProgramListener(this);
- mWatchedPositionManager.removeListener(this);
- }
-
- private void updateCardViewContent() {
- int count = 0;
- int quantityStringID;
- List<RecordedProgram> recordedPrograms =
- mDvrDataManager.getRecordedPrograms(mSeriesRecording.getId());
- if (recordedPrograms.size() == 0) {
- count = mDvrManager.getAvailableScheduledRecording(mSeriesRecording.getId()).size();
- quantityStringID = R.plurals.dvr_count_scheduled_recordings;
- } else {
- for (RecordedProgram recordedProgram : recordedPrograms) {
- if (mWatchedPositionManager.getWatchedPosition(recordedProgram.getId())
- == TvInputManager.TIME_SHIFT_INVALID_TIME) {
- count++;
- }
- }
- if (count == 0) {
- count = recordedPrograms.size();
- quantityStringID = R.plurals.dvr_count_recordings;
- } else {
- quantityStringID = R.plurals.dvr_count_new_recordings;
- }
- }
- mCardView.setContent(mCardView.getResources()
- .getQuantityString(quantityStringID, count, count), null);
- }
- }
-
- public SeriesRecordingPresenter(Context context) {
- ApplicationSingletons singletons = TvApplication.getSingletons(context);
- mChannelDataManager = singletons.getChannelDataManager();
- mDvrDataManager = singletons.getDvrDataManager();
- mDvrManager = singletons.getDvrManager();
- mWatchedPositionManager = singletons.getDvrWatchedPositionManager();
- }
-
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent) {
- Context context = parent.getContext();
- RecordingCardView view = new RecordingCardView(context);
- return new SeriesRecordingViewHolder(view, mDvrDataManager, mDvrManager,
- mWatchedPositionManager);
- }
-
- @Override
- public void onBindViewHolder(ViewHolder baseHolder, Object o) {
- final SeriesRecordingViewHolder viewHolder = (SeriesRecordingViewHolder) baseHolder;
- final SeriesRecording seriesRecording = (SeriesRecording) o;
- final RecordingCardView cardView = (RecordingCardView) viewHolder.view;
- viewHolder.onBound(seriesRecording);
- setTitleAndImage(cardView, seriesRecording);
- super.onBindViewHolder(baseHolder, o);
- }
-
- @Override
- public void onUnbindViewHolder(ViewHolder viewHolder) {
- ((RecordingCardView) viewHolder.view).reset();
- ((SeriesRecordingViewHolder) viewHolder).onUnbound();
- super.onUnbindViewHolder(viewHolder);
- }
-
- private void setTitleAndImage(RecordingCardView cardView, SeriesRecording recording) {
- cardView.setTitle(recording.getTitle());
- if (recording.getPosterUri() != null) {
- cardView.setImageUri(recording.getPosterUri(), false);
- } else {
- Channel channel = mChannelDataManager.getChannel(recording.getChannelId());
- String imageUri = null;
- if (channel != null) {
- imageUri = TvContract.buildChannelLogoUri(channel.getId()).toString();
- }
- cardView.setImageUri(imageUri, true);
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/SeriesSettingsFragment.java b/src/com/android/tv/dvr/ui/SeriesSettingsFragment.java
deleted file mode 100644
index 6c05c9c6..00000000
--- a/src/com/android/tv/dvr/ui/SeriesSettingsFragment.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr.ui;
-
-import android.app.FragmentManager;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v17.leanback.app.GuidedStepFragment;
-import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
-import android.support.v17.leanback.widget.GuidedAction;
-import android.support.v17.leanback.widget.GuidedActionsStylist;
-import android.util.Log;
-import android.util.LongSparseArray;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ProgressBar;
-
-import com.android.tv.R;
-import com.android.tv.TvApplication;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.Program;
-import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.EpisodicProgramLoadTask;
-import com.android.tv.dvr.SeriesRecording;
-import com.android.tv.dvr.SeriesRecording.ChannelOption;
-import com.android.tv.dvr.SeriesRecordingScheduler;
-import com.android.tv.dvr.SeriesRecordingScheduler.OnSeriesRecordingUpdatedListener;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Fragment for DVR series recording settings.
- */
-public class SeriesSettingsFragment extends GuidedStepFragment
- implements DvrDataManager.SeriesRecordingListener {
- private static final String TAG = "SeriesSettingsFragment";
- private static final boolean DEBUG = false;
-
- private static final long ACTION_ID_PRIORITY = 10;
- private static final long ACTION_ID_CHANNEL = 11;
-
- private static final long SUB_ACTION_ID_CHANNEL_ALL = 102;
- // Each channel's action id = SUB_ACTION_ID_CHANNEL_ONE_BASE + channel id
- private static final long SUB_ACTION_ID_CHANNEL_ONE_BASE = 500;
-
- private DvrDataManager mDvrDataManager;
- private ChannelDataManager mChannelDataManager;
- private DvrManager mDvrManager;
- private SeriesRecording mSeriesRecording;
- private long mSeriesRecordingId;
- @ChannelOption int mChannelOption;
- private Comparator<Channel> mChannelComparator;
- private long mSelectedChannelId;
- private int mBackStackCount;
- private boolean mShowViewScheduleOptionInDialog;
-
- private String mFragmentTitle;
- private String mProrityActionTitle;
- private String mProrityActionHighestText;
- private String mProrityActionLowestText;
- private String mChannelsActionTitle;
- private String mChannelsActionAllText;
- private LongSparseArray<Channel> mId2Channel = new LongSparseArray<>();
- private List<Channel> mChannels = new ArrayList<>();
- private EpisodicProgramLoadTask mEpisodicProgramLoadTask;
-
- private GuidedAction mPriorityGuidedAction;
- private GuidedAction mChannelsGuidedAction;
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- mBackStackCount = getFragmentManager().getBackStackEntryCount();
- mDvrDataManager = TvApplication.getSingletons(context).getDvrDataManager();
- mSeriesRecordingId = getArguments().getLong(DvrSeriesSettingsActivity.SERIES_RECORDING_ID);
- mSeriesRecording = mDvrDataManager.getSeriesRecording(mSeriesRecordingId);
- if (mSeriesRecording == null) {
- getActivity().finish();
- return;
- }
- mDvrManager = TvApplication.getSingletons(context).getDvrManager();
- mShowViewScheduleOptionInDialog = getArguments().getBoolean(
- DvrSeriesSettingsActivity.SHOW_VIEW_SCHEDULE_OPTION_IN_DIALOG);
- mDvrDataManager.addSeriesRecordingListener(this);
- long[] channelIds = getArguments().getLongArray(DvrSeriesSettingsActivity.CHANNEL_ID_LIST);
- mChannelDataManager = TvApplication.getSingletons(context).getChannelDataManager();
- if (channelIds == null) {
- Channel channel = mChannelDataManager.getChannel(mSeriesRecording.getChannelId());
- if (channel != null) {
- mId2Channel.put(channel.getId(), channel);
- mChannels.add(channel);
- }
- collectChannelsInBackground();
- } else {
- for (long channelId : channelIds) {
- Channel channel = mChannelDataManager.getChannel(channelId);
- if (channel != null) {
- mId2Channel.put(channel.getId(), channel);
- mChannels.add(channel);
- }
- }
- }
- mChannelOption = mSeriesRecording.getChannelOption();
- mSelectedChannelId = Channel.INVALID_ID;
- if (mChannelOption == SeriesRecording.OPTION_CHANNEL_ONE) {
- Channel channel = mChannelDataManager.getChannel(mSeriesRecording.getChannelId());
- if (channel != null) {
- mSelectedChannelId = channel.getId();
- } else {
- mChannelOption = SeriesRecording.OPTION_CHANNEL_ALL;
- }
- }
- mChannelComparator = new Channel.DefaultComparator(context,
- TvApplication.getSingletons(context).getTvInputManagerHelper());
- mChannels.sort(mChannelComparator);
- mFragmentTitle = getString(R.string.dvr_series_settings_title);
- mProrityActionTitle = getString(R.string.dvr_series_settings_priority);
- mProrityActionHighestText = getString(R.string.dvr_series_settings_priority_highest);
- mProrityActionLowestText = getString(R.string.dvr_series_settings_priority_lowest);
- mChannelsActionTitle = getString(R.string.dvr_series_settings_channels);
- mChannelsActionAllText = getString(R.string.dvr_series_settings_channels_all);
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
- mDvrDataManager.removeSeriesRecordingListener(this);
- if (mEpisodicProgramLoadTask != null) {
- mEpisodicProgramLoadTask.cancel(true);
- mEpisodicProgramLoadTask = null;
- }
- }
-
- @Override
- public void onDestroy() {
- DvrManager dvrManager = TvApplication.getSingletons(getActivity()).getDvrManager();
- if (getFragmentManager().getBackStackEntryCount() == mBackStackCount
- && getArguments()
- .getBoolean(DvrSeriesSettingsActivity.REMOVE_EMPTY_SERIES_RECORDING)
- && dvrManager.canRemoveSeriesRecording(mSeriesRecordingId)) {
- dvrManager.removeSeriesRecording(mSeriesRecordingId);
- }
- super.onDestroy();
- }
-
- @Override
- public Guidance onCreateGuidance(Bundle savedInstanceState) {
- String breadcrumb = mSeriesRecording.getTitle();
- String title = mFragmentTitle;
- return new Guidance(title, null, breadcrumb, null);
- }
-
- @Override
- public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- mPriorityGuidedAction = new GuidedAction.Builder(getActivity())
- .id(ACTION_ID_PRIORITY)
- .title(mProrityActionTitle)
- .build();
- updatePriorityGuidedAction(false);
- actions.add(mPriorityGuidedAction);
-
- mChannelsGuidedAction = new GuidedAction.Builder(getActivity())
- .id(ACTION_ID_CHANNEL)
- .title(mChannelsActionTitle)
- .subActions(buildChannelSubAction())
- .build();
- actions.add(mChannelsGuidedAction);
- updateChannelsGuidedAction(false);
- }
-
- @Override
- public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
- actions.add(new GuidedAction.Builder(getActivity())
- .clickAction(GuidedAction.ACTION_ID_OK)
- .build());
- actions.add(new GuidedAction.Builder(getActivity())
- .clickAction(GuidedAction.ACTION_ID_CANCEL)
- .build());
- }
-
- @Override
- public void onGuidedActionClicked(GuidedAction action) {
- long actionId = action.getId();
- if (actionId == GuidedAction.ACTION_ID_OK) {
- if (mEpisodicProgramLoadTask != null) {
- mEpisodicProgramLoadTask.cancel(true);
- mEpisodicProgramLoadTask = null;
- }
- if (mChannelOption != mSeriesRecording.getChannelOption()
- || mSeriesRecording.isStopped()
- || (mChannelOption == SeriesRecording.OPTION_CHANNEL_ONE
- && mSeriesRecording.getChannelId() != mSelectedChannelId)) {
- SeriesRecording.Builder builder = SeriesRecording.buildFrom(mSeriesRecording)
- .setChannelOption(mChannelOption)
- .setState(SeriesRecording.STATE_SERIES_NORMAL);
- if (mSelectedChannelId != Channel.INVALID_ID) {
- builder.setChannelId(mSelectedChannelId);
- }
- TvApplication.getSingletons(getContext()).getDvrManager()
- .updateSeriesRecording(builder.build());
- SeriesRecordingScheduler scheduler =
- SeriesRecordingScheduler.getInstance(getContext());
- // Since dialog is used even after the fragment is closed, we should
- // use application context.
- ProgressDialog dialog = ProgressDialog.show(getContext(), null, getString(
- R.string.dvr_series_schedules_progress_message_updating_programs));
- scheduler.addOnSeriesRecordingUpdatedListener(
- new OnSeriesRecordingUpdatedListener() {
- @Override
- public void onSeriesRecordingUpdated(SeriesRecording... seriesRecordings) {
- for (SeriesRecording seriesRecording : seriesRecordings) {
- if (seriesRecording.getId() == mSeriesRecordingId) {
- dialog.dismiss();
- scheduler.removeOnSeriesRecordingUpdatedListener(this);
- showConfirmDialog();
- return;
- }
- }
- }
- });
- } else {
- showConfirmDialog();
- }
- } else if (actionId == GuidedAction.ACTION_ID_CANCEL) {
- finishGuidedStepFragments();
- } else if (actionId == ACTION_ID_PRIORITY) {
- FragmentManager fragmentManager = getFragmentManager();
- PrioritySettingsFragment fragment = new PrioritySettingsFragment();
- Bundle args = new Bundle();
- args.putLong(PrioritySettingsFragment.COME_FROM_SERIES_RECORDING_ID,
- mSeriesRecording.getId());
- fragment.setArguments(args);
- GuidedStepFragment.add(fragmentManager, fragment, R.id.dvr_settings_view_frame);
- }
- }
-
- @Override
- public boolean onSubGuidedActionClicked(GuidedAction action) {
- long actionId = action.getId();
- if (actionId == SUB_ACTION_ID_CHANNEL_ALL) {
- mChannelOption = SeriesRecording.OPTION_CHANNEL_ALL;
- mSelectedChannelId = Channel.INVALID_ID;
- updateChannelsGuidedAction(true);
- return true;
- } else if (actionId > SUB_ACTION_ID_CHANNEL_ONE_BASE) {
- mChannelOption = SeriesRecording.OPTION_CHANNEL_ONE;
- mSelectedChannelId = actionId - SUB_ACTION_ID_CHANNEL_ONE_BASE;
- updateChannelsGuidedAction(true);
- return true;
- }
- return false;
- }
-
- @Override
- public GuidedActionsStylist onCreateButtonActionsStylist() {
- return new DvrGuidedActionsStylist(true);
- }
-
- private void updateChannelsGuidedAction(boolean notifyActionChanged) {
- if (mChannelOption == SeriesRecording.OPTION_CHANNEL_ALL) {
- mChannelsGuidedAction.setDescription(mChannelsActionAllText);
- } else {
- mChannelsGuidedAction.setDescription(mId2Channel.get(mSelectedChannelId)
- .getDisplayText());
- }
- if (notifyActionChanged) {
- notifyActionChanged(findActionPositionById(ACTION_ID_CHANNEL));
- }
- }
-
- private void updatePriorityGuidedAction(boolean notifyActionChanged) {
- int totalSeriesCount = 0;
- int priorityOrder = 0;
- for (SeriesRecording seriesRecording : mDvrDataManager.getSeriesRecordings()) {
- if (seriesRecording.getState() == SeriesRecording.STATE_SERIES_NORMAL
- || seriesRecording.getId() == mSeriesRecording.getId()) {
- ++totalSeriesCount;
- }
- if (seriesRecording.getState() == SeriesRecording.STATE_SERIES_NORMAL
- && seriesRecording.getId() != mSeriesRecording.getId()
- && seriesRecording.getPriority() > mSeriesRecording.getPriority()) {
- ++priorityOrder;
- }
- }
- if (priorityOrder == 0) {
- mPriorityGuidedAction.setDescription(mProrityActionHighestText);
- } else if (priorityOrder >= totalSeriesCount - 1) {
- mPriorityGuidedAction.setDescription(mProrityActionLowestText);
- } else {
- mPriorityGuidedAction.setDescription(getString(
- R.string.dvr_series_settings_priority_rank, priorityOrder + 1));
- }
- if (notifyActionChanged) {
- notifyActionChanged(findActionPositionById(ACTION_ID_PRIORITY));
- }
- }
-
- private void collectChannelsInBackground() {
- if (mEpisodicProgramLoadTask != null) {
- mEpisodicProgramLoadTask.cancel(true);
- }
- mEpisodicProgramLoadTask = new EpisodicProgramLoadTask(getContext(), mSeriesRecording) {
- @Override
- protected void onPostExecute(List<Program> programs) {
- mEpisodicProgramLoadTask = null;
- Set<Long> channelIds = new HashSet<>();
- for (Program program : programs) {
- channelIds.add(program.getChannelId());
- }
- boolean channelAdded = false;
- for (Long channelId : channelIds) {
- if (mId2Channel.get(channelId) != null) {
- continue;
- }
- Channel channel = mChannelDataManager.getChannel(channelId);
- if (channel != null) {
- channelAdded = true;
- mId2Channel.put(channelId, channel);
- mChannels.add(channel);
- if (DEBUG) Log.d(TAG, "Added channel: " + channel);
- }
- }
- if (!channelAdded) {
- return;
- }
- mChannels.sort(mChannelComparator);
- mChannelsGuidedAction.setSubActions(buildChannelSubAction());
- notifyActionChanged(findActionPositionById(ACTION_ID_CHANNEL));
- if (DEBUG) Log.d(TAG, "Complete EpisodicProgramLoadTask");
- }
- }.setLoadCurrentProgram(true)
- .setLoadDisallowedProgram(true)
- .setLoadScheduledEpisode(true)
- .setIgnoreChannelOption(true);
- mEpisodicProgramLoadTask.execute();
- }
-
- private List<GuidedAction> buildChannelSubAction() {
- List<GuidedAction> channelSubActions = new ArrayList<>();
- channelSubActions.add(new GuidedAction.Builder(getActivity())
- .id(SUB_ACTION_ID_CHANNEL_ALL)
- .title(mChannelsActionAllText)
- .build());
- for (Channel channel : mChannels) {
- channelSubActions.add(new GuidedAction.Builder(getActivity())
- .id(SUB_ACTION_ID_CHANNEL_ONE_BASE + channel.getId())
- .title(channel.getDisplayText())
- .build());
- }
- return channelSubActions;
- }
-
- private void showConfirmDialog() {
- DvrUiHelper.StartSeriesScheduledDialogActivity(
- getContext(), mSeriesRecording, mShowViewScheduleOptionInDialog);
- finishGuidedStepFragments();
- }
-
- @Override
- public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) { }
-
- @Override
- public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) { }
-
- @Override
- public void onSeriesRecordingChanged(SeriesRecording... seriesRecordings) {
- for (SeriesRecording seriesRecording : seriesRecordings) {
- if (seriesRecording.getId() == mSeriesRecordingId) {
- mSeriesRecording = seriesRecording;
- updatePriorityGuidedAction(true);
- return;
- }
- }
- }
-}
diff --git a/src/com/android/tv/dvr/ui/SortedArrayAdapter.java b/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
index 393a5ff3..8c0af9ed 100644
--- a/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
+++ b/src/com/android/tv/dvr/ui/SortedArrayAdapter.java
@@ -20,11 +20,15 @@ import android.support.annotation.VisibleForTesting;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.PresenterSelector;
+import com.android.tv.common.SoftPreconditions;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* Keeps a set of items sorted
@@ -35,16 +39,18 @@ public abstract class SortedArrayAdapter<T> extends ArrayObjectAdapter {
private final Comparator<T> mComparator;
private final int mMaxItemCount;
private int mExtraItemCount;
+ private final Set<Long> mIds = new HashSet<>();
- SortedArrayAdapter(PresenterSelector presenterSelector, Comparator<T> comparator) {
+ public SortedArrayAdapter(PresenterSelector presenterSelector, Comparator<T> comparator) {
this(presenterSelector, comparator, Integer.MAX_VALUE);
}
- SortedArrayAdapter(PresenterSelector presenterSelector, Comparator<T> comparator,
+ public SortedArrayAdapter(PresenterSelector presenterSelector, Comparator<T> comparator,
int maxItemCount) {
super(presenterSelector);
mComparator = comparator;
mMaxItemCount = maxItemCount;
+ setHasStableIds(true);
}
/**
@@ -56,7 +62,12 @@ public abstract class SortedArrayAdapter<T> extends ArrayObjectAdapter {
final void setInitialItems(List<T> items) {
List<T> itemsCopy = new ArrayList<>(items);
Collections.sort(itemsCopy, mComparator);
- addAll(0, itemsCopy.subList(0, Math.min(mMaxItemCount, itemsCopy.size())));
+ for (T item : itemsCopy) {
+ add(item, true);
+ if (size() == mMaxItemCount) {
+ break;
+ }
+ }
}
/**
@@ -82,6 +93,9 @@ public abstract class SortedArrayAdapter<T> extends ArrayObjectAdapter {
* the end to save search time.
*/
public final void add(T item, boolean insertToEnd) {
+ long newItemId = getId(item);
+ SoftPreconditions.checkState(!mIds.contains(newItemId));
+ mIds.add(newItemId);
int i;
if (insertToEnd) {
i = findInsertPosition(item);
@@ -89,8 +103,9 @@ public abstract class SortedArrayAdapter<T> extends ArrayObjectAdapter {
i = findInsertPositionBinary(item);
}
super.add(i, item);
- if (size() > mMaxItemCount + mExtraItemCount) {
- removeItems(mMaxItemCount, size() - mMaxItemCount - mExtraItemCount);
+ if (mMaxItemCount < Integer.MAX_VALUE && size() > mMaxItemCount + mExtraItemCount) {
+ Object removedItem = get(mMaxItemCount);
+ remove(removedItem);
}
}
@@ -100,48 +115,97 @@ public abstract class SortedArrayAdapter<T> extends ArrayObjectAdapter {
* They will be presented in their insertion order.
*/
public int addExtraItem(T item) {
+ long newItemId = getId(item);
+ SoftPreconditions.checkState(!mIds.contains(newItemId));
+ mIds.add(newItemId);
super.add(item);
return ++mExtraItemCount;
}
+ @Override
+ public boolean remove(Object item) {
+ return removeWithId((T) item);
+ }
+
/**
* Removes an item which has the same ID as {@code item}.
*/
public boolean removeWithId(T item) {
- int index = indexWithTypeAndId(item);
- return index >= 0 && index < size() && remove(get(index));
+ int index = indexWithId(item);
+ return index >= 0 && index < size() && removeItems(index, 1) == 1;
+ }
+
+ @Override
+ public int removeItems(int position, int count) {
+ int upperBound = Math.min(position + count, size());
+ for (int i = position; i < upperBound; i++) {
+ mIds.remove(getId((T) get(i)));
+ }
+ if (upperBound > size() - mExtraItemCount) {
+ mExtraItemCount -= upperBound - Math.max(size() - mExtraItemCount, position);
+ }
+ return super.removeItems(position, count);
+ }
+
+ @Override
+ public void replace(int position, Object item) {
+ boolean wasExtra = position >= size() - mExtraItemCount;
+ removeItems(position, 1);
+ if (!wasExtra) {
+ add(item);
+ } else {
+ addExtraItem((T) item);
+ }
+ }
+
+ @Override
+ public void clear() {
+ mIds.clear();
+ super.clear();
}
/**
- * Change an item in the list.
+ * Changes an item in the list.
* @param item The item to change.
*/
public final void change(T item) {
- int oldIndex = indexWithTypeAndId(item);
+ int oldIndex = indexWithId(item);
if (oldIndex != -1) {
T old = (T) get(oldIndex);
if (mComparator.compare(old, item) == 0) {
replace(oldIndex, item);
return;
}
- removeItems(oldIndex, 1);
+ remove(old);
}
add(item);
}
/**
+ * Checks whether the item is in the list.
+ */
+ public final boolean contains(T item) {
+ return indexWithId(item) != -1;
+ }
+
+ @Override
+ public long getId(int position) {
+ return getId((T) get(position));
+ }
+
+ /**
* Returns the id of the the given {@code item}, which will be used in {@link #change} to
* decide if the given item is already existed in the adapter.
*
* The id must be stable.
*/
- abstract long getId(T item);
+ protected abstract long getId(T item);
- private int indexWithTypeAndId(T item) {
+ private int indexWithId(T item) {
long id = getId(item);
for (int i = 0; i < size() - mExtraItemCount; i++) {
T r = (T) get(i);
- if (r.getClass() == item.getClass() && getId(r) == id) {
+ if (getId(r) == id) {
return i;
}
}
diff --git a/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java b/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java
new file mode 100644
index 00000000..5fe9c478
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/TrackedGuidedStepFragment.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 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.tv.dvr.ui;
+
+import android.content.Context;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidedAction;
+
+import com.android.tv.TvApplication;
+import com.android.tv.analytics.Tracker;
+
+/** A {@link GuidedStepFragment} with {@link Tracker} for analytics. */
+public abstract class TrackedGuidedStepFragment extends GuidedStepFragment {
+ private Tracker mTracker;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mTracker = TvApplication.getSingletons(context).getAnalytics().getDefaultTracker();
+ }
+
+ @Override
+ public void onDetach() {
+ mTracker = null;
+ super.onDetach();
+ }
+
+ @Override
+ public final void onGuidedActionClicked(GuidedAction action) {
+ super.onGuidedActionClicked(action);
+ if (mTracker != null) {
+ mTracker.sendMenuClicked(
+ getTrackerPrefix() + "-action-" + getTrackerLabelForGuidedAction(action));
+ }
+ onTrackedGuidedActionClicked(action);
+ }
+
+ public String getTrackerLabelForGuidedAction(GuidedAction action) {
+ long actionId = action.getId();
+ if (actionId == GuidedAction.ACTION_ID_CANCEL) {
+ return "cancel";
+ } else if (actionId == GuidedAction.ACTION_ID_NEXT) {
+ return "next";
+ } else if (actionId == GuidedAction.ACTION_ID_CURRENT) {
+ return "current";
+ } else if (actionId == GuidedAction.ACTION_ID_OK) {
+ return "ok";
+ } else if (actionId == GuidedAction.ACTION_ID_CANCEL) {
+ return "cancel";
+ } else if (actionId == GuidedAction.ACTION_ID_FINISH) {
+ return "finish";
+ } else if (actionId == GuidedAction.ACTION_ID_CONTINUE) {
+ return "continue";
+ } else if (actionId == GuidedAction.ACTION_ID_YES) {
+ return "yes";
+ } else if (actionId == GuidedAction.ACTION_ID_NO) {
+ return "no";
+ } else {
+ return "unknown-" + actionId;
+ }
+ }
+
+ /** Delegated from {@link #onGuidedActionClicked(GuidedAction)} */
+ public abstract void onTrackedGuidedActionClicked(GuidedAction action);
+
+ /** The prefix used for analytics tracking, Usually the class name. */
+ public abstract String getTrackerPrefix();
+}
diff --git a/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java b/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java
new file mode 100644
index 00000000..38a78f5d
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/ActionPresenterSelector.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.graphics.drawable.Drawable;
+import android.support.v17.leanback.R;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+// This class is adapted from Leanback's library, which does not support action icon with one-line
+// label. This class modified its getPresenter method to support the above situation.
+class ActionPresenterSelector extends PresenterSelector {
+ private final Presenter mOneLineActionPresenter = new OneLineActionPresenter();
+ private final Presenter mTwoLineActionPresenter = new TwoLineActionPresenter();
+ private final Presenter[] mPresenters = new Presenter[] {
+ mOneLineActionPresenter, mTwoLineActionPresenter};
+
+ @Override
+ public Presenter getPresenter(Object item) {
+ Action action = (Action) item;
+ if (TextUtils.isEmpty(action.getLabel2()) && action.getIcon() == null) {
+ return mOneLineActionPresenter;
+ } else {
+ return mTwoLineActionPresenter;
+ }
+ }
+
+ @Override
+ public Presenter[] getPresenters() {
+ return mPresenters;
+ }
+
+ static class ActionViewHolder extends Presenter.ViewHolder {
+ Action mAction;
+ Button mButton;
+ int mLayoutDirection;
+
+ public ActionViewHolder(View view, int layoutDirection) {
+ super(view);
+ mButton = (Button) view.findViewById(R.id.lb_action_button);
+ mLayoutDirection = layoutDirection;
+ }
+ }
+
+ class OneLineActionPresenter extends Presenter {
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent) {
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.lb_action_1_line, parent, false);
+ return new ActionViewHolder(v, parent.getLayoutDirection());
+ }
+
+ @Override
+ public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
+ Action action = (Action) item;
+ ActionViewHolder vh = (ActionViewHolder) viewHolder;
+ vh.mAction = action;
+ vh.mButton.setText(action.getLabel1());
+ }
+
+ @Override
+ public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
+ ((ActionViewHolder) viewHolder).mAction = null;
+ }
+ }
+
+ class TwoLineActionPresenter extends Presenter {
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent) {
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.lb_action_2_lines, parent, false);
+ return new ActionViewHolder(v, parent.getLayoutDirection());
+ }
+
+ @Override
+ public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
+ Action action = (Action) item;
+ ActionViewHolder vh = (ActionViewHolder) viewHolder;
+ Drawable icon = action.getIcon();
+ vh.mAction = action;
+
+ if (icon != null) {
+ final int startPadding = vh.view.getResources()
+ .getDimensionPixelSize(R.dimen.lb_action_with_icon_padding_start);
+ final int endPadding = vh.view.getResources()
+ .getDimensionPixelSize(R.dimen.lb_action_with_icon_padding_end);
+ vh.view.setPaddingRelative(startPadding, 0, endPadding, 0);
+ } else {
+ final int padding = vh.view.getResources()
+ .getDimensionPixelSize(R.dimen.lb_action_padding_horizontal);
+ vh.view.setPaddingRelative(padding, 0, padding, 0);
+ }
+ vh.mButton.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
+
+ CharSequence line1 = action.getLabel1();
+ CharSequence line2 = action.getLabel2();
+ if (TextUtils.isEmpty(line1)) {
+ vh.mButton.setText(line2);
+ } else if (TextUtils.isEmpty(line2)) {
+ vh.mButton.setText(line1);
+ } else {
+ vh.mButton.setText(line1 + "\n" + line2);
+ }
+ }
+
+ @Override
+ public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
+ ActionViewHolder vh = (ActionViewHolder) viewHolder;
+ vh.mButton.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null);
+ vh.view.setPadding(0, 0, 0, 0);
+ vh.mAction = null;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
new file mode 100644
index 00000000..bf18ddc0
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/CurrentRecordingDetailsFragment.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dialog.HalfSizedDialogFragment;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ui.DvrStopRecordingFragment;
+import com.android.tv.dvr.ui.DvrUiHelper;
+
+/**
+ * {@link RecordingDetailsFragment} for current recording in DVR.
+ */
+public class CurrentRecordingDetailsFragment extends RecordingDetailsFragment {
+ private static final int ACTION_STOP_RECORDING = 1;
+
+ private DvrDataManager mDvrDataManger;
+ private final DvrDataManager.ScheduledRecordingListener mScheduledRecordingListener =
+ new DvrDataManager.ScheduledRecordingListener() {
+ @Override
+ public void onScheduledRecordingAdded(ScheduledRecording... schedules) { }
+
+ @Override
+ public void onScheduledRecordingRemoved(ScheduledRecording... schedules) {
+ for (ScheduledRecording schedule : schedules) {
+ if (schedule.getId() == getRecording().getId()) {
+ getActivity().finish();
+ return;
+ }
+ }
+ }
+
+ @Override
+ public void onScheduledRecordingStatusChanged(ScheduledRecording... schedules) {
+ for (ScheduledRecording schedule : schedules) {
+ if (schedule.getId() == getRecording().getId()
+ && schedule.getState()
+ != ScheduledRecording.STATE_RECORDING_IN_PROGRESS) {
+ getActivity().finish();
+ return;
+ }
+ }
+ }
+ };
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mDvrDataManger = TvApplication.getSingletons(context).getDvrDataManager();
+ mDvrDataManger.addScheduledRecordingListener(mScheduledRecordingListener);
+ }
+
+ @Override
+ protected SparseArrayObjectAdapter onCreateActionsAdapter() {
+ SparseArrayObjectAdapter adapter =
+ new SparseArrayObjectAdapter(new ActionPresenterSelector());
+ Resources res = getResources();
+ adapter.set(ACTION_STOP_RECORDING, new Action(ACTION_STOP_RECORDING,
+ res.getString(R.string.dvr_detail_stop_recording), null,
+ res.getDrawable(R.drawable.lb_ic_stop)));
+ return adapter;
+ }
+
+ @Override
+ protected OnActionClickedListener onCreateOnActionClickedListener() {
+ return new OnActionClickedListener() {
+ @Override
+ public void onActionClicked(Action action) {
+ if (action.getId() == ACTION_STOP_RECORDING) {
+ DvrUiHelper.showStopRecordingDialog(getActivity(),
+ getRecording().getChannelId(),
+ DvrStopRecordingFragment.REASON_USER_STOP,
+ new HalfSizedDialogFragment.OnActionClickListener() {
+ @Override
+ public void onActionClick(long actionId) {
+ if (actionId == DvrStopRecordingFragment.ACTION_STOP) {
+ DvrManager dvrManager =
+ TvApplication.getSingletons(getContext())
+ .getDvrManager();
+ dvrManager.stopRecording(getRecording());
+ getActivity().finish();
+ }
+ }
+ });
+ }
+ }
+ };
+ }
+
+ @Override
+ public void onDetach() {
+ if (mDvrDataManger != null) {
+ mDvrDataManger.removeScheduledRecordingListener(mScheduledRecordingListener);
+ }
+ super.onDetach();
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsContent.java b/src/com/android/tv/dvr/ui/browse/DetailsContent.java
new file mode 100644
index 00000000..c1fa05d7
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/DetailsContent.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.content.Context;
+import android.media.tv.TvContract;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.data.Channel;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.ui.DvrUiHelper;
+
+/**
+ * A class for details content.
+ */
+class DetailsContent {
+ /** Constant for invalid time. */
+ public static final long INVALID_TIME = -1;
+
+ private CharSequence mTitle;
+ private long mStartTimeUtcMillis;
+ private long mEndTimeUtcMillis;
+ private String mDescription;
+ private String mLogoImageUri;
+ private String mBackgroundImageUri;
+ private boolean mUsingChannelLogo;
+
+ static DetailsContent createFromRecordedProgram(Context context,
+ RecordedProgram recordedProgram) {
+ return new DetailsContent.Builder()
+ .setChannelId(recordedProgram.getChannelId())
+ .setProgramTitle(recordedProgram.getTitle())
+ .setSeasonNumber(recordedProgram.getSeasonNumber())
+ .setEpisodeNumber(recordedProgram.getEpisodeNumber())
+ .setStartTimeUtcMillis(recordedProgram.getStartTimeUtcMillis())
+ .setEndTimeUtcMillis(recordedProgram.getEndTimeUtcMillis())
+ .setDescription(TextUtils.isEmpty(recordedProgram.getLongDescription())
+ ? recordedProgram.getDescription() : recordedProgram.getLongDescription())
+ .setPosterArtUri(recordedProgram.getPosterArtUri())
+ .setThumbnailUri(recordedProgram.getThumbnailUri())
+ .build(context);
+ }
+
+ static DetailsContent createFromSeriesRecording(Context context,
+ SeriesRecording seriesRecording) {
+ return new DetailsContent.Builder()
+ .setChannelId(seriesRecording.getChannelId())
+ .setTitle(seriesRecording.getTitle())
+ .setDescription(TextUtils.isEmpty(seriesRecording.getLongDescription())
+ ? seriesRecording.getDescription() : seriesRecording.getLongDescription())
+ .setPosterArtUri(seriesRecording.getPosterUri())
+ .setThumbnailUri(seriesRecording.getPhotoUri())
+ .build(context);
+ }
+
+ static DetailsContent createFromScheduledRecording(Context context,
+ ScheduledRecording scheduledRecording) {
+ Channel channel = TvApplication.getSingletons(context).getChannelDataManager()
+ .getChannel(scheduledRecording.getChannelId());
+ String description = !TextUtils.isEmpty(scheduledRecording.getProgramDescription()) ?
+ scheduledRecording.getProgramDescription()
+ : scheduledRecording.getProgramLongDescription();
+ if (TextUtils.isEmpty(description)) {
+ description = channel != null ? channel.getDescription() : null;
+ }
+ return new DetailsContent.Builder()
+ .setChannelId(scheduledRecording.getChannelId())
+ .setProgramTitle(scheduledRecording.getProgramTitle())
+ .setSeasonNumber(scheduledRecording.getSeasonNumber())
+ .setEpisodeNumber(scheduledRecording.getEpisodeNumber())
+ .setStartTimeUtcMillis(scheduledRecording.getStartTimeMs())
+ .setEndTimeUtcMillis(scheduledRecording.getEndTimeMs())
+ .setDescription(description)
+ .setPosterArtUri(scheduledRecording.getProgramPosterArtUri())
+ .setThumbnailUri(scheduledRecording.getProgramThumbnailUri())
+ .build(context);
+ }
+
+ private DetailsContent() { }
+
+ /**
+ * Returns title.
+ */
+ public CharSequence getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Returns start time.
+ */
+ public long getStartTimeUtcMillis() {
+ return mStartTimeUtcMillis;
+ }
+
+ /**
+ * Returns end time.
+ */
+ public long getEndTimeUtcMillis() {
+ return mEndTimeUtcMillis;
+ }
+
+ /**
+ * Returns description.
+ */
+ public String getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Returns Logo image URI as a String.
+ */
+ public String getLogoImageUri() {
+ return mLogoImageUri;
+ }
+
+ /**
+ * Returns background image URI as a String.
+ */
+ public String getBackgroundImageUri() {
+ return mBackgroundImageUri;
+ }
+
+ /**
+ * Returns if image URIs are from its channels' logo.
+ */
+ public boolean isUsingChannelLogo() {
+ return mUsingChannelLogo;
+ }
+
+ /**
+ * Copies other details content.
+ */
+ public void copyFrom(DetailsContent other) {
+ if (this == other) {
+ return;
+ }
+ mTitle = other.mTitle;
+ mStartTimeUtcMillis = other.mStartTimeUtcMillis;
+ mEndTimeUtcMillis = other.mEndTimeUtcMillis;
+ mDescription = other.mDescription;
+ mLogoImageUri = other.mLogoImageUri;
+ mBackgroundImageUri = other.mBackgroundImageUri;
+ mUsingChannelLogo = other.mUsingChannelLogo;
+ }
+
+ /**
+ * A class for building details content.
+ */
+ public static final class Builder {
+ private final DetailsContent mDetailsContent;
+
+ private long mChannelId;
+ private String mProgramTitle;
+ private String mSeasonNumber;
+ private String mEpisodeNumber;
+ private String mPosterArtUri;
+ private String mThumbnailUri;
+
+ public Builder() {
+ mDetailsContent = new DetailsContent();
+ mDetailsContent.mStartTimeUtcMillis = INVALID_TIME;
+ mDetailsContent.mEndTimeUtcMillis = INVALID_TIME;
+ }
+
+ /**
+ * Sets title.
+ */
+ public Builder setTitle(CharSequence title) {
+ mDetailsContent.mTitle = title;
+ return this;
+ }
+
+ /**
+ * Sets start time.
+ */
+ public Builder setStartTimeUtcMillis(long startTimeUtcMillis) {
+ mDetailsContent.mStartTimeUtcMillis = startTimeUtcMillis;
+ return this;
+ }
+
+ /**
+ * Sets end time.
+ */
+ public Builder setEndTimeUtcMillis(long endTimeUtcMillis) {
+ mDetailsContent.mEndTimeUtcMillis = endTimeUtcMillis;
+ return this;
+ }
+
+ /**
+ * Sets description.
+ */
+ public Builder setDescription(String description) {
+ mDetailsContent.mDescription = description;
+ return this;
+ }
+
+ /**
+ * Sets logo image URI as a String.
+ */
+ public Builder setLogoImageUri(String logoImageUri) {
+ mDetailsContent.mLogoImageUri = logoImageUri;
+ return this;
+ }
+
+ /**
+ * Sets background image URI as a String.
+ */
+ public Builder setBackgroundImageUri(String backgroundImageUri) {
+ mDetailsContent.mBackgroundImageUri = backgroundImageUri;
+ return this;
+ }
+
+ private Builder setProgramTitle(String programTitle) {
+ mProgramTitle = programTitle;
+ return this;
+ }
+
+ private Builder setSeasonNumber(String seasonNumber) {
+ mSeasonNumber = seasonNumber;
+ return this;
+ }
+
+ private Builder setEpisodeNumber(String episodeNumber) {
+ mEpisodeNumber = episodeNumber;
+ return this;
+ }
+
+ private Builder setChannelId(long channelId) {
+ mChannelId = channelId;
+ return this;
+ }
+
+ private Builder setPosterArtUri(String posterArtUri) {
+ mPosterArtUri = posterArtUri;
+ return this;
+ }
+
+ private Builder setThumbnailUri(String thumbnailUri) {
+ mThumbnailUri = thumbnailUri;
+ return this;
+ }
+
+ private void createStyledTitle(Context context, Channel channel) {
+ CharSequence title = DvrUiHelper.getStyledTitleWithEpisodeNumber(context,
+ mProgramTitle, mSeasonNumber, mEpisodeNumber,
+ R.style.text_appearance_card_view_episode_number);
+ if (TextUtils.isEmpty(title)) {
+ mDetailsContent.mTitle = channel != null ? channel.getDisplayName()
+ : context.getResources().getString(R.string.no_program_information);
+ } else {
+ mDetailsContent.mTitle = title;
+ }
+ }
+
+ private void createImageUris(@Nullable Channel channel) {
+ mDetailsContent.mLogoImageUri = null;
+ mDetailsContent.mBackgroundImageUri = null;
+ mDetailsContent.mUsingChannelLogo = false;
+ if (!TextUtils.isEmpty(mPosterArtUri) && !TextUtils.isEmpty(mThumbnailUri)) {
+ mDetailsContent.mLogoImageUri = mPosterArtUri;
+ mDetailsContent.mBackgroundImageUri = mThumbnailUri;
+ } else if (!TextUtils.isEmpty(mPosterArtUri)) {
+ // thumbnailUri is empty
+ mDetailsContent.mLogoImageUri = mPosterArtUri;
+ mDetailsContent.mBackgroundImageUri = mPosterArtUri;
+ } else if (!TextUtils.isEmpty(mThumbnailUri)) {
+ // posterArtUri is empty
+ mDetailsContent.mLogoImageUri = mThumbnailUri;
+ mDetailsContent.mBackgroundImageUri = mThumbnailUri;
+ }
+ if (TextUtils.isEmpty(mDetailsContent.mLogoImageUri) && channel != null) {
+ String channelLogoUri = TvContract.buildChannelLogoUri(channel.getId())
+ .toString();
+ mDetailsContent.mLogoImageUri = channelLogoUri;
+ mDetailsContent.mBackgroundImageUri = channelLogoUri;
+ mDetailsContent.mUsingChannelLogo = true;
+ }
+ }
+
+ /**
+ * Builds details content.
+ */
+ public DetailsContent build(Context context) {
+ Channel channel = TvApplication.getSingletons(context).getChannelDataManager()
+ .getChannel(mChannelId);
+ if (mDetailsContent.mTitle == null) {
+ createStyledTitle(context, channel);
+ }
+ if (mDetailsContent.mBackgroundImageUri == null
+ && mDetailsContent.mLogoImageUri == null) {
+ createImageUris(channel);
+ }
+ DetailsContent detailsContent = new DetailsContent();
+ detailsContent.copyFrom(mDetailsContent);
+ return detailsContent;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java b/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java
new file mode 100644
index 00000000..09b57887
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/DetailsContentPresenter.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.app.Activity;
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.content.Context;
+import android.graphics.Paint;
+import android.graphics.Paint.FontMetricsInt;
+import android.support.v17.leanback.widget.Presenter;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.tv.R;
+import com.android.tv.ui.ViewUtils;
+import com.android.tv.util.Utils;
+
+/**
+ * An {@link Presenter} for rendering a detailed description of an DVR item.
+ * Typically this Presenter will be used in a
+ * {@link android.support.v17.leanback.widget.DetailsOverviewRowPresenter}.
+ * Most codes of this class is originated from
+ * {@link android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter}.
+ * The latter class are re-used to provide a customized version of
+ * {@link android.support.v17.leanback.widget.DetailsOverviewRow}.
+ */
+class DetailsContentPresenter extends Presenter {
+ /**
+ * The ViewHolder for the {@link DetailsContentPresenter}.
+ */
+ public static class ViewHolder extends Presenter.ViewHolder {
+ final TextView mTitle;
+ final TextView mSubtitle;
+ final LinearLayout mDescriptionContainer;
+ final TextView mBody;
+ final TextView mReadMoreView;
+ final int mTitleMargin;
+ final int mUnderTitleBaselineMargin;
+ final int mUnderSubtitleBaselineMargin;
+ final int mTitleLineSpacing;
+ final int mBodyLineSpacing;
+ final int mBodyMaxLines;
+ final int mBodyMinLines;
+ final FontMetricsInt mTitleFontMetricsInt;
+ final FontMetricsInt mSubtitleFontMetricsInt;
+ final FontMetricsInt mBodyFontMetricsInt;
+ final int mTitleMaxLines;
+
+ private Activity mActivity;
+ private boolean mFullTextMode;
+ private int mFullTextAnimationDuration;
+ private boolean mIsListeningToPreDraw;
+
+ private ViewTreeObserver.OnPreDrawListener mPreDrawListener =
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ if (mSubtitle.getVisibility() == View.VISIBLE
+ && mSubtitle.getTop() > view.getHeight()
+ && mTitle.getLineCount() > 1) {
+ mTitle.setMaxLines(mTitle.getLineCount() - 1);
+ return false;
+ }
+ final int bodyLines = mBody.getLineCount();
+ int maxLines = mFullTextMode ? bodyLines :
+ (mTitle.getLineCount() > 1 ? mBodyMinLines : mBodyMaxLines);
+ if (bodyLines > maxLines) {
+ mReadMoreView.setVisibility(View.VISIBLE);
+ mDescriptionContainer.setFocusable(true);
+ mDescriptionContainer.setClickable(true);
+ mDescriptionContainer.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mFullTextMode = true;
+ mReadMoreView.setVisibility(View.GONE);
+ mDescriptionContainer.setFocusable((
+ (AccessibilityManager) view.getContext()
+ .getSystemService(
+ Context.ACCESSIBILITY_SERVICE))
+ .isEnabled());
+ mDescriptionContainer.setClickable(false);
+ mDescriptionContainer.setOnClickListener(null);
+ int oldMaxLines = mBody.getMaxLines();
+ mBody.setMaxLines(bodyLines);
+ // Minus 1 from line difference to eliminate the space
+ // originally occupied by "READ MORE"
+ showFullText((bodyLines - oldMaxLines - 1) * mBodyLineSpacing);
+ }
+ });
+ }
+ if (mReadMoreView.getVisibility() == View.VISIBLE
+ && mSubtitle.getVisibility() == View.VISIBLE) {
+ // If both "READ MORE" and subtitle is shown, the capable maximum lines
+ // will be one line less.
+ maxLines -= 1;
+ }
+ if (mBody.getMaxLines() != maxLines) {
+ mBody.setMaxLines(maxLines);
+ return false;
+ } else {
+ removePreDrawListener();
+ return true;
+ }
+ }
+ };
+
+ public ViewHolder(final View view) {
+ super(view);
+ view.addOnAttachStateChangeListener(
+ new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ // In case predraw listener was removed in detach, make sure
+ // we have the proper layout.
+ addPreDrawListener();
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ removePreDrawListener();
+ }
+ });
+ mTitle = (TextView) view.findViewById(R.id.dvr_details_description_title);
+ mSubtitle = (TextView) view.findViewById(R.id.dvr_details_description_subtitle);
+ mBody = (TextView) view.findViewById(R.id.dvr_details_description_body);
+ mDescriptionContainer =
+ (LinearLayout) view.findViewById(R.id.dvr_details_description_container);
+ // We have to explicitly set focusable to true here for accessibility, since we might
+ // set the view's focusable state when we need to show "READ MORE", which would remove
+ // the default focusable state for accessibility.
+ mDescriptionContainer.setFocusable(((AccessibilityManager) view.getContext()
+ .getSystemService(Context.ACCESSIBILITY_SERVICE)).isEnabled());
+ mReadMoreView = (TextView) view.findViewById(R.id.dvr_details_description_read_more);
+
+ FontMetricsInt titleFontMetricsInt = getFontMetricsInt(mTitle);
+ final int titleAscent = view.getResources().getDimensionPixelSize(
+ R.dimen.lb_details_description_title_baseline);
+ // Ascent is negative
+ mTitleMargin = titleAscent + titleFontMetricsInt.ascent;
+
+ mUnderTitleBaselineMargin = view.getResources().getDimensionPixelSize(
+ R.dimen.lb_details_description_under_title_baseline_margin);
+ mUnderSubtitleBaselineMargin = view.getResources().getDimensionPixelSize(
+ R.dimen.dvr_details_description_under_subtitle_baseline_margin);
+
+ mTitleLineSpacing = view.getResources().getDimensionPixelSize(
+ R.dimen.lb_details_description_title_line_spacing);
+ mBodyLineSpacing = view.getResources().getDimensionPixelSize(
+ R.dimen.lb_details_description_body_line_spacing);
+
+ mBodyMaxLines = view.getResources().getInteger(
+ R.integer.lb_details_description_body_max_lines);
+ mBodyMinLines = view.getResources().getInteger(
+ R.integer.lb_details_description_body_min_lines);
+ mTitleMaxLines = mTitle.getMaxLines();
+
+ mTitleFontMetricsInt = getFontMetricsInt(mTitle);
+ mSubtitleFontMetricsInt = getFontMetricsInt(mSubtitle);
+ mBodyFontMetricsInt = getFontMetricsInt(mBody);
+ }
+
+ void addPreDrawListener() {
+ if (!mIsListeningToPreDraw) {
+ mIsListeningToPreDraw = true;
+ view.getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
+ }
+ }
+
+ void removePreDrawListener() {
+ if (mIsListeningToPreDraw) {
+ view.getViewTreeObserver().removeOnPreDrawListener(mPreDrawListener);
+ mIsListeningToPreDraw = false;
+ }
+ }
+
+ public TextView getTitle() {
+ return mTitle;
+ }
+
+ public TextView getSubtitle() {
+ return mSubtitle;
+ }
+
+ public TextView getBody() {
+ return mBody;
+ }
+
+ private FontMetricsInt getFontMetricsInt(TextView textView) {
+ Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ paint.setTextSize(textView.getTextSize());
+ paint.setTypeface(textView.getTypeface());
+ return paint.getFontMetricsInt();
+ }
+
+ private void showFullText(int heightDiff) {
+ final ViewGroup detailsFrame = (ViewGroup) mActivity.findViewById(R.id.details_frame);
+ int nowHeight = ViewUtils.getLayoutHeight(detailsFrame);
+ Animator expandAnimator = ViewUtils.createHeightAnimator(
+ detailsFrame, nowHeight, nowHeight + heightDiff);
+ expandAnimator.setDuration(mFullTextAnimationDuration);
+ Animator shiftAnimator = ObjectAnimator.ofPropertyValuesHolder(detailsFrame,
+ PropertyValuesHolder.ofFloat(View.TRANSLATION_Y,
+ 0f, -(heightDiff / 2)));
+ shiftAnimator.setDuration(mFullTextAnimationDuration);
+ AnimatorSet fullTextAnimator = new AnimatorSet();
+ fullTextAnimator.playTogether(expandAnimator, shiftAnimator);
+ fullTextAnimator.start();
+ }
+ }
+
+ private final Activity mActivity;
+ private final int mFullTextAnimationDuration;
+
+ public DetailsContentPresenter(Activity activity) {
+ super();
+ mActivity = activity;
+ mFullTextAnimationDuration = mActivity.getResources()
+ .getInteger(R.integer.dvr_details_full_text_animation_duration);
+ }
+
+ @Override
+ public final ViewHolder onCreateViewHolder(ViewGroup parent) {
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.dvr_details_description, parent, false);
+ return new ViewHolder(v);
+ }
+
+ @Override
+ public final void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
+ final ViewHolder vh = (ViewHolder) viewHolder;
+ final DetailsContent detailsContent = (DetailsContent) item;
+
+ vh.mActivity = mActivity;
+ vh.mFullTextAnimationDuration = mFullTextAnimationDuration;
+
+ boolean hasTitle = true;
+ if (TextUtils.isEmpty(detailsContent.getTitle())) {
+ vh.mTitle.setVisibility(View.GONE);
+ hasTitle = false;
+ } else {
+ vh.mTitle.setText(detailsContent.getTitle());
+ vh.mTitle.setVisibility(View.VISIBLE);
+ vh.mTitle.setLineSpacing(vh.mTitleLineSpacing - vh.mTitle.getLineHeight()
+ + vh.mTitle.getLineSpacingExtra(), vh.mTitle.getLineSpacingMultiplier());
+ vh.mTitle.setMaxLines(vh.mTitleMaxLines);
+ }
+ setTopMargin(vh.mTitle, vh.mTitleMargin);
+
+ boolean hasSubtitle = true;
+ if (detailsContent.getStartTimeUtcMillis() != DetailsContent.INVALID_TIME
+ && detailsContent.getEndTimeUtcMillis() != DetailsContent.INVALID_TIME) {
+ vh.mSubtitle.setText(Utils.getDurationString(viewHolder.view.getContext(),
+ detailsContent.getStartTimeUtcMillis(),
+ detailsContent.getEndTimeUtcMillis(), false));
+ vh.mSubtitle.setVisibility(View.VISIBLE);
+ if (hasTitle) {
+ setTopMargin(vh.mSubtitle, vh.mUnderTitleBaselineMargin
+ + vh.mSubtitleFontMetricsInt.ascent - vh.mTitleFontMetricsInt.descent);
+ } else {
+ setTopMargin(vh.mSubtitle, 0);
+ }
+ } else {
+ vh.mSubtitle.setVisibility(View.GONE);
+ hasSubtitle = false;
+ }
+
+ if (TextUtils.isEmpty(detailsContent.getDescription())) {
+ vh.mBody.setVisibility(View.GONE);
+ } else {
+ vh.mBody.setText(detailsContent.getDescription());
+ vh.mBody.setVisibility(View.VISIBLE);
+ vh.mBody.setLineSpacing(vh.mBodyLineSpacing - vh.mBody.getLineHeight()
+ + vh.mBody.getLineSpacingExtra(), vh.mBody.getLineSpacingMultiplier());
+ if (hasSubtitle) {
+ setTopMargin(vh.mDescriptionContainer, vh.mUnderSubtitleBaselineMargin
+ + vh.mBodyFontMetricsInt.ascent - vh.mSubtitleFontMetricsInt.descent
+ - vh.mBody.getPaddingTop());
+ } else if (hasTitle) {
+ setTopMargin(vh.mDescriptionContainer, vh.mUnderTitleBaselineMargin
+ + vh.mBodyFontMetricsInt.ascent - vh.mTitleFontMetricsInt.descent
+ - vh.mBody.getPaddingTop());
+ } else {
+ setTopMargin(vh.mDescriptionContainer, 0);
+ }
+ }
+ }
+
+ @Override
+ public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { }
+
+ private void setTopMargin(View view, int topMargin) {
+ ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
+ lp.topMargin = topMargin;
+ view.setLayoutParams(lp);
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java b/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java
new file mode 100644
index 00000000..82fe9ce3
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/DetailsViewBackgroundHelper.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.app.Activity;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.support.v17.leanback.app.BackgroundManager;
+
+/**
+ * The Background Helper.
+ */
+class DetailsViewBackgroundHelper {
+ // Background delay serves to avoid kicking off expensive bitmap loading
+ // in case multiple backgrounds are set in quick succession.
+ private static final int SET_BACKGROUND_DELAY_MS = 100;
+
+ private final BackgroundManager mBackgroundManager;
+
+ class LoadBackgroundRunnable implements Runnable {
+ final Drawable mBackGround;
+
+ LoadBackgroundRunnable(Drawable background) {
+ mBackGround = background;
+ }
+
+ @Override
+ public void run() {
+ if (!mBackgroundManager.isAttached()) {
+ return;
+ }
+ if (mBackGround instanceof BitmapDrawable) {
+ mBackgroundManager.setBitmap(((BitmapDrawable) mBackGround).getBitmap());
+ }
+ mRunnable = null;
+ }
+ }
+
+ private LoadBackgroundRunnable mRunnable;
+
+ private final Handler mHandler = new Handler();
+
+ public DetailsViewBackgroundHelper(Activity activity) {
+ mBackgroundManager = BackgroundManager.getInstance(activity);
+ mBackgroundManager.attach(activity.getWindow());
+ }
+
+ /**
+ * Sets the given image to background.
+ */
+ public void setBackground(Drawable background) {
+ if (mRunnable != null) {
+ mHandler.removeCallbacks(mRunnable);
+ }
+ mRunnable = new LoadBackgroundRunnable(background);
+ mHandler.postDelayed(mRunnable, SET_BACKGROUND_DELAY_MS);
+ }
+
+ /**
+ * Sets the background color.
+ */
+ public void setBackgroundColor(int color) {
+ if (mBackgroundManager.isAttached()) {
+ mBackgroundManager.setColor(color);
+ }
+ }
+
+ /**
+ * Sets the background scrim.
+ */
+ public void setScrim(int color) {
+ if (mBackgroundManager.isAttached()) {
+ mBackgroundManager.setDimLayer(new ColorDrawable(color));
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java b/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java
new file mode 100644
index 00000000..07eec107
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/DvrBrowseActivity.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.ui.browse;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.tv.TvInputManager;
+import android.os.Bundle;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+
+/**
+ * {@link android.app.Activity} for DVR UI.
+ */
+public class DvrBrowseActivity extends Activity {
+ private DvrBrowseFragment mFragment;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ TvApplication.setCurrentRunningProcess(this, true);
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.dvr_main);
+ mFragment = (DvrBrowseFragment) getFragmentManager().findFragmentById(R.id.dvr_frame);
+ handleIntent(getIntent());
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ handleIntent(intent);
+ }
+
+ private void handleIntent(Intent intent) {
+ if (TvInputManager.ACTION_VIEW_RECORDING_SCHEDULES.equals(intent.getAction())) {
+ mFragment.showScheduledRow();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java b/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
new file mode 100644
index 00000000..cb3a5745
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/DvrBrowseFragment.java
@@ -0,0 +1,665 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.ui.browse;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v17.leanback.app.BrowseFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.TitleViewAdapter;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.data.GenreItems;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener;
+import com.android.tv.dvr.DvrDataManager.OnRecordedProgramLoadFinishedListener;
+import com.android.tv.dvr.DvrDataManager.RecordedProgramListener;
+import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
+import com.android.tv.dvr.DvrDataManager.SeriesRecordingListener;
+import com.android.tv.dvr.DvrScheduleManager;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.ui.SortedArrayAdapter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * {@link BrowseFragment} for DVR functions.
+ */
+public class DvrBrowseFragment extends BrowseFragment implements
+ RecordedProgramListener, ScheduledRecordingListener, SeriesRecordingListener,
+ OnDvrScheduleLoadFinishedListener, OnRecordedProgramLoadFinishedListener {
+ private static final String TAG = "DvrBrowseFragment";
+ private static final boolean DEBUG = false;
+
+ private static final int MAX_RECENT_ITEM_COUNT = 10;
+ private static final int MAX_SCHEDULED_ITEM_COUNT = 4;
+
+ private boolean mShouldShowScheduleRow;
+ private boolean mEntranceTransitionEnded;
+
+ private RecordedProgramAdapter mRecentAdapter;
+ private ScheduleAdapter mScheduleAdapter;
+ private SeriesAdapter mSeriesAdapter;
+ private RecordedProgramAdapter[] mGenreAdapters =
+ new RecordedProgramAdapter[GenreItems.getGenreCount() + 1];
+ private ListRow mRecentRow;
+ private ListRow mScheduledRow;
+ private ListRow mSeriesRow;
+ private ListRow[] mGenreRows = new ListRow[GenreItems.getGenreCount() + 1];
+ private List<String> mGenreLabels;
+ private DvrDataManager mDvrDataManager;
+ private DvrScheduleManager mDvrScheudleManager;
+ private ArrayObjectAdapter mRowsAdapter;
+ private ClassPresenterSelector mPresenterSelector;
+ private final HashMap<String, RecordedProgram> mSeriesId2LatestProgram = new HashMap<>();
+ private final Handler mHandler = new Handler();
+ private final OnGlobalFocusChangeListener mOnGlobalFocusChangeListener =
+ new OnGlobalFocusChangeListener() {
+ @Override
+ public void onGlobalFocusChanged(View oldFocus, View newFocus) {
+ if (oldFocus instanceof RecordingCardView) {
+ ((RecordingCardView) oldFocus).expandTitle(false, true);
+ }
+ if (newFocus instanceof RecordingCardView) {
+ // If the header transition is ongoing, expand cards immediately without
+ // animation to make a smooth transition.
+ ((RecordingCardView) newFocus).expandTitle(true, !isInHeadersTransition());
+ }
+ }
+ };
+
+ private final Comparator<Object> RECORDED_PROGRAM_COMPARATOR = new Comparator<Object>() {
+ @Override
+ public int compare(Object lhs, Object rhs) {
+ if (lhs instanceof SeriesRecording) {
+ lhs = mSeriesId2LatestProgram.get(((SeriesRecording) lhs).getSeriesId());
+ }
+ if (rhs instanceof SeriesRecording) {
+ rhs = mSeriesId2LatestProgram.get(((SeriesRecording) rhs).getSeriesId());
+ }
+ if (lhs instanceof RecordedProgram) {
+ if (rhs instanceof RecordedProgram) {
+ return RecordedProgram.START_TIME_THEN_ID_COMPARATOR.reversed()
+ .compare((RecordedProgram) lhs, (RecordedProgram) rhs);
+ } else {
+ return -1;
+ }
+ } else if (rhs instanceof RecordedProgram) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ };
+
+ private static final Comparator<Object> SCHEDULE_COMPARATOR = new Comparator<Object>() {
+ @Override
+ public int compare(Object lhs, Object rhs) {
+ if (lhs instanceof ScheduledRecording) {
+ if (rhs instanceof ScheduledRecording) {
+ return ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR
+ .compare((ScheduledRecording) lhs, (ScheduledRecording) rhs);
+ } else {
+ return -1;
+ }
+ } else if (rhs instanceof ScheduledRecording) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ };
+
+ private final DvrScheduleManager.OnConflictStateChangeListener mOnConflictStateChangeListener =
+ new DvrScheduleManager.OnConflictStateChangeListener() {
+ @Override
+ public void onConflictStateChange(boolean conflict, ScheduledRecording... schedules) {
+ if (mScheduleAdapter != null) {
+ for (ScheduledRecording schedule : schedules) {
+ onScheduledRecordingConflictStatusChanged(schedule);
+ }
+ }
+ }
+ };
+
+ private final Runnable mUpdateRowsRunnable = new Runnable() {
+ @Override
+ public void run() {
+ updateRows();
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ if (DEBUG) Log.d(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+ Context context = getContext();
+ ApplicationSingletons singletons = TvApplication.getSingletons(context);
+ mDvrDataManager = singletons.getDvrDataManager();
+ mDvrScheudleManager = singletons.getDvrScheduleManager();
+ mPresenterSelector = new ClassPresenterSelector()
+ .addClassPresenter(ScheduledRecording.class,
+ new ScheduledRecordingPresenter(context))
+ .addClassPresenter(RecordedProgram.class, new RecordedProgramPresenter(context))
+ .addClassPresenter(SeriesRecording.class, new SeriesRecordingPresenter(context))
+ .addClassPresenter(FullScheduleCardHolder.class,
+ new FullSchedulesCardPresenter(context));
+ mGenreLabels = new ArrayList<>(Arrays.asList(GenreItems.getLabels(context)));
+ mGenreLabels.add(getString(R.string.dvr_main_others));
+ prepareUiElements();
+ if (!startBrowseIfDvrInitialized()) {
+ if (!mDvrDataManager.isDvrScheduleLoadFinished()) {
+ mDvrDataManager.addDvrScheduleLoadFinishedListener(this);
+ }
+ if (!mDvrDataManager.isRecordedProgramLoadFinished()) {
+ mDvrDataManager.addRecordedProgramLoadFinishedListener(this);
+ }
+ }
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ view.getViewTreeObserver().addOnGlobalFocusChangeListener(mOnGlobalFocusChangeListener);
+ }
+
+ @Override
+ public void onDestroyView() {
+ getView().getViewTreeObserver()
+ .removeOnGlobalFocusChangeListener(mOnGlobalFocusChangeListener);
+ super.onDestroyView();
+ }
+
+ @Override
+ public void onDestroy() {
+ if (DEBUG) Log.d(TAG, "onDestroy");
+ mHandler.removeCallbacks(mUpdateRowsRunnable);
+ mDvrScheudleManager.removeOnConflictStateChangeListener(mOnConflictStateChangeListener);
+ mDvrDataManager.removeRecordedProgramListener(this);
+ mDvrDataManager.removeScheduledRecordingListener(this);
+ mDvrDataManager.removeSeriesRecordingListener(this);
+ mDvrDataManager.removeDvrScheduleLoadFinishedListener(this);
+ mDvrDataManager.removeRecordedProgramLoadFinishedListener(this);
+ mRowsAdapter.clear();
+ mSeriesId2LatestProgram.clear();
+ for (Presenter presenter : mPresenterSelector.getPresenters()) {
+ if (presenter instanceof DvrItemPresenter) {
+ ((DvrItemPresenter) presenter).unbindAllViewHolders();
+ }
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ public void onDvrScheduleLoadFinished() {
+ startBrowseIfDvrInitialized();
+ mDvrDataManager.removeDvrScheduleLoadFinishedListener(this);
+ }
+
+ @Override
+ public void onRecordedProgramLoadFinished() {
+ startBrowseIfDvrInitialized();
+ mDvrDataManager.removeRecordedProgramLoadFinishedListener(this);
+ }
+
+ @Override
+ public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) {
+ for (RecordedProgram recordedProgram : recordedPrograms) {
+ handleRecordedProgramAdded(recordedProgram, true);
+ }
+ postUpdateRows();
+ }
+
+ @Override
+ public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) {
+ for (RecordedProgram recordedProgram : recordedPrograms) {
+ handleRecordedProgramChanged(recordedProgram);
+ }
+ postUpdateRows();
+ }
+
+ @Override
+ public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) {
+ for (RecordedProgram recordedProgram : recordedPrograms) {
+ handleRecordedProgramRemoved(recordedProgram);
+ }
+ postUpdateRows();
+ }
+
+ // No need to call updateRows() during ScheduledRecordings' change because
+ // the row for ScheduledRecordings is always displayed.
+ @Override
+ public void onScheduledRecordingAdded(ScheduledRecording... scheduledRecordings) {
+ for (ScheduledRecording scheduleRecording : scheduledRecordings) {
+ if (needToShowScheduledRecording(scheduleRecording)) {
+ mScheduleAdapter.add(scheduleRecording);
+ }
+ }
+ }
+
+ @Override
+ public void onScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings) {
+ for (ScheduledRecording scheduleRecording : scheduledRecordings) {
+ mScheduleAdapter.remove(scheduleRecording);
+ }
+ }
+
+ @Override
+ public void onScheduledRecordingStatusChanged(ScheduledRecording... scheduledRecordings) {
+ for (ScheduledRecording scheduleRecording : scheduledRecordings) {
+ if (needToShowScheduledRecording(scheduleRecording)) {
+ mScheduleAdapter.change(scheduleRecording);
+ } else {
+ mScheduleAdapter.removeWithId(scheduleRecording);
+ }
+ }
+ }
+
+ private void onScheduledRecordingConflictStatusChanged(ScheduledRecording... schedules) {
+ for (ScheduledRecording schedule : schedules) {
+ if (needToShowScheduledRecording(schedule)) {
+ if (mScheduleAdapter.contains(schedule)) {
+ mScheduleAdapter.change(schedule);
+ }
+ } else {
+ mScheduleAdapter.removeWithId(schedule);
+ }
+ }
+ }
+
+ @Override
+ public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) {
+ handleSeriesRecordingsAdded(Arrays.asList(seriesRecordings));
+ postUpdateRows();
+ }
+
+ @Override
+ public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) {
+ handleSeriesRecordingsRemoved(Arrays.asList(seriesRecordings));
+ postUpdateRows();
+ }
+
+ @Override
+ public void onSeriesRecordingChanged(SeriesRecording... seriesRecordings) {
+ handleSeriesRecordingsChanged(Arrays.asList(seriesRecordings));
+ postUpdateRows();
+ }
+
+ // Workaround of b/29108300
+ @Override
+ public void showTitle(int flags) {
+ flags &= ~TitleViewAdapter.SEARCH_VIEW_VISIBLE;
+ super.showTitle(flags);
+ }
+
+ @Override
+ protected void onEntranceTransitionEnd() {
+ super.onEntranceTransitionEnd();
+ if (mShouldShowScheduleRow) {
+ showScheduledRowInternal();
+ }
+ mEntranceTransitionEnded = true;
+ }
+
+ void showScheduledRow() {
+ if (!mEntranceTransitionEnded) {
+ setHeadersState(HEADERS_HIDDEN);
+ mShouldShowScheduleRow = true;
+ } else {
+ showScheduledRowInternal();
+ }
+ }
+
+ private void showScheduledRowInternal() {
+ setSelectedPosition(mRowsAdapter.indexOf(mScheduledRow), true, null);
+ if (getHeadersState() == HEADERS_ENABLED) {
+ startHeadersTransition(false);
+ }
+ mShouldShowScheduleRow = false;
+ }
+
+ private void prepareUiElements() {
+ setBadgeDrawable(getActivity().getDrawable(R.drawable.ic_dvr_badge));
+ setHeadersState(HEADERS_ENABLED);
+ setHeadersTransitionOnBackEnabled(false);
+ setBrandColor(getResources().getColor(R.color.program_guide_side_panel_background, null));
+ mRowsAdapter = new ArrayObjectAdapter(new DvrListRowPresenter(getContext()));
+ setAdapter(mRowsAdapter);
+ prepareEntranceTransition();
+ }
+
+ private boolean startBrowseIfDvrInitialized() {
+ if (mDvrDataManager.isInitialized()) {
+ // Setup rows
+ mRecentAdapter = new RecordedProgramAdapter(MAX_RECENT_ITEM_COUNT);
+ mScheduleAdapter = new ScheduleAdapter(MAX_SCHEDULED_ITEM_COUNT);
+ mSeriesAdapter = new SeriesAdapter();
+ for (int i = 0; i < mGenreAdapters.length; i++) {
+ mGenreAdapters[i] = new RecordedProgramAdapter();
+ }
+ // Schedule Recordings.
+ List<ScheduledRecording> schedules = mDvrDataManager.getAllScheduledRecordings();
+ onScheduledRecordingAdded(ScheduledRecording.toArray(schedules));
+ mScheduleAdapter.addExtraItem(FullScheduleCardHolder.FULL_SCHEDULE_CARD_HOLDER);
+ // Recorded Programs.
+ for (RecordedProgram recordedProgram : mDvrDataManager.getRecordedPrograms()) {
+ handleRecordedProgramAdded(recordedProgram, false);
+ }
+ // Series Recordings. Series recordings should be added after recorded programs, because
+ // we build series recordings' latest program information while adding recorded programs.
+ List<SeriesRecording> recordings = mDvrDataManager.getSeriesRecordings();
+ handleSeriesRecordingsAdded(recordings);
+ mRecentRow = new ListRow(new HeaderItem(
+ getString(R.string.dvr_main_recent)), mRecentAdapter);
+ mScheduledRow = new ListRow(new HeaderItem(
+ getString(R.string.dvr_main_scheduled)), mScheduleAdapter);
+ mSeriesRow = new ListRow(new HeaderItem(
+ getString(R.string.dvr_main_series)), mSeriesAdapter);
+ mRowsAdapter.add(mScheduledRow);
+ updateRows();
+ // Initialize listeners
+ mDvrDataManager.addRecordedProgramListener(this);
+ mDvrDataManager.addScheduledRecordingListener(this);
+ mDvrDataManager.addSeriesRecordingListener(this);
+ mDvrScheudleManager.addOnConflictStateChangeListener(mOnConflictStateChangeListener);
+ startEntranceTransition();
+ return true;
+ }
+ return false;
+ }
+
+ private void handleRecordedProgramAdded(RecordedProgram recordedProgram,
+ boolean updateSeriesRecording) {
+ mRecentAdapter.add(recordedProgram);
+ String seriesId = recordedProgram.getSeriesId();
+ SeriesRecording seriesRecording = null;
+ if (seriesId != null) {
+ seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
+ RecordedProgram latestProgram = mSeriesId2LatestProgram.get(seriesId);
+ if (latestProgram == null || RecordedProgram.START_TIME_THEN_ID_COMPARATOR
+ .compare(latestProgram, recordedProgram) < 0) {
+ mSeriesId2LatestProgram.put(seriesId, recordedProgram);
+ if (updateSeriesRecording && seriesRecording != null) {
+ onSeriesRecordingChanged(seriesRecording);
+ }
+ }
+ }
+ if (seriesRecording == null) {
+ for (RecordedProgramAdapter adapter
+ : getGenreAdapters(recordedProgram.getCanonicalGenres())) {
+ adapter.add(recordedProgram);
+ }
+ }
+ }
+
+ private void handleRecordedProgramRemoved(RecordedProgram recordedProgram) {
+ mRecentAdapter.remove(recordedProgram);
+ String seriesId = recordedProgram.getSeriesId();
+ if (seriesId != null) {
+ SeriesRecording seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
+ RecordedProgram latestProgram =
+ mSeriesId2LatestProgram.get(recordedProgram.getSeriesId());
+ if (latestProgram != null && latestProgram.getId() == recordedProgram.getId()) {
+ if (seriesRecording != null) {
+ updateLatestRecordedProgram(seriesRecording);
+ onSeriesRecordingChanged(seriesRecording);
+ }
+ }
+ }
+ for (RecordedProgramAdapter adapter
+ : getGenreAdapters(recordedProgram.getCanonicalGenres())) {
+ adapter.remove(recordedProgram);
+ }
+ }
+
+ private void handleRecordedProgramChanged(RecordedProgram recordedProgram) {
+ mRecentAdapter.change(recordedProgram);
+ String seriesId = recordedProgram.getSeriesId();
+ SeriesRecording seriesRecording = null;
+ if (seriesId != null) {
+ seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
+ RecordedProgram latestProgram = mSeriesId2LatestProgram.get(seriesId);
+ if (latestProgram == null || RecordedProgram.START_TIME_THEN_ID_COMPARATOR
+ .compare(latestProgram, recordedProgram) <= 0) {
+ mSeriesId2LatestProgram.put(seriesId, recordedProgram);
+ if (seriesRecording != null) {
+ onSeriesRecordingChanged(seriesRecording);
+ }
+ } else if (latestProgram.getId() == recordedProgram.getId()) {
+ if (seriesRecording != null) {
+ updateLatestRecordedProgram(seriesRecording);
+ onSeriesRecordingChanged(seriesRecording);
+ }
+ }
+ }
+ if (seriesRecording == null) {
+ updateGenreAdapters(getGenreAdapters(
+ recordedProgram.getCanonicalGenres()), recordedProgram);
+ } else {
+ updateGenreAdapters(new ArrayList<>(), recordedProgram);
+ }
+ }
+
+ private void handleSeriesRecordingsAdded(List<SeriesRecording> seriesRecordings) {
+ for (SeriesRecording seriesRecording : seriesRecordings) {
+ mSeriesAdapter.add(seriesRecording);
+ if (mSeriesId2LatestProgram.get(seriesRecording.getSeriesId()) != null) {
+ for (RecordedProgramAdapter adapter
+ : getGenreAdapters(seriesRecording.getCanonicalGenreIds())) {
+ adapter.add(seriesRecording);
+ }
+ }
+ }
+ }
+
+ private void handleSeriesRecordingsRemoved(List<SeriesRecording> seriesRecordings) {
+ for (SeriesRecording seriesRecording : seriesRecordings) {
+ mSeriesAdapter.remove(seriesRecording);
+ for (RecordedProgramAdapter adapter
+ : getGenreAdapters(seriesRecording.getCanonicalGenreIds())) {
+ adapter.remove(seriesRecording);
+ }
+ }
+ }
+
+ private void handleSeriesRecordingsChanged(List<SeriesRecording> seriesRecordings) {
+ for (SeriesRecording seriesRecording : seriesRecordings) {
+ mSeriesAdapter.change(seriesRecording);
+ if (mSeriesId2LatestProgram.get(seriesRecording.getSeriesId()) != null) {
+ updateGenreAdapters(getGenreAdapters(
+ seriesRecording.getCanonicalGenreIds()), seriesRecording);
+ } else {
+ // Remove series recording from all genre rows if it has no recorded program
+ updateGenreAdapters(new ArrayList<>(), seriesRecording);
+ }
+ }
+ }
+
+ private List<RecordedProgramAdapter> getGenreAdapters(String[] genres) {
+ List<RecordedProgramAdapter> result = new ArrayList<>();
+ if (genres == null || genres.length == 0) {
+ result.add(mGenreAdapters[mGenreAdapters.length - 1]);
+ } else {
+ for (String genre : genres) {
+ int genreId = GenreItems.getId(genre);
+ if(genreId >= mGenreAdapters.length) {
+ Log.d(TAG, "Wrong Genre ID: " + genreId);
+ } else {
+ result.add(mGenreAdapters[genreId]);
+ }
+ }
+ }
+ return result;
+ }
+
+ private List<RecordedProgramAdapter> getGenreAdapters(int[] genreIds) {
+ List<RecordedProgramAdapter> result = new ArrayList<>();
+ if (genreIds == null || genreIds.length == 0) {
+ result.add(mGenreAdapters[mGenreAdapters.length - 1]);
+ } else {
+ for (int genreId : genreIds) {
+ if(genreId >= mGenreAdapters.length) {
+ Log.d(TAG, "Wrong Genre ID: " + genreId);
+ } else {
+ result.add(mGenreAdapters[genreId]);
+ }
+ }
+ }
+ return result;
+ }
+
+ private void updateGenreAdapters(List<RecordedProgramAdapter> adapters, Object r) {
+ for (RecordedProgramAdapter adapter : mGenreAdapters) {
+ if (adapters.contains(adapter)) {
+ adapter.change(r);
+ } else {
+ adapter.remove(r);
+ }
+ }
+ }
+
+ private void postUpdateRows() {
+ mHandler.removeCallbacks(mUpdateRowsRunnable);
+ mHandler.post(mUpdateRowsRunnable);
+ }
+
+ private void updateRows() {
+ int visibleRowsCount = 1; // Schedule's Row will never be empty
+ if (mRecentAdapter.isEmpty()) {
+ mRowsAdapter.remove(mRecentRow);
+ } else {
+ if (mRowsAdapter.indexOf(mRecentRow) < 0) {
+ mRowsAdapter.add(0, mRecentRow);
+ }
+ visibleRowsCount++;
+ }
+ if (mSeriesAdapter.isEmpty()) {
+ mRowsAdapter.remove(mSeriesRow);
+ } else {
+ if (mRowsAdapter.indexOf(mSeriesRow) < 0) {
+ mRowsAdapter.add(visibleRowsCount, mSeriesRow);
+ }
+ visibleRowsCount++;
+ }
+ for (int i = 0; i < mGenreAdapters.length; i++) {
+ RecordedProgramAdapter adapter = mGenreAdapters[i];
+ if (adapter != null) {
+ if (adapter.isEmpty()) {
+ mRowsAdapter.remove(mGenreRows[i]);
+ } else {
+ if (mGenreRows[i] == null || mRowsAdapter.indexOf(mGenreRows[i]) < 0) {
+ mGenreRows[i] = new ListRow(new HeaderItem(mGenreLabels.get(i)), adapter);
+ mRowsAdapter.add(visibleRowsCount, mGenreRows[i]);
+ }
+ visibleRowsCount++;
+ }
+ }
+ }
+ }
+
+ private boolean needToShowScheduledRecording(ScheduledRecording recording) {
+ int state = recording.getState();
+ return state == ScheduledRecording.STATE_RECORDING_IN_PROGRESS
+ || state == ScheduledRecording.STATE_RECORDING_NOT_STARTED;
+ }
+
+ private void updateLatestRecordedProgram(SeriesRecording seriesRecording) {
+ RecordedProgram latestProgram = null;
+ for (RecordedProgram program :
+ mDvrDataManager.getRecordedPrograms(seriesRecording.getId())) {
+ if (latestProgram == null || RecordedProgram
+ .START_TIME_THEN_ID_COMPARATOR.compare(latestProgram, program) < 0) {
+ latestProgram = program;
+ }
+ }
+ mSeriesId2LatestProgram.put(seriesRecording.getSeriesId(), latestProgram);
+ }
+
+ private class ScheduleAdapter extends SortedArrayAdapter<Object> {
+ ScheduleAdapter(int maxItemCount) {
+ super(mPresenterSelector, SCHEDULE_COMPARATOR, maxItemCount);
+ }
+
+ @Override
+ public long getId(Object item) {
+ if (item instanceof ScheduledRecording) {
+ return ((ScheduledRecording) item).getId();
+ } else {
+ return -1;
+ }
+ }
+ }
+
+ private class SeriesAdapter extends SortedArrayAdapter<SeriesRecording> {
+ SeriesAdapter() {
+ super(mPresenterSelector, new Comparator<SeriesRecording>() {
+ @Override
+ public int compare(SeriesRecording lhs, SeriesRecording rhs) {
+ if (lhs.isStopped() && !rhs.isStopped()) {
+ return 1;
+ } else if (!lhs.isStopped() && rhs.isStopped()) {
+ return -1;
+ }
+ return SeriesRecording.PRIORITY_COMPARATOR.compare(lhs, rhs);
+ }
+ });
+ }
+
+ @Override
+ public long getId(SeriesRecording item) {
+ return item.getId();
+ }
+ }
+
+ private class RecordedProgramAdapter extends SortedArrayAdapter<Object> {
+ RecordedProgramAdapter() {
+ this(Integer.MAX_VALUE);
+ }
+
+ RecordedProgramAdapter(int maxItemCount) {
+ super(mPresenterSelector, RECORDED_PROGRAM_COMPARATOR, maxItemCount);
+ }
+
+ @Override
+ public long getId(Object item) {
+ // We takes the inverse number for the ID of recorded programs to make the ID stable.
+ if (item instanceof SeriesRecording) {
+ return ((SeriesRecording) item).getId();
+ } else if (item instanceof RecordedProgram) {
+ return -((RecordedProgram) item).getId() - 1;
+ } else {
+ return -1;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/DvrDetailsActivity.java b/src/com/android/tv/dvr/ui/browse/DvrDetailsActivity.java
new file mode 100644
index 00000000..35d21db8
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/DvrDetailsActivity.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v17.leanback.app.DetailsFragment;
+
+import android.transition.Transition;
+import android.transition.Transition.TransitionListener;
+import android.view.View;
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dialog.PinDialogFragment;
+
+/**
+ * Activity to show details view in DVR.
+ */
+public class DvrDetailsActivity extends Activity implements PinDialogFragment.OnPinCheckedListener {
+ /**
+ * Name of record id added to the Intent.
+ */
+ public static final String RECORDING_ID = "record_id";
+
+ /**
+ * Name of flag added to the Intent to determine if details view should hide "View schedule"
+ * button.
+ */
+ public static final String HIDE_VIEW_SCHEDULE = "hide_view_schedule";
+
+ /**
+ * Name of details view's type added to the intent.
+ */
+ public static final String DETAILS_VIEW_TYPE = "details_view_type";
+
+ /**
+ * Name of shared element between activities.
+ */
+ public static final String SHARED_ELEMENT_NAME = "shared_element";
+
+ /**
+ * CURRENT_RECORDING_VIEW refers to Current Recordings in DVR.
+ */
+ public static final int CURRENT_RECORDING_VIEW = 1;
+
+ /**
+ * SCHEDULED_RECORDING_VIEW refers to Scheduled Recordings in DVR.
+ */
+ public static final int SCHEDULED_RECORDING_VIEW = 2;
+
+ /**
+ * RECORDED_PROGRAM_VIEW refers to Recorded programs in DVR.
+ */
+ public static final int RECORDED_PROGRAM_VIEW = 3;
+
+ /**
+ * SERIES_RECORDING_VIEW refers to series recording in DVR.
+ */
+ public static final int SERIES_RECORDING_VIEW = 4;
+
+ private PinDialogFragment.OnPinCheckedListener mOnPinCheckedListener;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ TvApplication.setCurrentRunningProcess(this, true);
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_dvr_details);
+ long recordId = getIntent().getLongExtra(RECORDING_ID, -1);
+ int detailsViewType = getIntent().getIntExtra(DETAILS_VIEW_TYPE, -1);
+ boolean hideViewSchedule = getIntent().getBooleanExtra(HIDE_VIEW_SCHEDULE, false);
+ if (recordId != -1 && detailsViewType != -1 && savedInstanceState == null) {
+ Bundle args = new Bundle();
+ args.putLong(RECORDING_ID, recordId);
+ DetailsFragment detailsFragment = null;
+ if (detailsViewType == CURRENT_RECORDING_VIEW) {
+ detailsFragment = new CurrentRecordingDetailsFragment();
+ } else if (detailsViewType == SCHEDULED_RECORDING_VIEW) {
+ args.putBoolean(HIDE_VIEW_SCHEDULE, hideViewSchedule);
+ detailsFragment = new ScheduledRecordingDetailsFragment();
+ } else if (detailsViewType == RECORDED_PROGRAM_VIEW) {
+ detailsFragment = new RecordedProgramDetailsFragment();
+ } else if (detailsViewType == SERIES_RECORDING_VIEW) {
+ detailsFragment = new SeriesRecordingDetailsFragment();
+ }
+ detailsFragment.setArguments(args);
+ getFragmentManager().beginTransaction()
+ .replace(R.id.dvr_details_view_frame, detailsFragment).commit();
+ }
+
+ // This is a workaround for the focus on O device
+ addTransitionListener();
+ }
+
+ @Override
+ public void onPinChecked(boolean checked, int type, String rating) {
+ if (mOnPinCheckedListener != null) {
+ mOnPinCheckedListener.onPinChecked(checked, type, rating);
+ }
+ }
+
+ void setOnPinCheckListener(PinDialogFragment.OnPinCheckedListener listener) {
+ mOnPinCheckedListener = listener;
+ }
+
+ private void addTransitionListener() {
+ getWindow()
+ .getSharedElementEnterTransition()
+ .addListener(
+ new TransitionListener() {
+ @Override
+ public void onTransitionStart(Transition transition) {
+ // Do nothing
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ View actions = findViewById(R.id.details_overview_actions);
+ if (actions != null) {
+ actions.requestFocus();
+ }
+ }
+
+ @Override
+ public void onTransitionCancel(Transition transition) {
+ // Do nothing
+
+ }
+
+ @Override
+ public void onTransitionPause(Transition transition) {
+ // Do nothing
+ }
+
+ @Override
+ public void onTransitionResume(Transition transition) {
+ // Do nothing
+ }
+ });
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java
new file mode 100644
index 00000000..19fb7117
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/DvrDetailsFragment.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.media.tv.TvContentRating;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.DetailsOverviewRow;
+import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.support.v17.leanback.widget.VerticalGridView;
+import android.text.TextUtils;
+import android.widget.Toast;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.data.Channel;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.dialog.PinDialogFragment;
+import com.android.tv.dialog.PinDialogFragment.OnPinCheckedListener;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.ui.DvrUiHelper;
+import com.android.tv.parental.ParentalControlSettings;
+import com.android.tv.util.ImageLoader;
+import com.android.tv.util.ToastUtils;
+import com.android.tv.util.Utils;
+
+import java.io.File;
+
+abstract class DvrDetailsFragment extends DetailsFragment {
+ private static final int LOAD_LOGO_IMAGE = 1;
+ private static final int LOAD_BACKGROUND_IMAGE = 2;
+
+ protected DetailsViewBackgroundHelper mBackgroundHelper;
+ private ArrayObjectAdapter mRowsAdapter;
+ private DetailsOverviewRow mDetailsOverview;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (!onLoadRecordingDetails(getArguments())) {
+ getActivity().finish();
+ return;
+ }
+ mBackgroundHelper = new DetailsViewBackgroundHelper(getActivity());
+ setupAdapter();
+ onCreateInternal();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ // TODO: remove the workaround of b/30401180.
+ VerticalGridView container = (VerticalGridView) getActivity()
+ .findViewById(R.id.container_list);
+ // Need to manually modify offset. Please refer DetailsFragment.setVerticalGridViewLayout.
+ container.setItemAlignmentOffset(0);
+ container.setWindowAlignmentOffset(
+ getResources().getDimensionPixelSize(R.dimen.lb_details_rows_align_top));
+ }
+
+ private void setupAdapter() {
+ DetailsOverviewRowPresenter rowPresenter = new DetailsOverviewRowPresenter(
+ new DetailsContentPresenter(getActivity()));
+ rowPresenter.setBackgroundColor(getResources().getColor(R.color.common_tv_background,
+ null));
+ rowPresenter.setSharedElementEnterTransition(getActivity(),
+ DvrDetailsActivity.SHARED_ELEMENT_NAME);
+ rowPresenter.setOnActionClickedListener(onCreateOnActionClickedListener());
+ mRowsAdapter = new ArrayObjectAdapter(onCreatePresenterSelector(rowPresenter));
+ setAdapter(mRowsAdapter);
+ }
+
+ /**
+ * Returns details views' rows adapter.
+ */
+ protected ArrayObjectAdapter getRowsAdapter() {
+ return mRowsAdapter;
+ }
+
+ /**
+ * Sets details overview.
+ */
+ protected void setDetailsOverviewRow(DetailsContent detailsContent) {
+ mDetailsOverview = new DetailsOverviewRow(detailsContent);
+ mDetailsOverview.setActionsAdapter(onCreateActionsAdapter());
+ mRowsAdapter.add(mDetailsOverview);
+ onLoadLogoAndBackgroundImages(detailsContent);
+ }
+
+ /**
+ * Creates and returns presenter selector will be used by rows adaptor.
+ */
+ protected PresenterSelector onCreatePresenterSelector(
+ DetailsOverviewRowPresenter rowPresenter) {
+ ClassPresenterSelector presenterSelector = new ClassPresenterSelector();
+ presenterSelector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
+ return presenterSelector;
+ }
+
+ /**
+ * Does customized initialization of subclasses. Since {@link #onCreate(Bundle)} might finish
+ * activity early when it cannot fetch valid recordings, subclasses' onCreate method should not
+ * do anything after calling {@link #onCreate(Bundle)}. If there's something subclasses have to
+ * do after the super class did onCreate, it should override this method and put the codes here.
+ */
+ protected void onCreateInternal() { }
+
+ /**
+ * Updates actions of details overview.
+ */
+ protected void updateActions() {
+ mDetailsOverview.setActionsAdapter(onCreateActionsAdapter());
+ }
+
+ /**
+ * Loads recording details according to the arguments the fragment got.
+ *
+ * @return false if cannot find valid recordings, else return true. If the return value
+ * is false, the detail activity and fragment will be ended.
+ */
+ abstract boolean onLoadRecordingDetails(Bundle args);
+
+ /**
+ * Creates actions users can interact with and their adaptor for this fragment.
+ */
+ abstract SparseArrayObjectAdapter onCreateActionsAdapter();
+
+ /**
+ * Creates actions listeners to implement the behavior of the fragment after users click some
+ * action buttons.
+ */
+ abstract OnActionClickedListener onCreateOnActionClickedListener();
+
+ /**
+ * Loads logo and background images for detail fragments.
+ */
+ protected void onLoadLogoAndBackgroundImages(DetailsContent detailsContent) {
+ Drawable logoDrawable = null;
+ Drawable backgroundDrawable = null;
+ if (TextUtils.isEmpty(detailsContent.getLogoImageUri())) {
+ logoDrawable = getContext().getResources()
+ .getDrawable(R.drawable.dvr_default_poster, null);
+ mDetailsOverview.setImageDrawable(logoDrawable);
+ }
+ if (TextUtils.isEmpty(detailsContent.getBackgroundImageUri())) {
+ backgroundDrawable = getContext().getResources()
+ .getDrawable(R.drawable.dvr_default_poster, null);
+ mBackgroundHelper.setBackground(backgroundDrawable);
+ }
+ if (logoDrawable != null && backgroundDrawable != null) {
+ return;
+ }
+ if (logoDrawable == null && backgroundDrawable == null
+ && detailsContent.getLogoImageUri().equals(
+ detailsContent.getBackgroundImageUri())) {
+ ImageLoader.loadBitmap(getContext(), detailsContent.getLogoImageUri(),
+ new MyImageLoaderCallback(this, LOAD_LOGO_IMAGE | LOAD_BACKGROUND_IMAGE,
+ getContext()));
+ return;
+ }
+ if (logoDrawable == null) {
+ int imageWidth = getResources().getDimensionPixelSize(R.dimen.dvr_details_poster_width);
+ int imageHeight = getResources()
+ .getDimensionPixelSize(R.dimen.dvr_details_poster_height);
+ ImageLoader.loadBitmap(getContext(), detailsContent.getLogoImageUri(),
+ imageWidth, imageHeight,
+ new MyImageLoaderCallback(this, LOAD_LOGO_IMAGE, getContext()));
+ }
+ if (backgroundDrawable == null) {
+ ImageLoader.loadBitmap(getContext(), detailsContent.getBackgroundImageUri(),
+ new MyImageLoaderCallback(this, LOAD_BACKGROUND_IMAGE, getContext()));
+ }
+ }
+
+ protected void startPlayback(RecordedProgram recordedProgram, long seekTimeMs) {
+ if (Utils.isInBundledPackageSet(recordedProgram.getPackageName()) &&
+ !isDataUriAccessible(recordedProgram.getDataUri())) {
+ // Since cleaning RecordedProgram from forgotten storage will take some time,
+ // ignore playback until cleaning is finished.
+ ToastUtils.show(getContext(),
+ getContext().getResources().getString(R.string.dvr_toast_recording_deleted),
+ Toast.LENGTH_SHORT);
+ return;
+ }
+ long programId = recordedProgram.getId();
+ ParentalControlSettings parental = TvApplication.getSingletons(getActivity())
+ .getTvInputManagerHelper().getParentalControlSettings();
+ if (!parental.isParentalControlsEnabled()) {
+ DvrUiHelper.startPlaybackActivity(getContext(), programId, seekTimeMs, false);
+ return;
+ }
+ ChannelDataManager channelDataManager =
+ TvApplication.getSingletons(getActivity()).getChannelDataManager();
+ Channel channel = channelDataManager.getChannel(recordedProgram.getChannelId());
+ if (channel != null && channel.isLocked()) {
+ checkPinToPlay(recordedProgram, seekTimeMs);
+ return;
+ }
+ TvContentRating[] ratings = recordedProgram.getContentRatings();
+ TvContentRating blockRatings = parental.getBlockedRating(ratings);
+ if (blockRatings != null) {
+ checkPinToPlay(recordedProgram, seekTimeMs);
+ } else {
+ DvrUiHelper.startPlaybackActivity(getContext(), programId, seekTimeMs, false);
+ }
+ }
+
+ private boolean isDataUriAccessible(Uri dataUri) {
+ if (dataUri == null || dataUri.getPath() == null) {
+ return false;
+ }
+ try {
+ File recordedProgramPath = new File(dataUri.getPath());
+ if (recordedProgramPath.exists()) {
+ return true;
+ }
+ } catch (SecurityException e) {
+ }
+ return false;
+ }
+
+ private void checkPinToPlay(RecordedProgram recordedProgram, long seekTimeMs) {
+ SoftPreconditions.checkState(getActivity() instanceof DvrDetailsActivity);
+ if (getActivity() instanceof DvrDetailsActivity) {
+ ((DvrDetailsActivity) getActivity()).setOnPinCheckListener(new OnPinCheckedListener() {
+ @Override
+ public void onPinChecked(boolean checked, int type, String rating) {
+ ((DvrDetailsActivity) getActivity()).setOnPinCheckListener(null);
+ if (checked && type == PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_PROGRAM) {
+ DvrUiHelper.startPlaybackActivity(getContext(), recordedProgram.getId(),
+ seekTimeMs, true);
+ }
+ }
+ });
+ PinDialogFragment.create(PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_PROGRAM)
+ .show(getActivity().getFragmentManager(), PinDialogFragment.DIALOG_TAG);
+ }
+ }
+
+ private static class MyImageLoaderCallback extends
+ ImageLoader.ImageLoaderCallback<DvrDetailsFragment> {
+ private final Context mContext;
+ private final int mLoadType;
+
+ public MyImageLoaderCallback(DvrDetailsFragment fragment,
+ int loadType, Context context) {
+ super(fragment);
+ mLoadType = loadType;
+ mContext = context;
+ }
+
+ @Override
+ public void onBitmapLoaded(DvrDetailsFragment fragment,
+ @Nullable Bitmap bitmap) {
+ Drawable drawable;
+ int loadType = mLoadType;
+ if (bitmap == null) {
+ Resources res = mContext.getResources();
+ drawable = res.getDrawable(R.drawable.dvr_default_poster, null);
+ if ((loadType & LOAD_BACKGROUND_IMAGE) != 0 && !fragment.isDetached()) {
+ loadType &= ~LOAD_BACKGROUND_IMAGE;
+ fragment.mBackgroundHelper.setBackgroundColor(
+ res.getColor(R.color.dvr_detail_default_background));
+ fragment.mBackgroundHelper.setScrim(
+ res.getColor(R.color.dvr_detail_default_background_scrim));
+ }
+ } else {
+ drawable = new BitmapDrawable(mContext.getResources(), bitmap);
+ }
+ if (!fragment.isDetached()) {
+ if ((loadType & LOAD_LOGO_IMAGE) != 0) {
+ fragment.mDetailsOverview.setImageDrawable(drawable);
+ }
+ if ((loadType & LOAD_BACKGROUND_IMAGE) != 0) {
+ fragment.mBackgroundHelper.setBackground(drawable);
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java b/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java
new file mode 100644
index 00000000..df0e61c1
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/DvrItemPresenter.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.app.Activity;
+import android.content.Context;
+import android.support.annotation.CallSuper;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.dvr.ui.DvrUiHelper;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * An abstract class to present DVR items in {@link RecordingCardView}, which is mainly used in
+ * {@link DvrBrowseFragment}. DVR items might include:
+ * {@link com.android.tv.dvr.data.ScheduledRecording},
+ * {@link com.android.tv.dvr.data.RecordedProgram}, and
+ * {@link com.android.tv.dvr.data.SeriesRecording}.
+ */
+public abstract class DvrItemPresenter<T> extends Presenter {
+ protected final Context mContext;
+ private final Set<DvrItemViewHolder> mBoundViewHolders = new HashSet<>();
+ private final OnClickListener mOnClickListener = onCreateOnClickListener();
+
+ protected class DvrItemViewHolder extends ViewHolder {
+ DvrItemViewHolder(RecordingCardView view) {
+ super(view);
+ }
+
+ protected RecordingCardView getView() {
+ return (RecordingCardView) view;
+ }
+
+ protected void onBound(T item) { }
+
+ protected void onUnbound() { }
+ }
+
+ DvrItemPresenter(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public final ViewHolder onCreateViewHolder(ViewGroup parent) {
+ return onCreateDvrItemViewHolder();
+ }
+
+ @Override
+ public final void onBindViewHolder(ViewHolder baseHolder, Object item) {
+ DvrItemViewHolder viewHolder;
+ T dvrItem;
+ try {
+ viewHolder = (DvrItemViewHolder) baseHolder;
+ Class<T> itemType = (Class<T>) item.getClass();
+ dvrItem = itemType.cast(item);
+ } catch (ClassCastException e) {
+ SoftPreconditions.checkState(false);
+ return;
+ }
+ viewHolder.view.setTag(item);
+ viewHolder.view.setOnClickListener(mOnClickListener);
+ onBindDvrItemViewHolder(viewHolder, dvrItem);
+ viewHolder.onBound(dvrItem);
+ mBoundViewHolders.add(viewHolder);
+ }
+
+ @Override
+ @CallSuper
+ public void onUnbindViewHolder(ViewHolder baseHolder) {
+ DvrItemViewHolder viewHolder = (DvrItemViewHolder) baseHolder;
+ mBoundViewHolders.remove(viewHolder);
+ viewHolder.onUnbound();
+ viewHolder.view.setTag(null);
+ viewHolder.view.setOnClickListener(null);
+ }
+
+ /**
+ * Unbinds all bound view holders.
+ */
+ public void unbindAllViewHolders() {
+ // When browse fragments are destroyed, RecyclerView would not call presenters'
+ // onUnbindViewHolder(). We should handle it by ourselves to prevent resources leaks.
+ for (ViewHolder viewHolder : new HashSet<>(mBoundViewHolders)) {
+ onUnbindViewHolder(viewHolder);
+ }
+ }
+
+ /**
+ * This method will be called when a {@link DvrItemViewHolder} is needed to be created.
+ */
+ abstract protected DvrItemViewHolder onCreateDvrItemViewHolder();
+
+ /**
+ * This method will be called when a {@link DvrItemViewHolder} is bound to a DVR item.
+ */
+ abstract protected void onBindDvrItemViewHolder(DvrItemViewHolder viewHolder, T item);
+
+ /**
+ * Returns context.
+ */
+ protected Context getContext() {
+ return mContext;
+ }
+
+ /**
+ * Creates {@link OnClickListener} for DVR library's card views.
+ */
+ protected OnClickListener onCreateOnClickListener() {
+ return new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (view instanceof RecordingCardView) {
+ RecordingCardView v = (RecordingCardView) view;
+ DvrUiHelper.startDetailsActivity((Activity) v.getContext(),
+ v.getTag(), v.getImageView(), false);
+ }
+ }
+ };
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java b/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java
new file mode 100644
index 00000000..37a72eaf
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/DvrListRowPresenter.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017 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.tv.dvr.ui.browse;
+
+import android.content.Context;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.view.ViewGroup;
+
+import com.android.tv.R;
+
+/** A list row presenter to display expand/fold card views list. */
+public class DvrListRowPresenter extends ListRowPresenter {
+ public DvrListRowPresenter(Context context) {
+ super();
+ setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
+ setExpandedRowHeight(
+ context.getResources()
+ .getDimensionPixelSize(R.dimen.dvr_library_expanded_row_height));
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/browse/FullScheduleCardHolder.java b/src/com/android/tv/dvr/ui/browse/FullScheduleCardHolder.java
new file mode 100644
index 00000000..311137a9
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/FullScheduleCardHolder.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+/**
+ * Special object for schedule preview;
+ */
+final class FullScheduleCardHolder {
+ /**
+ * Full schedule card holder.
+ */
+ static final FullScheduleCardHolder FULL_SCHEDULE_CARD_HOLDER = new FullScheduleCardHolder();
+
+ private FullScheduleCardHolder() { }
+}
diff --git a/src/com/android/tv/dvr/ui/browse/FullSchedulesCardPresenter.java b/src/com/android/tv/dvr/ui/browse/FullSchedulesCardPresenter.java
new file mode 100644
index 00000000..94c67eec
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/FullSchedulesCardPresenter.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ui.DvrUiHelper;
+import com.android.tv.util.Utils;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Presents a {@link ScheduledRecording} in the {@link DvrBrowseFragment}.
+ */
+class FullSchedulesCardPresenter extends DvrItemPresenter<Object> {
+ private final Drawable mIconDrawable;
+ private final String mCardTitleText;
+
+ FullSchedulesCardPresenter(Context context) {
+ super(context);
+ mIconDrawable = mContext.getDrawable(R.drawable.dvr_full_schedule);
+ mCardTitleText = mContext.getString(R.string.dvr_full_schedule_card_view_title);
+ }
+
+ @Override
+ public DvrItemViewHolder onCreateDvrItemViewHolder() {
+ return new DvrItemViewHolder(new RecordingCardView(mContext));
+ }
+
+ @Override
+ public void onBindDvrItemViewHolder(DvrItemViewHolder vh, Object o) {
+ final RecordingCardView cardView = (RecordingCardView) vh.view;
+
+ cardView.setTitle(mCardTitleText);
+ cardView.setImage(mIconDrawable);
+ List<ScheduledRecording> scheduledRecordings = TvApplication.getSingletons(mContext)
+ .getDvrDataManager().getAvailableScheduledRecordings();
+ int fullDays = 0;
+ if (!scheduledRecordings.isEmpty()) {
+ fullDays = Utils.computeDateDifference(System.currentTimeMillis(),
+ Collections.max(scheduledRecordings, ScheduledRecording.START_TIME_COMPARATOR)
+ .getStartTimeMs()) + 1;
+ }
+ cardView.setContent(mContext.getResources().getQuantityString(
+ R.plurals.dvr_full_schedule_card_view_content, fullDays, fullDays), null);
+ }
+
+ @Override
+ public void onUnbindViewHolder(ViewHolder vh) {
+ ((RecordingCardView) vh.view).reset();
+ super.onUnbindViewHolder(vh);
+ }
+
+ @Override
+ protected View.OnClickListener onCreateOnClickListener() {
+ return new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ DvrUiHelper.startSchedulesActivity(mContext, null);
+ }
+ };
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java
new file mode 100644
index 00000000..eb9cb26c
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/RecordedProgramDetailsFragment.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.content.res.Resources;
+import android.media.tv.TvInputManager;
+import android.os.Bundle;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.DvrWatchedPositionManager;
+import com.android.tv.dvr.data.RecordedProgram;
+
+/**
+ * {@link android.support.v17.leanback.app.DetailsFragment} for recorded program in DVR.
+ */
+public class RecordedProgramDetailsFragment extends DvrDetailsFragment
+ implements DvrDataManager.RecordedProgramListener {
+ private static final int ACTION_RESUME_PLAYING = 1;
+ private static final int ACTION_PLAY_FROM_BEGINNING = 2;
+ private static final int ACTION_DELETE_RECORDING = 3;
+
+ private DvrWatchedPositionManager mDvrWatchedPositionManager;
+
+ private RecordedProgram mRecordedProgram;
+ private boolean mPaused;
+ private DvrDataManager mDvrDataManager;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ mDvrDataManager = TvApplication.getSingletons(getContext()).getDvrDataManager();
+ mDvrDataManager.addRecordedProgramListener(this);
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onCreateInternal() {
+ mDvrWatchedPositionManager = TvApplication.getSingletons(getActivity())
+ .getDvrWatchedPositionManager();
+ setDetailsOverviewRow(DetailsContent
+ .createFromRecordedProgram(getContext(), mRecordedProgram));
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (mPaused) {
+ updateActions();
+ mPaused = false;
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mPaused = true;
+ }
+
+ @Override
+ public void onDestroy() {
+ mDvrDataManager.removeRecordedProgramListener(this);
+ super.onDestroy();
+ }
+
+ @Override
+ protected boolean onLoadRecordingDetails(Bundle args) {
+ long recordedProgramId = args.getLong(DvrDetailsActivity.RECORDING_ID);
+ mRecordedProgram = mDvrDataManager.getRecordedProgram(recordedProgramId);
+ return mRecordedProgram != null;
+ }
+
+ @Override
+ protected SparseArrayObjectAdapter onCreateActionsAdapter() {
+ SparseArrayObjectAdapter adapter =
+ new SparseArrayObjectAdapter(new ActionPresenterSelector());
+ Resources res = getResources();
+ if (mDvrWatchedPositionManager.getWatchedStatus(mRecordedProgram)
+ == DvrWatchedPositionManager.DVR_WATCHED_STATUS_WATCHING) {
+ adapter.set(ACTION_RESUME_PLAYING, new Action(ACTION_RESUME_PLAYING,
+ res.getString(R.string.dvr_detail_resume_play), null,
+ res.getDrawable(R.drawable.lb_ic_play)));
+ adapter.set(ACTION_PLAY_FROM_BEGINNING, new Action(ACTION_PLAY_FROM_BEGINNING,
+ res.getString(R.string.dvr_detail_play_from_beginning), null,
+ res.getDrawable(R.drawable.lb_ic_replay)));
+ } else {
+ adapter.set(ACTION_PLAY_FROM_BEGINNING, new Action(ACTION_PLAY_FROM_BEGINNING,
+ res.getString(R.string.dvr_detail_watch), null,
+ res.getDrawable(R.drawable.lb_ic_play)));
+ }
+ adapter.set(ACTION_DELETE_RECORDING, new Action(ACTION_DELETE_RECORDING,
+ res.getString(R.string.dvr_detail_delete), null,
+ res.getDrawable(R.drawable.ic_delete_32dp)));
+ return adapter;
+ }
+
+ @Override
+ protected OnActionClickedListener onCreateOnActionClickedListener() {
+ return new OnActionClickedListener() {
+ @Override
+ public void onActionClicked(Action action) {
+ if (action.getId() == ACTION_PLAY_FROM_BEGINNING) {
+ startPlayback(mRecordedProgram, TvInputManager.TIME_SHIFT_INVALID_TIME);
+ } else if (action.getId() == ACTION_RESUME_PLAYING) {
+ startPlayback(mRecordedProgram, mDvrWatchedPositionManager
+ .getWatchedPosition(mRecordedProgram.getId()));
+ } else if (action.getId() == ACTION_DELETE_RECORDING) {
+ DvrManager dvrManager = TvApplication
+ .getSingletons(getActivity()).getDvrManager();
+ dvrManager.removeRecordedProgram(mRecordedProgram);
+ getActivity().finish();
+ }
+ }
+ };
+ }
+
+ @Override
+ public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) { }
+
+ @Override
+ public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) { }
+
+ @Override
+ public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) {
+ for (RecordedProgram recordedProgram : recordedPrograms) {
+ if (recordedProgram.getId() == mRecordedProgram.getId()) {
+ getActivity().finish();
+ }
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/browse/RecordedProgramPresenter.java b/src/com/android/tv/dvr/ui/browse/RecordedProgramPresenter.java
new file mode 100644
index 00000000..5fe162b6
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/RecordedProgramPresenter.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.content.Context;
+import android.media.tv.TvInputManager;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.DvrWatchedPositionManager;
+import com.android.tv.dvr.DvrWatchedPositionManager.WatchedPositionChangedListener;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.util.Utils;
+
+/**
+ * Presents a {@link RecordedProgram} in the {@link DvrBrowseFragment}.
+ */
+public class RecordedProgramPresenter extends DvrItemPresenter<RecordedProgram> {
+ private final DvrWatchedPositionManager mDvrWatchedPositionManager;
+ private String mTodayString;
+ private String mYesterdayString;
+ private final int mProgressBarColor;
+ private final boolean mShowEpisodeTitle;
+ private final boolean mExpandTitleWhenFocused;
+
+ protected final class RecordedProgramViewHolder extends DvrItemViewHolder
+ implements WatchedPositionChangedListener {
+ private RecordedProgram mProgram;
+ private boolean mShowProgress;
+
+ public RecordedProgramViewHolder(RecordingCardView view, Integer progressColor) {
+ super(view);
+ if (progressColor == null) {
+ mShowProgress = false;
+ } else {
+ mShowProgress = true;
+ view.setProgressBarColor(progressColor);
+ }
+ }
+
+ private void setProgressBar(long watchedPositionMs) {
+ ((RecordingCardView) view).setProgressBar(
+ (watchedPositionMs == TvInputManager.TIME_SHIFT_INVALID_TIME) ? null
+ : Math.min(100, (int) (100.0f * watchedPositionMs
+ / mProgram.getDurationMillis())));
+ }
+
+ @Override
+ public void onWatchedPositionChanged(long programId, long positionMs) {
+ if (programId == mProgram.getId()) {
+ setProgressBar(positionMs);
+ }
+ }
+
+ @Override
+ protected void onBound(RecordedProgram program) {
+ mProgram = program;
+ if (mShowProgress) {
+ mDvrWatchedPositionManager.addListener(this, program.getId());
+ setProgressBar(mDvrWatchedPositionManager.getWatchedPosition(program.getId()));
+ } else {
+ getView().setProgressBar(null);
+ }
+ }
+
+ @Override
+ protected void onUnbound() {
+ if (mShowProgress) {
+ mDvrWatchedPositionManager.removeListener(this, mProgram.getId());
+ }
+ getView().reset();
+ }
+ }
+
+ RecordedProgramPresenter(Context context, boolean showEpisodeTitle,
+ boolean expandTitleWhenFocused) {
+ super(context);
+ mTodayString = mContext.getString(R.string.dvr_date_today);
+ mYesterdayString = mContext.getString(R.string.dvr_date_yesterday);
+ mDvrWatchedPositionManager =
+ TvApplication.getSingletons(mContext).getDvrWatchedPositionManager();
+ mProgressBarColor = mContext.getResources()
+ .getColor(R.color.play_controls_progress_bar_watched);
+ mShowEpisodeTitle = showEpisodeTitle;
+ mExpandTitleWhenFocused = expandTitleWhenFocused;
+ }
+
+ public RecordedProgramPresenter(Context context) {
+ this(context, false, false);
+ }
+
+ @Override
+ public DvrItemViewHolder onCreateDvrItemViewHolder() {
+ return new RecordedProgramViewHolder(
+ new RecordingCardView(mContext, mExpandTitleWhenFocused), mProgressBarColor);
+ }
+
+ @Override
+ public void onBindDvrItemViewHolder(DvrItemViewHolder baseHolder, RecordedProgram program) {
+ final RecordedProgramViewHolder viewHolder = (RecordedProgramViewHolder) baseHolder;
+ final RecordingCardView cardView = viewHolder.getView();
+ DetailsContent details = DetailsContent.createFromRecordedProgram(mContext, program);
+ cardView.setTitle(mShowEpisodeTitle ?
+ program.getEpisodeDisplayTitle(mContext) : details.getTitle());
+ cardView.setImageUri(details.getLogoImageUri(), details.isUsingChannelLogo());
+ cardView.setContent(generateMajorContent(program), generateMinorContent(program));
+ cardView.setDetailBackgroundImageUri(details.getBackgroundImageUri());
+ }
+
+ private String generateMajorContent(RecordedProgram program) {
+ int dateDifference = Utils.computeDateDifference(program.getStartTimeUtcMillis(),
+ System.currentTimeMillis());
+ if (dateDifference == 0) {
+ return mTodayString;
+ } else if (dateDifference == 1) {
+ return mYesterdayString;
+ } else {
+ return Utils.getDurationString(mContext, program.getStartTimeUtcMillis(),
+ program.getStartTimeUtcMillis(), false, true, false, 0);
+ }
+ }
+
+ private String generateMinorContent(RecordedProgram program) {
+ int durationMinutes = Math.max(1, Utils.getRoundOffMinsFromMs(program.getDurationMillis()));
+ return mContext.getResources().getQuantityString(
+ R.plurals.dvr_program_duration, durationMinutes, durationMinutes);
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/browse/RecordingCardView.java b/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
new file mode 100644
index 00000000..767addc8
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/RecordingCardView.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.Nullable;
+import android.support.v17.leanback.widget.BaseCardView;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.android.tv.R;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.ui.ViewUtils;
+import com.android.tv.util.ImageLoader;
+
+/**
+ * A CardView for displaying info about a {@link com.android.tv.dvr.data.ScheduledRecording}
+ * or {@link RecordedProgram} or {@link com.android.tv.dvr.data.SeriesRecording}.
+ */
+public class RecordingCardView extends BaseCardView {
+ // This value should be the same with
+ // android.support.v17.leanback.widget.FocusHighlightHelper.BrowseItemFocusHighlight.DURATION_MS
+ private final static int ANIMATION_DURATION = 150;
+ private final ImageView mImageView;
+ private final int mImageWidth;
+ private final int mImageHeight;
+ private String mImageUri;
+ private final TextView mMajorContentView;
+ private final TextView mMinorContentView;
+ private final ProgressBar mProgressBar;
+ private final View mAffiliatedIconContainer;
+ private final ImageView mAffiliatedIcon;
+ private final Drawable mDefaultImage;
+ private final FrameLayout mTitleArea;
+ private final TextView mFoldedTitleView;
+ private final TextView mExpandedTitleView;
+ private final ValueAnimator mExpandTitleAnimator;
+ private final int mFoldedTitleHeight;
+ private final int mExpandedTitleHeight;
+ private final boolean mExpandTitleWhenFocused;
+ private boolean mExpanded;
+ private String mDetailBackgroundImageUri;
+
+ public RecordingCardView(Context context) {
+ this(context, false);
+ }
+
+ public RecordingCardView(Context context, boolean expandTitleWhenFocused) {
+ this(context, context.getResources().getDimensionPixelSize(
+ R.dimen.dvr_library_card_image_layout_width), context.getResources()
+ .getDimensionPixelSize(R.dimen.dvr_library_card_image_layout_height),
+ expandTitleWhenFocused);
+ }
+
+ public RecordingCardView(Context context, int imageWidth, int imageHeight,
+ boolean expandTitleWhenFocused) {
+ super(context);
+ //TODO(dvr): move these to the layout XML.
+ setCardType(BaseCardView.CARD_TYPE_INFO_UNDER_WITH_EXTRA);
+ setInfoVisibility(BaseCardView.CARD_REGION_VISIBLE_ALWAYS);
+ setFocusable(true);
+ setFocusableInTouchMode(true);
+ mDefaultImage = getResources().getDrawable(R.drawable.dvr_default_poster, null);
+
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ inflater.inflate(R.layout.dvr_recording_card_view, this);
+ mImageView = (ImageView) findViewById(R.id.image);
+ mImageWidth = imageWidth;
+ mImageHeight = imageHeight;
+ mProgressBar = (ProgressBar) findViewById(R.id.recording_progress);
+ mAffiliatedIconContainer = findViewById(R.id.affiliated_icon_container);
+ mAffiliatedIcon = (ImageView) findViewById(R.id.affiliated_icon);
+ mMajorContentView = (TextView) findViewById(R.id.content_major);
+ mMinorContentView = (TextView) findViewById(R.id.content_minor);
+ mTitleArea = (FrameLayout) findViewById(R.id.title_area);
+ mFoldedTitleView = (TextView) findViewById(R.id.title_one_line);
+ mExpandedTitleView = (TextView) findViewById(R.id.title_two_lines);
+ mFoldedTitleHeight = getResources()
+ .getDimensionPixelSize(R.dimen.dvr_library_card_folded_title_height);
+ mExpandedTitleHeight = getResources()
+ .getDimensionPixelSize(R.dimen.dvr_library_card_expanded_title_height);
+ mExpandTitleAnimator = ValueAnimator.ofFloat(0.0f, 1.0f).setDuration(ANIMATION_DURATION);
+ mExpandTitleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ float value = (Float) valueAnimator.getAnimatedValue();
+ mExpandedTitleView.setAlpha(value);
+ mFoldedTitleView.setAlpha(1.0f - value);
+ ViewUtils.setLayoutHeight(mTitleArea, (int) (mFoldedTitleHeight
+ + (mExpandedTitleHeight - mFoldedTitleHeight) * value));
+ }
+ });
+ mExpandTitleWhenFocused = expandTitleWhenFocused;
+ }
+
+ @Override
+ protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+ // Preload the background image going to be used in detail fragments here to prevent
+ // loading and drawing background images during activity transitions.
+ if (gainFocus) {
+ if (!TextUtils.isEmpty(mDetailBackgroundImageUri)) {
+ ImageLoader.loadBitmap(getContext(), mDetailBackgroundImageUri,
+ Integer.MAX_VALUE, Integer.MAX_VALUE, null);
+ }
+ }
+ if (mExpandTitleWhenFocused) {
+ if (gainFocus) {
+ expandTitle(true, true);
+ } else {
+ expandTitle(false, true);
+ }
+ }
+ }
+
+ /**
+ * Expands/folds the title area to show program title with two/one lines.
+ *
+ * @param expand {@code true} to expand the title area, or {@code false} to fold it.
+ * @param withAnimation {@code true} to expand/fold with animation.
+ */
+ public void expandTitle(boolean expand, boolean withAnimation) {
+ if (expand != mExpanded && mFoldedTitleView.getLayout().getEllipsisCount(0) > 0) {
+ if (withAnimation) {
+ if (expand) {
+ mExpandTitleAnimator.start();
+ } else {
+ mExpandTitleAnimator.reverse();
+ }
+ } else {
+ if (expand) {
+ mFoldedTitleView.setAlpha(0.0f);
+ mExpandedTitleView.setAlpha(1.0f);
+ ViewUtils.setLayoutHeight(mTitleArea, mExpandedTitleHeight);
+ } else {
+ mFoldedTitleView.setAlpha(1.0f);
+ mExpandedTitleView.setAlpha(0.0f);
+ ViewUtils.setLayoutHeight(mTitleArea, mFoldedTitleHeight);
+ }
+ }
+ mExpanded = expand;
+ }
+ }
+
+ void setTitle(CharSequence title) {
+ mFoldedTitleView.setText(title);
+ mExpandedTitleView.setText(title);
+ }
+
+ void setContent(CharSequence majorContent, CharSequence minorContent) {
+ if (!TextUtils.isEmpty(majorContent)) {
+ mMajorContentView.setText(majorContent);
+ mMajorContentView.setVisibility(View.VISIBLE);
+ } else {
+ mMajorContentView.setVisibility(View.GONE);
+ }
+ if (!TextUtils.isEmpty(minorContent)) {
+ mMinorContentView.setText(minorContent);
+ mMinorContentView.setVisibility(View.VISIBLE);
+ } else {
+ mMinorContentView.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * Sets progress bar. If progress is {@code null}, hides progress bar.
+ */
+ void setProgressBar(Integer progress) {
+ if (progress == null) {
+ mProgressBar.setVisibility(View.GONE);
+ } else {
+ mProgressBar.setProgress(progress);
+ mProgressBar.setVisibility(View.VISIBLE);
+ }
+ }
+
+ /**
+ * Sets the color of progress bar.
+ */
+ void setProgressBarColor(int color) {
+ mProgressBar.getProgressDrawable().setTint(color);
+ }
+
+ /**
+ * Sets the image URI of the poster should be shown on the card view.
+
+ * @param isChannelLogo {@code true} if the image is from channels' logo.
+ */
+ void setImageUri(String uri, boolean isChannelLogo) {
+ if (isChannelLogo) {
+ mImageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+ } else {
+ mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
+ }
+ mImageUri = uri;
+ if (TextUtils.isEmpty(uri)) {
+ mImageView.setImageDrawable(mDefaultImage);
+ } else {
+ ImageLoader.loadBitmap(getContext(), uri, mImageWidth, mImageHeight,
+ new RecordingCardImageLoaderCallback(this, uri));
+ }
+ }
+
+ /**
+ * Sets the {@link Drawable} of the poster should be shown on the card view.
+ */
+ public void setImage(Drawable image) {
+ if (image != null) {
+ mImageView.setImageDrawable(image);
+ }
+ }
+
+ /**
+ * Sets the affiliated icon of the card view, which will be displayed at the lower-right corner
+ * of the poster.
+ */
+ public void setAffiliatedIcon(int imageResId) {
+ if (imageResId > 0) {
+ mAffiliatedIconContainer.setVisibility(View.VISIBLE);
+ mAffiliatedIcon.setImageResource(imageResId);
+ } else {
+ mAffiliatedIconContainer.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ /**
+ * Sets the background image URI of the card view, which will be displayed as background when
+ * the view is clicked and shows its details fragment.
+ */
+ public void setDetailBackgroundImageUri(String uri) {
+ mDetailBackgroundImageUri = uri;
+ }
+
+ /**
+ * Returns image view.
+ */
+ public ImageView getImageView() {
+ return mImageView;
+ }
+
+ private static class RecordingCardImageLoaderCallback
+ extends ImageLoader.ImageLoaderCallback<RecordingCardView> {
+ private final String mUri;
+
+ RecordingCardImageLoaderCallback(RecordingCardView referent, String uri) {
+ super(referent);
+ mUri = uri;
+ }
+
+ @Override
+ public void onBitmapLoaded(RecordingCardView view, @Nullable Bitmap bitmap) {
+ if (bitmap == null || !mUri.equals(view.mImageUri)) {
+ view.mImageView.setImageDrawable(view.mDefaultImage);
+ } else {
+ view.mImageView.setImageDrawable(new BitmapDrawable(view.getResources(), bitmap));
+ }
+ }
+ }
+
+ public void reset() {
+ mFoldedTitleView.setText(null);
+ mExpandedTitleView.setText(null);
+ setContent(null, null);
+ mImageView.setImageDrawable(mDefaultImage);
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java
new file mode 100644
index 00000000..56ec357f
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/RecordingDetailsFragment.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.os.Bundle;
+import android.support.v17.leanback.app.DetailsFragment;
+
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.data.ScheduledRecording;
+
+/**
+ * {@link DetailsFragment} for recordings in DVR.
+ */
+abstract class RecordingDetailsFragment extends DvrDetailsFragment {
+ private ScheduledRecording mRecording;
+
+ @Override
+ protected void onCreateInternal() {
+ setDetailsOverviewRow(DetailsContent
+ .createFromScheduledRecording(getContext(), mRecording));
+ }
+
+ @Override
+ protected boolean onLoadRecordingDetails(Bundle args) {
+ long scheduledRecordingId = args.getLong(DvrDetailsActivity.RECORDING_ID);
+ mRecording = TvApplication.getSingletons(getContext()).getDvrDataManager()
+ .getScheduledRecording(scheduledRecordingId);
+ return mRecording != null;
+ }
+
+ /**
+ * Returns {@link ScheduledRecording} for the current fragment.
+ */
+ public ScheduledRecording getRecording() {
+ return mRecording;
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java
new file mode 100644
index 00000000..958f8bf8
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/ScheduledRecordingDetailsFragment.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.text.TextUtils;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.ui.DvrUiHelper;
+
+/**
+ * {@link RecordingDetailsFragment} for scheduled recording in DVR.
+ */
+public class ScheduledRecordingDetailsFragment extends RecordingDetailsFragment {
+ private static final int ACTION_VIEW_SCHEDULE = 1;
+ private static final int ACTION_CANCEL = 2;
+
+ private DvrManager mDvrManager;
+ private Action mScheduleAction;
+ private boolean mHideViewSchedule;
+
+ @Override
+ public void onCreate(Bundle savedInstance) {
+ mDvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
+ mHideViewSchedule = getArguments().getBoolean(DvrDetailsActivity.HIDE_VIEW_SCHEDULE);
+ super.onCreate(savedInstance);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (mScheduleAction != null) {
+ mScheduleAction.setIcon(getResources().getDrawable(getScheduleIconId()));
+ }
+ }
+
+ @Override
+ protected SparseArrayObjectAdapter onCreateActionsAdapter() {
+ SparseArrayObjectAdapter adapter =
+ new SparseArrayObjectAdapter(new ActionPresenterSelector());
+ Resources res = getResources();
+ if (!mHideViewSchedule) {
+ mScheduleAction = new Action(ACTION_VIEW_SCHEDULE,
+ res.getString(R.string.dvr_detail_view_schedule), null,
+ res.getDrawable(getScheduleIconId()));
+ adapter.set(ACTION_VIEW_SCHEDULE, mScheduleAction);
+ }
+ adapter.set(ACTION_CANCEL, new Action(ACTION_CANCEL,
+ res.getString(R.string.dvr_detail_cancel_recording), null,
+ res.getDrawable(R.drawable.ic_dvr_cancel_32dp)));
+ return adapter;
+ }
+
+ @Override
+ protected OnActionClickedListener onCreateOnActionClickedListener() {
+ return new OnActionClickedListener() {
+ @Override
+ public void onActionClicked(Action action) {
+ long actionId = action.getId();
+ if (actionId == ACTION_VIEW_SCHEDULE) {
+ DvrUiHelper.startSchedulesActivity(getContext(), getRecording());
+ } else if (actionId == ACTION_CANCEL) {
+ mDvrManager.removeScheduledRecording(getRecording());
+ getActivity().finish();
+ }
+ }
+ };
+ }
+
+ private int getScheduleIconId() {
+ if (mDvrManager.isConflicting(getRecording())) {
+ return R.drawable.ic_warning_white_32dp;
+ } else {
+ return R.drawable.ic_schedule_32dp;
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/browse/ScheduledRecordingPresenter.java b/src/com/android/tv/dvr/ui/browse/ScheduledRecordingPresenter.java
new file mode 100644
index 00000000..273d3d19
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/ScheduledRecordingPresenter.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.content.Context;
+import android.os.Handler;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.util.Utils;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Presents a {@link ScheduledRecording} in the {@link DvrBrowseFragment}.
+ */
+class ScheduledRecordingPresenter extends DvrItemPresenter<ScheduledRecording> {
+ private static final long PROGRESS_UPDATE_INTERVAL_MS = TimeUnit.SECONDS.toMillis(5);
+
+ private final DvrManager mDvrManager;
+ private final int mProgressBarColor;
+
+ private final class ScheduledRecordingViewHolder extends DvrItemViewHolder {
+ private final Handler mHandler = new Handler();
+ private ScheduledRecording mScheduledRecording;
+ private final Runnable mProgressBarUpdater = new Runnable() {
+ @Override
+ public void run() {
+ updateProgressBar();
+ mHandler.postDelayed(this, PROGRESS_UPDATE_INTERVAL_MS);
+ }
+ };
+
+ ScheduledRecordingViewHolder(RecordingCardView view, int progressBarColor) {
+ super(view);
+ view.setProgressBarColor(progressBarColor);
+ }
+
+ @Override
+ protected void onBound(ScheduledRecording recording) {
+ mScheduledRecording = recording;
+ updateProgressBar();
+ startUpdateProgressBar();
+ }
+
+ @Override
+ protected void onUnbound() {
+ stopUpdateProgressBar();
+ mScheduledRecording = null;
+ getView().reset();
+ }
+
+ private void updateProgressBar() {
+ if (mScheduledRecording == null) {
+ return;
+ }
+ int recordingState = mScheduledRecording.getState();
+ RecordingCardView cardView = (RecordingCardView) view;
+ if (recordingState == ScheduledRecording.STATE_RECORDING_IN_PROGRESS) {
+ cardView.setProgressBar(Math.max(0, Math.min((int) (100 *
+ (System.currentTimeMillis() - mScheduledRecording.getStartTimeMs())
+ / mScheduledRecording.getDuration()), 100)));
+ } else if (recordingState == ScheduledRecording.STATE_RECORDING_FINISHED) {
+ cardView.setProgressBar(100);
+ } else {
+ // Hides progress bar.
+ cardView.setProgressBar(null);
+ }
+ }
+
+ private void startUpdateProgressBar() {
+ mHandler.post(mProgressBarUpdater);
+ }
+
+ private void stopUpdateProgressBar() {
+ mHandler.removeCallbacks(mProgressBarUpdater);
+ }
+ }
+
+ public ScheduledRecordingPresenter(Context context) {
+ super(context);
+ mDvrManager = TvApplication.getSingletons(mContext).getDvrManager();
+ mProgressBarColor = mContext.getResources()
+ .getColor(R.color.play_controls_recording_icon_color_on_focus);
+ }
+
+ @Override
+ public DvrItemViewHolder onCreateDvrItemViewHolder() {
+ return new ScheduledRecordingViewHolder(new RecordingCardView(mContext), mProgressBarColor);
+ }
+
+ @Override
+ public void onBindDvrItemViewHolder(DvrItemViewHolder baseHolder,
+ ScheduledRecording recording) {
+ final ScheduledRecordingViewHolder viewHolder = (ScheduledRecordingViewHolder) baseHolder;
+ final RecordingCardView cardView = viewHolder.getView();
+ DetailsContent details = DetailsContent.createFromScheduledRecording(mContext, recording);
+ cardView.setTitle(details.getTitle());
+ cardView.setImageUri(details.getLogoImageUri(), details.isUsingChannelLogo());
+ cardView.setAffiliatedIcon(mDvrManager.isConflicting(recording) ?
+ R.drawable.ic_warning_white_32dp : 0);
+ cardView.setContent(generateMajorContent(recording), null);
+ cardView.setDetailBackgroundImageUri(details.getBackgroundImageUri());
+ }
+
+ private String generateMajorContent(ScheduledRecording recording) {
+ int dateDifference = Utils.computeDateDifference(System.currentTimeMillis(),
+ recording.getStartTimeMs());
+ if (dateDifference <= 0) {
+ return mContext.getString(R.string.dvr_date_today_time,
+ Utils.getDurationString(mContext, recording.getStartTimeMs(),
+ recording.getEndTimeMs(), false, false, true, 0));
+ } else if (dateDifference == 1) {
+ return mContext.getString(R.string.dvr_date_tomorrow_time,
+ Utils.getDurationString(mContext, recording.getStartTimeMs(),
+ recording.getEndTimeMs(), false, false, true, 0));
+ } else {
+ return Utils.getDurationString(mContext, recording.getStartTimeMs(),
+ recording.getStartTimeMs(), false, true, false, 0);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java b/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
new file mode 100644
index 00000000..c2aa8e98
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/SeriesRecordingDetailsFragment.java
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.media.tv.TvInputManager;
+import android.os.Bundle;
+import android.support.v17.leanback.app.DetailsFragment;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.DetailsOverviewRow;
+import android.support.v17.leanback.widget.DetailsOverviewRowPresenter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.OnActionClickedListener;
+import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
+import android.text.TextUtils;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.data.BaseProgram;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrWatchedPositionManager;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.ui.DvrUiHelper;
+import com.android.tv.dvr.ui.SortedArrayAdapter;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * {@link DetailsFragment} for series recording in DVR.
+ */
+public class SeriesRecordingDetailsFragment extends DvrDetailsFragment implements
+ DvrDataManager.SeriesRecordingListener, DvrDataManager.RecordedProgramListener {
+ private static final int ACTION_WATCH = 1;
+ private static final int ACTION_SERIES_SCHEDULES = 2;
+ private static final int ACTION_DELETE = 3;
+
+ private DvrWatchedPositionManager mDvrWatchedPositionManager;
+ private DvrDataManager mDvrDataManager;
+
+ private SeriesRecording mSeries;
+ // NOTICE: mRecordedPrograms should only be used in creating details fragments.
+ // After fragments are created, it should be cleared to save resources.
+ private List<RecordedProgram> mRecordedPrograms;
+ private RecordedProgram mRecommendRecordedProgram;
+ private int mSeasonRowCount;
+ private SparseArrayObjectAdapter mActionsAdapter;
+ private Action mDeleteAction;
+
+ private boolean mPaused;
+ private long mInitialPlaybackPositionMs;
+ private String mWatchLabel;
+ private String mResumeLabel;
+ private Drawable mWatchDrawable;
+ private RecordedProgramPresenter mRecordedProgramPresenter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ mDvrDataManager = TvApplication.getSingletons(getActivity()).getDvrDataManager();
+ mWatchLabel = getString(R.string.dvr_detail_watch);
+ mResumeLabel = getString(R.string.dvr_detail_series_resume);
+ mWatchDrawable = getResources().getDrawable(R.drawable.lb_ic_play, null);
+ mRecordedProgramPresenter = new RecordedProgramPresenter(getContext(), true, true);
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onCreateInternal() {
+ mDvrWatchedPositionManager = TvApplication.getSingletons(getActivity())
+ .getDvrWatchedPositionManager();
+ setDetailsOverviewRow(DetailsContent.createFromSeriesRecording(getContext(), mSeries));
+ setupRecordedProgramsRow();
+ mDvrDataManager.addSeriesRecordingListener(this);
+ mDvrDataManager.addRecordedProgramListener(this);
+ mRecordedPrograms = null;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (mPaused) {
+ updateWatchAction();
+ mPaused = false;
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mPaused = true;
+ }
+
+ private void updateWatchAction() {
+ List<RecordedProgram> programs = mDvrDataManager.getRecordedPrograms(mSeries.getId());
+ Collections.sort(programs, RecordedProgram.EPISODE_COMPARATOR);
+ mRecommendRecordedProgram = getRecommendProgram(programs);
+ if (mRecommendRecordedProgram == null) {
+ mActionsAdapter.clear(ACTION_WATCH);
+ } else {
+ String episodeStatus;
+ if(mDvrWatchedPositionManager.getWatchedStatus(mRecommendRecordedProgram)
+ == DvrWatchedPositionManager.DVR_WATCHED_STATUS_WATCHING) {
+ episodeStatus = mResumeLabel;
+ mInitialPlaybackPositionMs = mDvrWatchedPositionManager
+ .getWatchedPosition(mRecommendRecordedProgram.getId());
+ } else {
+ episodeStatus = mWatchLabel;
+ mInitialPlaybackPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
+ }
+ String episodeDisplayNumber = mRecommendRecordedProgram.getEpisodeDisplayNumber(
+ getContext());
+ mActionsAdapter.set(ACTION_WATCH, new Action(ACTION_WATCH,
+ episodeStatus, episodeDisplayNumber, mWatchDrawable));
+ }
+ }
+
+ @Override
+ protected boolean onLoadRecordingDetails(Bundle args) {
+ long recordId = args.getLong(DvrDetailsActivity.RECORDING_ID);
+ mSeries = TvApplication.getSingletons(getActivity()).getDvrDataManager()
+ .getSeriesRecording(recordId);
+ if (mSeries == null) {
+ return false;
+ }
+ mRecordedPrograms = mDvrDataManager.getRecordedPrograms(mSeries.getId());
+ Collections.sort(mRecordedPrograms, RecordedProgram.SEASON_REVERSED_EPISODE_COMPARATOR);
+ return true;
+ }
+
+ @Override
+ protected PresenterSelector onCreatePresenterSelector(
+ DetailsOverviewRowPresenter rowPresenter) {
+ ClassPresenterSelector presenterSelector = new ClassPresenterSelector();
+ presenterSelector.addClassPresenter(DetailsOverviewRow.class, rowPresenter);
+ presenterSelector.addClassPresenter(ListRow.class, new DvrListRowPresenter(getContext()));
+ return presenterSelector;
+ }
+
+ @Override
+ protected SparseArrayObjectAdapter onCreateActionsAdapter() {
+ mActionsAdapter = new SparseArrayObjectAdapter(new ActionPresenterSelector());
+ Resources res = getResources();
+ updateWatchAction();
+ mActionsAdapter.set(ACTION_SERIES_SCHEDULES, new Action(ACTION_SERIES_SCHEDULES,
+ getString(R.string.dvr_detail_view_schedule), null,
+ res.getDrawable(R.drawable.ic_schedule_32dp, null)));
+ mDeleteAction = new Action(ACTION_DELETE,
+ getString(R.string.dvr_detail_series_delete), null,
+ res.getDrawable(R.drawable.ic_delete_32dp, null));
+ if (!mRecordedPrograms.isEmpty()) {
+ mActionsAdapter.set(ACTION_DELETE, mDeleteAction);
+ }
+ return mActionsAdapter;
+ }
+
+ private void setupRecordedProgramsRow() {
+ for (RecordedProgram program : mRecordedPrograms) {
+ addProgram(program);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mDvrDataManager.removeSeriesRecordingListener(this);
+ mDvrDataManager.removeRecordedProgramListener(this);
+ if (mSeries != null) {
+ mDvrDataManager.checkAndRemoveEmptySeriesRecording(mSeries.getId());
+ }
+ mRecordedProgramPresenter.unbindAllViewHolders();
+ }
+
+ @Override
+ protected OnActionClickedListener onCreateOnActionClickedListener() {
+ return new OnActionClickedListener() {
+ @Override
+ public void onActionClicked(Action action) {
+ if (action.getId() == ACTION_WATCH) {
+ startPlayback(mRecommendRecordedProgram, mInitialPlaybackPositionMs);
+ } else if (action.getId() == ACTION_SERIES_SCHEDULES) {
+ DvrUiHelper.startSchedulesActivityForSeries(getContext(), mSeries);
+ } else if (action.getId() == ACTION_DELETE) {
+ DvrUiHelper.startSeriesDeletionActivity(getContext(), mSeries.getId());
+ }
+ }
+ };
+ }
+
+ /**
+ * The programs are sorted by season number and episode number.
+ */
+ private RecordedProgram getRecommendProgram(List<RecordedProgram> programs) {
+ for (int i = programs.size() - 1 ; i >= 0 ; i--) {
+ RecordedProgram program = programs.get(i);
+ int watchedStatus = mDvrWatchedPositionManager.getWatchedStatus(program);
+ if (watchedStatus == DvrWatchedPositionManager.DVR_WATCHED_STATUS_NEW) {
+ continue;
+ }
+ if (watchedStatus == DvrWatchedPositionManager.DVR_WATCHED_STATUS_WATCHING) {
+ return program;
+ }
+ if (i == programs.size() - 1) {
+ return program;
+ } else {
+ return programs.get(i + 1);
+ }
+ }
+ return programs.isEmpty() ? null : programs.get(0);
+ }
+
+ @Override
+ public void onSeriesRecordingAdded(SeriesRecording... seriesRecordings) { }
+
+ @Override
+ public void onSeriesRecordingChanged(SeriesRecording... seriesRecordings) {
+ for (SeriesRecording series : seriesRecordings) {
+ if (mSeries.getId() == series.getId()) {
+ mSeries = series;
+ }
+ }
+ }
+
+ @Override
+ public void onSeriesRecordingRemoved(SeriesRecording... seriesRecordings) {
+ for (SeriesRecording series : seriesRecordings) {
+ if (series.getId() == mSeries.getId()) {
+ getActivity().finish();
+ return;
+ }
+ }
+ }
+
+ @Override
+ public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) {
+ for (RecordedProgram recordedProgram : recordedPrograms) {
+ if (TextUtils.equals(recordedProgram.getSeriesId(), mSeries.getSeriesId())) {
+ addProgram(recordedProgram);
+ if (mActionsAdapter.lookup(ACTION_DELETE) == null) {
+ mActionsAdapter.set(ACTION_DELETE, mDeleteAction);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) {
+ // Do nothing
+ }
+
+ @Override
+ public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) {
+ for (RecordedProgram recordedProgram : recordedPrograms) {
+ if (TextUtils.equals(recordedProgram.getSeriesId(), mSeries.getSeriesId())) {
+ ListRow row = getSeasonRow(recordedProgram.getSeasonNumber(), false);
+ if (row != null) {
+ SeasonRowAdapter adapter = (SeasonRowAdapter) row.getAdapter();
+ adapter.remove(recordedProgram);
+ if (adapter.isEmpty()) {
+ getRowsAdapter().remove(row);
+ if (getRowsAdapter().size() == 1) {
+ // No season rows left. Only DetailsOverviewRow
+ mActionsAdapter.clear(ACTION_DELETE);
+ }
+ }
+ }
+ if (recordedProgram.getId() == mRecommendRecordedProgram.getId()) {
+ updateWatchAction();
+ }
+ }
+ }
+ }
+
+ private void addProgram(RecordedProgram program) {
+ String programSeasonNumber =
+ TextUtils.isEmpty(program.getSeasonNumber()) ? "" : program.getSeasonNumber();
+ getOrCreateSeasonRowAdapter(programSeasonNumber).add(program);
+ }
+
+ private SeasonRowAdapter getOrCreateSeasonRowAdapter(String seasonNumber) {
+ ListRow row = getSeasonRow(seasonNumber, true);
+ return (SeasonRowAdapter) row.getAdapter();
+ }
+
+ private ListRow getSeasonRow(String seasonNumber, boolean createNewRow) {
+ seasonNumber = TextUtils.isEmpty(seasonNumber) ? "" : seasonNumber;
+ ArrayObjectAdapter rowsAdaptor = getRowsAdapter();
+ for (int i = rowsAdaptor.size() - 1; i >= 0; i--) {
+ Object row = rowsAdaptor.get(i);
+ if (row instanceof ListRow) {
+ int compareResult = BaseProgram.numberCompare(seasonNumber,
+ ((SeasonRowAdapter) ((ListRow) row).getAdapter()).mSeasonNumber);
+ if (compareResult == 0) {
+ return (ListRow) row;
+ } else if (compareResult < 0) {
+ return createNewRow ? createNewSeasonRow(seasonNumber, i + 1) : null;
+ }
+ }
+ }
+ return createNewRow ? createNewSeasonRow(seasonNumber, rowsAdaptor.size()) : null;
+ }
+
+ private ListRow createNewSeasonRow(String seasonNumber, int position) {
+ String seasonTitle = seasonNumber.isEmpty() ? mSeries.getTitle()
+ : getString(R.string.dvr_detail_series_season_title, seasonNumber);
+ HeaderItem header = new HeaderItem(mSeasonRowCount++, seasonTitle);
+ ClassPresenterSelector selector = new ClassPresenterSelector();
+ selector.addClassPresenter(RecordedProgram.class, mRecordedProgramPresenter);
+ ListRow row = new ListRow(header, new SeasonRowAdapter(selector,
+ new Comparator<RecordedProgram>() {
+ @Override
+ public int compare(RecordedProgram lhs, RecordedProgram rhs) {
+ return BaseProgram.EPISODE_COMPARATOR.compare(lhs, rhs);
+ }
+ }, seasonNumber));
+ getRowsAdapter().add(position, row);
+ return row;
+ }
+
+ private class SeasonRowAdapter extends SortedArrayAdapter<RecordedProgram> {
+ private String mSeasonNumber;
+
+ SeasonRowAdapter(PresenterSelector selector, Comparator<RecordedProgram> comparator,
+ String seasonNumber) {
+ super(selector, comparator);
+ mSeasonNumber = seasonNumber;
+ }
+
+ @Override
+ public long getId(RecordedProgram program) {
+ return program.getId();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/browse/SeriesRecordingPresenter.java b/src/com/android/tv/dvr/ui/browse/SeriesRecordingPresenter.java
new file mode 100644
index 00000000..e508259d
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/browse/SeriesRecordingPresenter.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.browse;
+
+import android.content.Context;
+import android.media.tv.TvInputManager;
+import android.text.TextUtils;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrDataManager.RecordedProgramListener;
+import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.DvrWatchedPositionManager;
+import com.android.tv.dvr.DvrWatchedPositionManager.WatchedPositionChangedListener;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
+
+import java.util.List;
+
+/**
+ * Presents a {@link SeriesRecording} in {@link DvrBrowseFragment}.
+ */
+class SeriesRecordingPresenter extends DvrItemPresenter<SeriesRecording> {
+ private final DvrDataManager mDvrDataManager;
+ private final DvrManager mDvrManager;
+ private final DvrWatchedPositionManager mWatchedPositionManager;
+
+ private final class SeriesRecordingViewHolder extends DvrItemViewHolder implements
+ WatchedPositionChangedListener, ScheduledRecordingListener, RecordedProgramListener {
+ private SeriesRecording mSeriesRecording;
+ private RecordingCardView mCardView;
+ private DvrDataManager mDvrDataManager;
+ private DvrManager mDvrManager;
+ private DvrWatchedPositionManager mWatchedPositionManager;
+
+ SeriesRecordingViewHolder(RecordingCardView view, DvrDataManager dvrDataManager,
+ DvrManager dvrManager, DvrWatchedPositionManager watchedPositionManager) {
+ super(view);
+ mCardView = view;
+ mDvrDataManager = dvrDataManager;
+ mDvrManager = dvrManager;
+ mWatchedPositionManager = watchedPositionManager;
+ }
+
+ @Override
+ public void onWatchedPositionChanged(long recordedProgramId, long positionMs) {
+ if (positionMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
+ mWatchedPositionManager.removeListener(this, recordedProgramId);
+ updateCardViewContent();
+ }
+ }
+
+ @Override
+ public void onScheduledRecordingAdded(ScheduledRecording... scheduledRecordings) {
+ for (ScheduledRecording scheduledRecording : scheduledRecordings) {
+ if (scheduledRecording.getSeriesRecordingId() == mSeriesRecording.getId()) {
+ updateCardViewContent();
+ return;
+ }
+ }
+ }
+
+ @Override
+ public void onScheduledRecordingRemoved(ScheduledRecording... scheduledRecordings) {
+ for (ScheduledRecording scheduledRecording : scheduledRecordings) {
+ if (scheduledRecording.getSeriesRecordingId() == mSeriesRecording.getId()) {
+ updateCardViewContent();
+ return;
+ }
+ }
+ }
+
+ @Override
+ public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) {
+ boolean needToUpdateCardView = false;
+ for (RecordedProgram recordedProgram : recordedPrograms) {
+ if (TextUtils.equals(recordedProgram.getSeriesId(),
+ mSeriesRecording.getSeriesId())) {
+ mDvrDataManager.removeScheduledRecordingListener(this);
+ mWatchedPositionManager.addListener(this, recordedProgram.getId());
+ needToUpdateCardView = true;
+ }
+ }
+ if (needToUpdateCardView) {
+ updateCardViewContent();
+ }
+ }
+
+ @Override
+ public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) {
+ boolean needToUpdateCardView = false;
+ for (RecordedProgram recordedProgram : recordedPrograms) {
+ if (TextUtils.equals(recordedProgram.getSeriesId(),
+ mSeriesRecording.getSeriesId())) {
+ if (mWatchedPositionManager.getWatchedPosition(recordedProgram.getId())
+ == TvInputManager.TIME_SHIFT_INVALID_TIME) {
+ mWatchedPositionManager.removeListener(this, recordedProgram.getId());
+ }
+ needToUpdateCardView = true;
+ }
+ }
+ if (needToUpdateCardView) {
+ updateCardViewContent();
+ }
+ }
+
+ @Override
+ public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) {
+ // Do nothing
+ }
+
+ @Override
+ public void onScheduledRecordingStatusChanged(ScheduledRecording... scheduledRecordings) {
+ // Do nothing
+ }
+
+ @Override
+ protected void onBound(SeriesRecording seriesRecording) {
+ mSeriesRecording = seriesRecording;
+ mDvrDataManager.addScheduledRecordingListener(this);
+ mDvrDataManager.addRecordedProgramListener(this);
+ for (RecordedProgram recordedProgram :
+ mDvrDataManager.getRecordedPrograms(mSeriesRecording.getId())) {
+ if (mWatchedPositionManager.getWatchedPosition(recordedProgram.getId())
+ == TvInputManager.TIME_SHIFT_INVALID_TIME) {
+ mWatchedPositionManager.addListener(this, recordedProgram.getId());
+ }
+ }
+ updateCardViewContent();
+ }
+
+ @Override
+ protected void onUnbound() {
+ mDvrDataManager.removeScheduledRecordingListener(this);
+ mDvrDataManager.removeRecordedProgramListener(this);
+ mWatchedPositionManager.removeListener(this);
+ getView().reset();
+ }
+
+ private void updateCardViewContent() {
+ int count = 0;
+ int quantityStringID;
+ List<RecordedProgram> recordedPrograms =
+ mDvrDataManager.getRecordedPrograms(mSeriesRecording.getId());
+ if (recordedPrograms.size() == 0) {
+ count = mDvrManager.getAvailableScheduledRecording(mSeriesRecording.getId()).size();
+ quantityStringID = R.plurals.dvr_count_scheduled_recordings;
+ } else {
+ for (RecordedProgram recordedProgram : recordedPrograms) {
+ if (mWatchedPositionManager.getWatchedPosition(recordedProgram.getId())
+ == TvInputManager.TIME_SHIFT_INVALID_TIME) {
+ count++;
+ }
+ }
+ if (count == 0) {
+ count = recordedPrograms.size();
+ quantityStringID = R.plurals.dvr_count_recordings;
+ } else {
+ quantityStringID = R.plurals.dvr_count_new_recordings;
+ }
+ }
+ mCardView.setContent(mCardView.getResources()
+ .getQuantityString(quantityStringID, count, count), null);
+ }
+ }
+
+ public SeriesRecordingPresenter(Context context) {
+ super(context);
+ ApplicationSingletons singletons = TvApplication.getSingletons(context);
+ mDvrDataManager = singletons.getDvrDataManager();
+ mDvrManager = singletons.getDvrManager();
+ mWatchedPositionManager = singletons.getDvrWatchedPositionManager();
+ }
+
+ @Override
+ public DvrItemViewHolder onCreateDvrItemViewHolder() {
+ return new SeriesRecordingViewHolder(new RecordingCardView(mContext), mDvrDataManager,
+ mDvrManager, mWatchedPositionManager);
+ }
+
+ @Override
+ public void onBindDvrItemViewHolder(DvrItemViewHolder baseHolder, SeriesRecording series) {
+ final SeriesRecordingViewHolder viewHolder = (SeriesRecordingViewHolder) baseHolder;
+ final RecordingCardView cardView = viewHolder.getView();
+ viewHolder.onBound(series);
+ DetailsContent details = DetailsContent.createFromSeriesRecording(mContext, series);
+ cardView.setTitle(details.getTitle());
+ cardView.setImageUri(details.getLogoImageUri(), details.isUsingChannelLogo());
+ cardView.setDetailBackgroundImageUri(details.getBackgroundImageUri());
+ }
+
+ @Override
+ public void onUnbindViewHolder(ViewHolder viewHolder) {
+ ((RecordingCardView) viewHolder.view).reset();
+ ((SeriesRecordingViewHolder) viewHolder).onUnbound();
+ super.onUnbindViewHolder(viewHolder);
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
index d28f026c..b9407b15 100644
--- a/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/BaseDvrSchedulesFragment.java
@@ -29,7 +29,7 @@ import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
/**
* A base fragment to show the list of schedule recordings.
@@ -40,7 +40,8 @@ public abstract class BaseDvrSchedulesFragment extends DetailsFragment
/**
* The key for scheduled recording which has be selected in the list.
*/
- public static String SCHEDULES_KEY_SCHEDULED_RECORDING = "schedules_key_scheduled_recording";
+ public static final String SCHEDULES_KEY_SCHEDULED_RECORDING =
+ "schedules_key_scheduled_recording";
private ScheduleRowAdapter mRowsAdapter;
private TextView mEmptyInfoScreenView;
diff --git a/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java b/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java
new file mode 100644
index 00000000..a0410bb3
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/list/DvrSchedulesActivity.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.list;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.os.Bundle;
+import android.support.annotation.IntDef;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.data.Program;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
+import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
+import com.android.tv.dvr.ui.BigArguments;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Activity to show the list of recording schedules.
+ */
+public class DvrSchedulesActivity extends Activity {
+ /**
+ * The key for the type of the schedules which will be listed in the list. The type of the value
+ * should be {@link ScheduleListType}.
+ */
+ public static final String KEY_SCHEDULES_TYPE = "schedules_type";
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({TYPE_FULL_SCHEDULE, TYPE_SERIES_SCHEDULE})
+ public @interface ScheduleListType {}
+ /**
+ * A type which means the activity will display the full scheduled recordings.
+ */
+ public static final int TYPE_FULL_SCHEDULE = 0;
+ /**
+ * A type which means the activity will display a scheduled recording list of a series
+ * recording.
+ */
+ public static final int TYPE_SERIES_SCHEDULE = 1;
+
+ @Override
+ public void onCreate(final Bundle savedInstanceState) {
+ TvApplication.setCurrentRunningProcess(this, true);
+ // Pass null to prevent automatically re-creating fragments
+ super.onCreate(null);
+ setContentView(R.layout.activity_dvr_schedules);
+ int scheduleType = getIntent().getIntExtra(KEY_SCHEDULES_TYPE, TYPE_FULL_SCHEDULE);
+ if (scheduleType == TYPE_FULL_SCHEDULE) {
+ DvrSchedulesFragment schedulesFragment = new DvrSchedulesFragment();
+ schedulesFragment.setArguments(getIntent().getExtras());
+ getFragmentManager().beginTransaction().add(
+ R.id.fragment_container, schedulesFragment).commit();
+ } else if (scheduleType == TYPE_SERIES_SCHEDULE) {
+ if (BigArguments.getArgument(DvrSeriesSchedulesFragment
+ .SERIES_SCHEDULES_KEY_SERIES_PROGRAMS) != null) {
+ // The programs will be passed to the DvrSeriesSchedulesFragment, so don't need
+ // to reset the BigArguments.
+ showDvrSeriesSchedulesFragment(getIntent().getExtras());
+ } else {
+ final ProgressDialog dialog = ProgressDialog.show(this, null, getString(
+ R.string.dvr_series_progress_message_reading_programs));
+ SeriesRecording seriesRecording = getIntent().getExtras()
+ .getParcelable(DvrSeriesSchedulesFragment
+ .SERIES_SCHEDULES_KEY_SERIES_RECORDING);
+ // To get programs faster, hold the update of the series schedules.
+ SeriesRecordingScheduler.getInstance(this).pauseUpdate();
+ new EpisodicProgramLoadTask(this, Collections.singletonList(seriesRecording)) {
+ @Override
+ protected void onPostExecute(List<Program> programs) {
+ SeriesRecordingScheduler.getInstance(DvrSchedulesActivity.this)
+ .resumeUpdate();
+ dialog.dismiss();
+ Bundle args = getIntent().getExtras();
+ BigArguments.reset();
+ BigArguments.setArgument(
+ DvrSeriesSchedulesFragment.SERIES_SCHEDULES_KEY_SERIES_PROGRAMS,
+ programs == null ? Collections.EMPTY_LIST : programs);
+ showDvrSeriesSchedulesFragment(args);
+ }
+ }.setLoadCurrentProgram(true)
+ .setLoadDisallowedProgram(true)
+ .setLoadScheduledEpisode(true)
+ .setIgnoreChannelOption(true)
+ .execute();
+ }
+ } else {
+ finish();
+ }
+ }
+
+ private void showDvrSeriesSchedulesFragment(Bundle args) {
+ DvrSeriesSchedulesFragment schedulesFragment = new DvrSeriesSchedulesFragment();
+ schedulesFragment.setArguments(args);
+ getFragmentManager().beginTransaction().add(
+ R.id.fragment_container, schedulesFragment).commit();
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
index 722c9b6e..3cbb500a 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSchedulesFragment.java
@@ -18,12 +18,9 @@ package com.android.tv.dvr.ui.list;
import android.os.Bundle;
import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
import com.android.tv.R;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRowPresenter.DateHeaderRowPresenter;
/**
diff --git a/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java b/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
index 42a1e72b..57e7a88f 100644
--- a/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
+++ b/src/com/android/tv/dvr/ui/list/DvrSeriesSchedulesFragment.java
@@ -17,6 +17,7 @@
package com.android.tv.dvr.ui.list;
import android.annotation.TargetApi;
+import android.content.Context;
import android.database.ContentObserver;
import android.media.tv.TvContract.Programs;
import android.net.Uri;
@@ -35,11 +36,13 @@ import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.Program;
+import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.SeriesRecordingListener;
-import com.android.tv.dvr.EpisodicProgramLoadTask;
-import com.android.tv.dvr.SeriesRecording;
-import com.android.tv.dvr.ui.list.SchedulesHeaderRowPresenter.SeriesRecordingHeaderRowPresenter;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.provider.EpisodicProgramLoadTask;
+import com.android.tv.dvr.ui.BigArguments;
+import java.util.Collections;
import java.util.List;
/**
@@ -47,20 +50,22 @@ import java.util.List;
*/
@TargetApi(Build.VERSION_CODES.N)
public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
- private static final String TAG = "DvrSeriesSchedulesFragment";
/**
* The key for series recording whose scheduled recording list will be displayed.
+ * Type: {@link SeriesRecording}
*/
public static final String SERIES_SCHEDULES_KEY_SERIES_RECORDING =
"series_schedules_key_series_recording";
/**
- * The key for programs belong to the series recording whose scheduled recording
- * list will be displayed.
+ * The key for programs which belong to the series recording whose scheduled recording list
+ * will be displayed.
+ * Type: List<{@link Program}>
*/
public static final String SERIES_SCHEDULES_KEY_SERIES_PROGRAMS =
"series_schedules_key_series_programs";
private ChannelDataManager mChannelDataManager;
+ private DvrDataManager mDvrDataManager;
private SeriesRecording mSeriesRecording;
private List<Program> mPrograms;
private EpisodicProgramLoadTask mProgramLoadTask;
@@ -87,20 +92,22 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
&& getRowsAdapter() instanceof SeriesScheduleRowAdapter) {
((SeriesScheduleRowAdapter) getRowsAdapter())
.onSeriesRecordingUpdated(r);
+ mSeriesRecording = r;
+ updateEmptyMessage();
return;
}
}
}
};
- private final ContentObserver mContentObserver =
- new ContentObserver(new Handler(Looper.getMainLooper())) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- super.onChange(selfChange, uri);
- executeProgramLoadingTask();
- }
- };
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+ private final ContentObserver mContentObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ executeProgramLoadingTask();
+ }
+ };
private final ChannelDataManager.Listener mChannelListener = new ChannelDataManager.Listener() {
@Override
@@ -120,17 +127,28 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
}
@Override
- public void onCreate(Bundle savedInstanceState) {
+ public void onAttach(Context context) {
+ super.onAttach(context);
Bundle args = getArguments();
if (args != null) {
mSeriesRecording = args.getParcelable(SERIES_SCHEDULES_KEY_SERIES_RECORDING);
- mPrograms = args.getParcelableArrayList(SERIES_SCHEDULES_KEY_SERIES_PROGRAMS);
+ mPrograms = (List<Program>) BigArguments.getArgument(
+ SERIES_SCHEDULES_KEY_SERIES_PROGRAMS);
+ BigArguments.reset();
}
+ if (args == null || mPrograms == null) {
+ getActivity().finish();
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ApplicationSingletons singletons = TvApplication.getSingletons(getContext());
- singletons.getDvrDataManager().addSeriesRecordingListener(mSeriesRecordingListener);
mChannelDataManager = singletons.getChannelDataManager();
mChannelDataManager.addListener(mChannelListener);
+ mDvrDataManager = singletons.getDvrDataManager();
+ mDvrDataManager.addSeriesRecordingListener(mSeriesRecordingListener);
getContext().getContentResolver().registerContentObserver(Programs.CONTENT_URI, true,
mContentObserver);
}
@@ -144,8 +162,16 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
private void onProgramsUpdated() {
((SeriesScheduleRowAdapter) getRowsAdapter()).setPrograms(mPrograms);
+ updateEmptyMessage();
+ }
+
+ private void updateEmptyMessage() {
if (mPrograms == null || mPrograms.isEmpty()) {
- showEmptyMessage(R.string.dvr_series_schedules_empty_state);
+ if (mSeriesRecording.getState() == SeriesRecording.STATE_SERIES_STOPPED) {
+ showEmptyMessage(R.string.dvr_series_schedules_stopped_empty_state);
+ } else {
+ showEmptyMessage(R.string.dvr_series_schedules_empty_state);
+ }
} else {
hideEmptyMessage();
}
@@ -158,15 +184,15 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
mProgramLoadTask = null;
}
getContext().getContentResolver().unregisterContentObserver(mContentObserver);
+ mHandler.removeCallbacksAndMessages(null);
mChannelDataManager.removeListener(mChannelListener);
- TvApplication.getSingletons(getContext()).getDvrDataManager()
- .removeSeriesRecordingListener(mSeriesRecordingListener);
+ mDvrDataManager.removeSeriesRecordingListener(mSeriesRecordingListener);
super.onDestroy();
}
@Override
public SchedulesHeaderRowPresenter onCreateHeaderRowPresenter() {
- return new SeriesRecordingHeaderRowPresenter(getContext());
+ return new SchedulesHeaderRowPresenter.SeriesRecordingHeaderRowPresenter(getContext());
}
@Override
@@ -195,7 +221,7 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
mProgramLoadTask = new EpisodicProgramLoadTask(getContext(), mSeriesRecording) {
@Override
protected void onPostExecute(List<Program> programs) {
- mPrograms = programs;
+ mPrograms = programs == null ? Collections.EMPTY_LIST : programs;
onProgramsUpdated();
}
};
@@ -205,4 +231,4 @@ public class DvrSeriesSchedulesFragment extends BaseDvrSchedulesFragment {
.setIgnoreChannelOption(true)
.execute();
}
-} \ No newline at end of file
+}
diff --git a/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java b/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
index 23aebf59..2af832ec 100644
--- a/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
+++ b/src/com/android/tv/dvr/ui/list/EpisodicProgramRow.java
@@ -19,13 +19,14 @@ package com.android.tv.dvr.ui.list;
import android.content.Context;
import com.android.tv.data.Program;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.dvr.ScheduledRecording.Builder;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording.Builder;
+import com.android.tv.dvr.ui.DvrUiHelper;
/**
* A class for the episodic program.
*/
-public class EpisodicProgramRow extends ScheduleRow {
+class EpisodicProgramRow extends ScheduleRow {
private final String mInputId;
private final Program mProgram;
@@ -65,7 +66,7 @@ public class EpisodicProgramRow extends ScheduleRow {
@Override
public String getProgramTitleWithEpisodeNumber(Context context) {
- return mProgram.getTitleWithEpisodeNumber(context);
+ return DvrUiHelper.getStyledTitleWithEpisodeNumber(context, mProgram, 0).toString();
}
@Override
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRow.java b/src/com/android/tv/dvr/ui/list/ScheduleRow.java
index 3fc92e8a..91ba393a 100644
--- a/src/com/android/tv/dvr/ui/list/ScheduleRow.java
+++ b/src/com/android/tv/dvr/ui/list/ScheduleRow.java
@@ -20,12 +20,13 @@ import android.content.Context;
import android.support.annotation.Nullable;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ui.DvrUiHelper;
/**
* A class for schedule recording row.
*/
-public class ScheduleRow {
+class ScheduleRow {
private final SchedulesHeaderRow mHeaderRow;
@Nullable private ScheduledRecording mSchedule;
private boolean mStopRecordingRequested;
@@ -166,7 +167,8 @@ public class ScheduleRow {
* Returns the program title with episode number.
*/
public String getProgramTitleWithEpisodeNumber(Context context) {
- return mSchedule != null ? mSchedule.getProgramTitleWithEpisodeNumber(context) : null;
+ return mSchedule != null ? DvrUiHelper.getStyledTitleWithEpisodeNumber(context,
+ mSchedule, 0).toString() : null;
}
/**
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java b/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
index 9cc82653..97d60473 100644
--- a/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/ScheduleRowAdapter.java
@@ -30,8 +30,8 @@ import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.ScheduledRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.DateHeaderRow;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.util.Utils;
import java.util.ArrayList;
@@ -43,7 +43,7 @@ import java.util.concurrent.TimeUnit;
/**
* An adapter for {@link ScheduleRow}.
*/
-public class ScheduleRowAdapter extends ArrayObjectAdapter {
+class ScheduleRowAdapter extends ArrayObjectAdapter {
private static final String TAG = "ScheduleRowAdapter";
private static final boolean DEBUG = false;
diff --git a/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java b/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
index 1257e725..dc4e3c41 100644
--- a/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/list/ScheduleRowPresenter.java
@@ -42,25 +42,24 @@ import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
+import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.DvrScheduleManager;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.DvrStopRecordingFragment;
-import com.android.tv.dvr.ui.HalfSizedDialogFragment;
+import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.util.ToastUtils;
import com.android.tv.util.Utils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
-import java.util.concurrent.TimeUnit;
/**
* A RowPresenter for {@link ScheduleRow}.
*/
@TargetApi(Build.VERSION_CODES.N)
-public class ScheduleRowPresenter extends RowPresenter {
+class ScheduleRowPresenter extends RowPresenter {
private static final String TAG = "ScheduleRowPresenter";
@Retention(RetentionPolicy.SOURCE)
@@ -345,7 +344,9 @@ public class ScheduleRowPresenter extends RowPresenter {
viewHolder.mInfoContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- onInfoClicked(row);
+ if (isInfoClickable(row)) {
+ onInfoClicked(row);
+ }
}
});
@@ -366,8 +367,7 @@ public class ScheduleRowPresenter extends RowPresenter {
viewHolder.mTimeView.setText(onGetRecordingTimeText(row));
String programInfoText = onGetProgramInfoText(row);
if (TextUtils.isEmpty(programInfoText)) {
- int durationMins =
- Math.max((int) TimeUnit.MILLISECONDS.toMinutes(row.getDuration()), 1);
+ int durationMins = Math.max(1, Utils.getRoundOffMinsFromMs(row.getDuration()));
programInfoText = mContext.getResources().getQuantityString(
R.plurals.dvr_schedules_recording_duration, durationMins, durationMins);
}
@@ -403,6 +403,7 @@ public class ScheduleRowPresenter extends RowPresenter {
} else {
viewHolder.whiteBackInfo();
}
+ viewHolder.mInfoContainer.setFocusable(isInfoClickable(row));
updateActionContainer(viewHolder, viewHolder.isSelected());
}
@@ -454,11 +455,13 @@ public class ScheduleRowPresenter extends RowPresenter {
/**
* Called when user click Info in {@link ScheduleRow}.
*/
- protected void onInfoClicked(ScheduleRow scheduleRow) {
- ScheduledRecording schedule = scheduleRow.getSchedule();
- if (schedule != null) {
- DvrUiHelper.startDetailsActivity((Activity) mContext, schedule, null, true);
- }
+ protected void onInfoClicked(ScheduleRow row) {
+ DvrUiHelper.startDetailsActivity((Activity) mContext, row.getSchedule(), null, true);
+ }
+
+ private boolean isInfoClickable(ScheduleRow row) {
+ return row.getSchedule() != null
+ && (row.getSchedule().isNotStarted() || row.getSchedule().isInProgress());
}
/**
@@ -545,7 +548,7 @@ public class ScheduleRowPresenter extends RowPresenter {
// This row has been deleted.
return;
}
- if (row.isOnAir() && row.isRecordingInProgress() && !row.isStopRecordingRequested()) {
+ if (row.isRecordingInProgress() && !row.isStopRecordingRequested()) {
row.setStopRecordingRequested(true);
mDvrManager.stopRecording(row.getSchedule());
CharSequence deletedInfo = onGetProgramInfoText(row);
@@ -670,10 +673,9 @@ public class ScheduleRowPresenter extends RowPresenter {
hideActionView(viewHolder.mFirstActionContainer, View.GONE);
}
};
- if (mLastFocusedViewId == R.id.action_first_container
- || mLastFocusedViewId == R.id.action_second_container) {
- mLastFocusedViewId = R.id.info_container;
- }
+ mLastFocusedViewId = R.id.info_container;
+ SoftPreconditions.checkState(viewHolder.mInfoContainer.isFocusable(), TAG,
+ "No focusable view in this row: " + viewHolder);
break;
}
View view = viewHolder.view.findViewById(mLastFocusedViewId);
@@ -683,8 +685,10 @@ public class ScheduleRowPresenter extends RowPresenter {
// requestFocus() explicitly.
if (view.hasFocus()) {
viewHolder.mPendingAnimationRunnable.run();
- } else {
+ } else if (view.isFocusable()){
view.requestFocus();
+ } else {
+ viewHolder.view.requestFocus();
}
}
} else {
@@ -737,10 +741,10 @@ public class ScheduleRowPresenter extends RowPresenter {
@ScheduleRowAction
protected int[] getAvailableActions(ScheduleRow row) {
if (row.getSchedule() != null) {
- if (row.isOnAir()) {
- if (row.isRecordingInProgress()) {
- return new int[] {ACTION_STOP_RECORDING};
- } else if (row.isRecordingNotStarted()) {
+ if (row.isRecordingInProgress()) {
+ return new int[]{ACTION_STOP_RECORDING};
+ } else if (row.isOnAir()) {
+ if (row.isRecordingNotStarted()) {
if (canResolveConflict()) {
// The "START" action can change the conflict states.
return new int[] {ACTION_REMOVE_SCHEDULE, ACTION_START_RECORDING};
diff --git a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
index 0fb0924d..715ecb8c 100644
--- a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
+++ b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRow.java
@@ -16,12 +16,15 @@
package com.android.tv.dvr.ui.list;
-import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.data.Program;
+import com.android.tv.dvr.data.SeriesRecording;
+
+import java.util.List;
/**
* A base class for the rows for schedules' header.
*/
-public abstract class SchedulesHeaderRow {
+abstract class SchedulesHeaderRow {
private String mTitle;
private String mDescription;
private int mItemCount;
@@ -98,11 +101,20 @@ public abstract class SchedulesHeaderRow {
*/
public static class SeriesRecordingHeaderRow extends SchedulesHeaderRow {
private SeriesRecording mSeriesRecording;
+ private List<Program> mPrograms;
public SeriesRecordingHeaderRow(String title, String description, int itemCount,
- SeriesRecording series) {
+ SeriesRecording series, List<Program> programs) {
super(title, description, itemCount);
mSeriesRecording = series;
+ mPrograms = programs;
+ }
+
+ /**
+ * Returns the list of programs which belong to the series.
+ */
+ public List<Program> getPrograms() {
+ return mPrograms;
}
/**
@@ -119,4 +131,4 @@ public abstract class SchedulesHeaderRow {
mSeriesRecording = seriesRecording;
}
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
index 69c33a96..fe2033ba 100644
--- a/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/list/SchedulesHeaderRowPresenter.java
@@ -30,15 +30,14 @@ import android.widget.TextView;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.SeriesRecording;
-import com.android.tv.dvr.ui.DvrSchedulesActivity;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.SeriesRecordingHeaderRow;
/**
* A base class for RowPresenter for {@link SchedulesHeaderRow}
*/
-public abstract class SchedulesHeaderRowPresenter extends RowPresenter {
+abstract class SchedulesHeaderRowPresenter extends RowPresenter {
private Context mContext;
public SchedulesHeaderRowPresenter(Context context) {
@@ -79,7 +78,7 @@ public abstract class SchedulesHeaderRowPresenter extends RowPresenter {
}
/**
- * A presenter for {@link com.android.tv.dvr.ui.list.SchedulesHeaderRow.DateHeaderRow}.
+ * A presenter for {@link SchedulesHeaderRow.DateHeaderRow}.
*/
public static class DateHeaderRowPresenter extends SchedulesHeaderRowPresenter {
public DateHeaderRowPresenter(Context context) {
@@ -93,7 +92,7 @@ public abstract class SchedulesHeaderRowPresenter extends RowPresenter {
/**
* A ViewHolder for
- * {@link com.android.tv.dvr.ui.list.SchedulesHeaderRow.DateHeaderRow}.
+ * {@link SchedulesHeaderRow.DateHeaderRow}.
*/
public static class DateHeaderRowViewHolder extends SchedulesHeaderRowViewHolder {
public DateHeaderRowViewHolder(Context context, ViewGroup parent) {
@@ -152,9 +151,9 @@ public abstract class SchedulesHeaderRowPresenter extends RowPresenter {
headerViewHolder.mSeriesSettingsButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
- // TODO: pass channel list for settings.
DvrUiHelper.startSeriesSettingsActivity(getContext(),
- header.getSeriesRecording().getId(), null, false, false, false);
+ header.getSeriesRecording().getId(),
+ header.getPrograms(), false, false, false, null);
}
});
headerViewHolder.mToggleStartStopButton.setOnClickListener(new OnClickListener() {
@@ -169,9 +168,9 @@ public abstract class SchedulesHeaderRowPresenter extends RowPresenter {
.build();
TvApplication.getSingletons(getContext()).getDvrManager()
.updateSeriesRecording(seriesRecording);
- // TODO: pass channel list for settings.
DvrUiHelper.startSeriesSettingsActivity(getContext(),
- header.getSeriesRecording().getId(), null, false, false, false);
+ header.getSeriesRecording().getId(),
+ header.getPrograms(), false, false, false, null);
} else {
DvrUiHelper.showCancelAllSeriesRecordingDialog(
(DvrSchedulesActivity) view.getContext(),
@@ -182,11 +181,8 @@ public abstract class SchedulesHeaderRowPresenter extends RowPresenter {
}
private void setTextDrawable(TextView textView, Drawable drawableStart) {
- if (mLtr) {
- textView.setCompoundDrawablesWithIntrinsicBounds(drawableStart, null, null, null);
- } else {
- textView.setCompoundDrawablesWithIntrinsicBounds(null, null, drawableStart, null);
- }
+ textView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStart, null, null,
+ null);
}
/**
diff --git a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
index 3b493774..6b6de8b8 100644
--- a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
+++ b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowAdapter.java
@@ -31,8 +31,8 @@ import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Program;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.ScheduledRecording;
-import com.android.tv.dvr.SeriesRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.SeriesRecordingHeaderRow;
import com.android.tv.util.Utils;
@@ -46,7 +46,7 @@ import java.util.Map;
* An adapter for series schedule row.
*/
@TargetApi(Build.VERSION_CODES.N)
-public class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
+class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
private static final String TAG = "SeriesRowAdapter";
private static final boolean DEBUG = false;
@@ -96,7 +96,7 @@ public class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
Collections.sort(sortedPrograms);
List<EpisodicProgramRow> rows = new ArrayList<>();
mHeaderRow = new SeriesRecordingHeaderRow(mSeriesRecording.getTitle(),
- null, sortedPrograms.size(), mSeriesRecording);
+ null, sortedPrograms.size(), mSeriesRecording, programs);
for (Program program : sortedPrograms) {
ScheduledRecording schedule =
mDataManager.getScheduledRecordingForProgramId(program.getId());
@@ -145,7 +145,7 @@ public class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
if (index != -1) {
EpisodicProgramRow row = (EpisodicProgramRow) get(index);
if (!row.isStartRecordingRequested()) {
- row.setSchedule(schedule);
+ setScheduleToRow(row, schedule);
notifyArrayItemRangeChanged(index, 1);
}
}
@@ -195,12 +195,10 @@ public class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
if (!isStartOrStopRequested()) {
executePendingUpdate();
}
- row.setSchedule(schedule);
+ setScheduleToRow(row, schedule);
}
- } else if (willBeKept(schedule)) {
- row.setSchedule(schedule);
} else {
- row.setSchedule(null);
+ setScheduleToRow(row, schedule);
}
notifyArrayItemRangeChanged(index, 1);
}
@@ -213,6 +211,14 @@ public class SeriesScheduleRowAdapter extends ScheduleRowAdapter {
}
}
+ private void setScheduleToRow(ScheduleRow row, ScheduledRecording schedule) {
+ if (schedule != null && willBeKept(schedule)) {
+ row.setSchedule(schedule);
+ } else {
+ row.setSchedule(null);
+ }
+ }
+
private int findRowIndexByProgramId(long programId) {
for (int i = 0; i < size(); i++) {
Object item = get(i);
diff --git a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowPresenter.java b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowPresenter.java
index 5d88579a..c8503e0d 100644
--- a/src/com/android/tv/dvr/ui/list/SeriesScheduleRowPresenter.java
+++ b/src/com/android/tv/dvr/ui/list/SeriesScheduleRowPresenter.java
@@ -22,13 +22,13 @@ import android.view.ViewGroup;
import com.android.tv.R;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dvr.DvrUiHelper;
+import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.util.Utils;
/**
* A RowPresenter for series schedule row.
*/
-public class SeriesScheduleRowPresenter extends ScheduleRowPresenter {
+class SeriesScheduleRowPresenter extends ScheduleRowPresenter {
private static final String TAG = "SeriesRowPresenter";
private boolean mLtr;
@@ -74,13 +74,8 @@ public class SeriesScheduleRowPresenter extends ScheduleRowPresenter {
viewHolder.getProgramTitleView().setCompoundDrawablePadding(getContext()
.getResources().getDimensionPixelOffset(
R.dimen.dvr_schedules_warning_icon_padding));
- if (mLtr) {
- viewHolder.getProgramTitleView().setCompoundDrawablesWithIntrinsicBounds(
- R.drawable.ic_warning_gray600_36dp, 0, 0, 0);
- } else {
- viewHolder.getProgramTitleView().setCompoundDrawablesWithIntrinsicBounds(
- 0, 0, R.drawable.ic_warning_gray600_36dp, 0);
- }
+ viewHolder.getProgramTitleView().setCompoundDrawablesRelativeWithIntrinsicBounds(
+ R.drawable.ic_warning_gray600_36dp, 0, 0, 0);
} else {
viewHolder.getProgramTitleView().setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
@@ -88,9 +83,7 @@ public class SeriesScheduleRowPresenter extends ScheduleRowPresenter {
@Override
protected void onInfoClicked(ScheduleRow row) {
- if (row.getSchedule() != null) {
- DvrUiHelper.startSchedulesActivity(getContext(), row.getSchedule());
- }
+ DvrUiHelper.startSchedulesActivity(getContext(), row.getSchedule());
}
@Override
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
new file mode 100644
index 00000000..6824cfe2
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackActivity.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.playback;
+
+import android.app.Activity;
+import android.content.ContentUris;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.dialog.PinDialogFragment.OnPinCheckedListener;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.util.Utils;
+
+/**
+ * Activity to play a {@link RecordedProgram}.
+ */
+public class DvrPlaybackActivity extends Activity implements OnPinCheckedListener {
+ private static final String TAG = "DvrPlaybackActivity";
+ private static final boolean DEBUG = false;
+
+ private DvrPlaybackOverlayFragment mOverlayFragment;
+ private OnPinCheckedListener mOnPinCheckedListener;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ TvApplication.setCurrentRunningProcess(this, true);
+ if (DEBUG) Log.d(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+ setIntent(createProgramIntent(getIntent()));
+ setContentView(R.layout.activity_dvr_playback);
+ mOverlayFragment = (DvrPlaybackOverlayFragment) getFragmentManager()
+ .findFragmentById(R.id.dvr_playback_controls_fragment);
+ }
+
+ @Override
+ public void onVisibleBehindCanceled() {
+ if (DEBUG) Log.d(TAG, "onVisibleBehindCanceled");
+ super.onVisibleBehindCanceled();
+ finish();
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ setIntent(createProgramIntent(intent));
+ mOverlayFragment.onNewIntent(createProgramIntent(intent));
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ float density = getResources().getDisplayMetrics().density;
+ mOverlayFragment.onWindowSizeChanged((int) (newConfig.screenWidthDp * density),
+ (int) (newConfig.screenHeightDp * density));
+ }
+
+ private Intent createProgramIntent(Intent intent) {
+ if (Intent.ACTION_VIEW.equals(intent.getAction())) {
+ Uri uri = intent.getData();
+ long recordedProgramId = ContentUris.parseId(uri);
+ intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, recordedProgramId);
+ }
+ return intent;
+ }
+
+ @Override
+ public void onPinChecked(boolean checked, int type, String rating) {
+ if (mOnPinCheckedListener != null) {
+ mOnPinCheckedListener.onPinChecked(checked, type, rating);
+ }
+ }
+
+ void setOnPinCheckListener(OnPinCheckedListener listener) {
+ mOnPinCheckedListener = listener;
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackCardPresenter.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackCardPresenter.java
new file mode 100644
index 00000000..8ef0041d
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackCardPresenter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 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.tv.dvr.ui.playback;
+
+import android.content.Context;
+
+import com.android.tv.R;
+import com.android.tv.dvr.ui.browse.RecordedProgramPresenter;
+import com.android.tv.dvr.ui.browse.RecordingCardView;
+
+/**
+ * This class is used to generate Views and bind Objects for related recordings in DVR playback.
+ */
+class DvrPlaybackCardPresenter extends RecordedProgramPresenter {
+ private final int mRelatedRecordingCardWidth;
+ private final int mRelatedRecordingCardHeight;
+
+ DvrPlaybackCardPresenter(Context context) {
+ super(context);
+ mRelatedRecordingCardWidth =
+ context.getResources().getDimensionPixelSize(R.dimen.dvr_related_recordings_width);
+ mRelatedRecordingCardHeight =
+ context.getResources().getDimensionPixelSize(R.dimen.dvr_related_recordings_height);
+ }
+
+ @Override
+ public DvrItemViewHolder onCreateDvrItemViewHolder() {
+ return new RecordedProgramViewHolder(new RecordingCardView(
+ getContext(), mRelatedRecordingCardWidth, mRelatedRecordingCardHeight, true), null);
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java
new file mode 100644
index 00000000..1a6ae187
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackControlHelper.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.playback;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.media.MediaMetadata;
+import android.media.session.MediaController;
+import android.media.session.MediaController.TransportControls;
+import android.media.session.PlaybackState;
+import android.media.tv.TvTrackInfo;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v17.leanback.media.PlaybackControlGlue;
+import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter;
+import android.support.v17.leanback.widget.Action;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.PlaybackControlsRow;
+import android.support.v17.leanback.widget.PlaybackControlsRow.ClosedCaptioningAction;
+import android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction;
+import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import com.android.tv.R;
+import com.android.tv.util.TimeShiftUtils;
+import java.util.ArrayList;
+
+/**
+ * A helper class to assist {@link DvrPlaybackOverlayFragment} to manage its controls row and
+ * send command to the media controller. It also helps to update playback states displayed in the
+ * fragment according to information the media session provides.
+ */
+class DvrPlaybackControlHelper extends PlaybackControlGlue {
+ private static final String TAG = "DvrPlaybackControlHelpr";
+ private static final boolean DEBUG = false;
+
+ private static final int AUDIO_ACTION_ID = 1001;
+
+ private int mPlaybackState = PlaybackState.STATE_NONE;
+ private int mPlaybackSpeedLevel;
+ private int mPlaybackSpeedId;
+ private boolean mReadyToControl;
+
+ private final DvrPlaybackOverlayFragment mFragment;
+ private final MediaController mMediaController;
+ private final MediaController.Callback mMediaControllerCallback = new MediaControllerCallback();
+ private final TransportControls mTransportControls;
+ private final int mExtraPaddingTopForNoDescription;
+ private final MultiAction mClosedCaptioningAction;
+ private final MultiAction mMultiAudioAction;
+ private ArrayObjectAdapter mSecondaryActionsAdapter;
+
+ DvrPlaybackControlHelper(Activity activity, DvrPlaybackOverlayFragment overlayFragment) {
+ super(activity, new int[TimeShiftUtils.MAX_SPEED_LEVEL + 1]);
+ mFragment = overlayFragment;
+ mMediaController = activity.getMediaController();
+ mMediaController.registerCallback(mMediaControllerCallback);
+ mTransportControls = mMediaController.getTransportControls();
+ mExtraPaddingTopForNoDescription = activity.getResources()
+ .getDimensionPixelOffset(R.dimen.dvr_playback_controls_extra_padding_top);
+ mClosedCaptioningAction = new ClosedCaptioningAction(activity);
+ mMultiAudioAction = new MultiAudioAction(activity);
+ createControlsRowPresenter();
+ }
+
+ void createControlsRow() {
+ PlaybackControlsRow controlsRow = new PlaybackControlsRow(this);
+ setControlsRow(controlsRow);
+ mSecondaryActionsAdapter = (ArrayObjectAdapter) controlsRow.getSecondaryActionsAdapter();
+ }
+
+ private void createControlsRowPresenter() {
+ AbstractDetailsDescriptionPresenter detailsPresenter =
+ new AbstractDetailsDescriptionPresenter() {
+ @Override
+ protected void onBindDescription(
+ AbstractDetailsDescriptionPresenter.ViewHolder viewHolder, Object object) {
+ PlaybackControlGlue glue = (PlaybackControlGlue) object;
+ if (glue.hasValidMedia()) {
+ viewHolder.getTitle().setText(glue.getMediaTitle());
+ viewHolder.getSubtitle().setText(glue.getMediaSubtitle());
+ } else {
+ viewHolder.getTitle().setText("");
+ viewHolder.getSubtitle().setText("");
+ }
+ if (TextUtils.isEmpty(viewHolder.getSubtitle().getText())) {
+ viewHolder.view.setPadding(viewHolder.view.getPaddingLeft(),
+ mExtraPaddingTopForNoDescription,
+ viewHolder.view.getPaddingRight(), viewHolder.view.getPaddingBottom());
+ }
+ }
+ };
+ PlaybackControlsRowPresenter presenter =
+ new PlaybackControlsRowPresenter(detailsPresenter) {
+ @Override
+ protected void onBindRowViewHolder(RowPresenter.ViewHolder vh, Object item) {
+ super.onBindRowViewHolder(vh, item);
+ vh.setOnKeyListener(DvrPlaybackControlHelper.this);
+ }
+
+ @Override
+ protected void onUnbindRowViewHolder(RowPresenter.ViewHolder vh) {
+ super.onUnbindRowViewHolder(vh);
+ vh.setOnKeyListener(null);
+ }
+ };
+ presenter.setProgressColor(getContext().getResources()
+ .getColor(R.color.play_controls_progress_bar_watched));
+ presenter.setBackgroundColor(getContext().getResources()
+ .getColor(R.color.play_controls_body_background_enabled));
+ setControlsRowPresenter(presenter);
+ }
+
+ @Override
+ public void onActionClicked(Action action) {
+ if (mReadyToControl) {
+ int trackType;
+ if (action.getId() == mClosedCaptioningAction.getId()) {
+ trackType = TvTrackInfo.TYPE_SUBTITLE;
+ } else if (action.getId() == AUDIO_ACTION_ID) {
+ trackType = TvTrackInfo.TYPE_AUDIO;
+ } else {
+ super.onActionClicked(action);
+ return;
+ }
+ ArrayList<TvTrackInfo> trackInfos = mFragment.getTracks(trackType);
+ if (!trackInfos.isEmpty()) {
+ showSideFragment(trackInfos, mFragment.getSelectedTrackId(trackType));
+ }
+ }
+ }
+
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ return mReadyToControl && super.onKey(v, keyCode, event);
+ }
+
+ @Override
+ public boolean hasValidMedia() {
+ PlaybackState playbackState = mMediaController.getPlaybackState();
+ return playbackState != null;
+ }
+
+ @Override
+ public boolean isMediaPlaying() {
+ PlaybackState playbackState = mMediaController.getPlaybackState();
+ if (playbackState == null) {
+ return false;
+ }
+ int state = playbackState.getState();
+ return state != PlaybackState.STATE_NONE && state != PlaybackState.STATE_CONNECTING
+ && state != PlaybackState.STATE_PAUSED;
+ }
+
+ /**
+ * Returns the ID of the media under playback.
+ */
+ public String getMediaId() {
+ MediaMetadata mediaMetadata = mMediaController.getMetadata();
+ return mediaMetadata == null ? null
+ : mediaMetadata.getString(MediaMetadata.METADATA_KEY_MEDIA_ID);
+ }
+
+ @Override
+ public CharSequence getMediaTitle() {
+ MediaMetadata mediaMetadata = mMediaController.getMetadata();
+ return mediaMetadata == null ? ""
+ : mediaMetadata.getString(MediaMetadata.METADATA_KEY_TITLE);
+ }
+
+ @Override
+ public CharSequence getMediaSubtitle() {
+ MediaMetadata mediaMetadata = mMediaController.getMetadata();
+ return mediaMetadata == null ? ""
+ : mediaMetadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE);
+ }
+
+ @Override
+ public int getMediaDuration() {
+ MediaMetadata mediaMetadata = mMediaController.getMetadata();
+ return mediaMetadata == null ? 0
+ : (int) mediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
+ }
+
+ @Override
+ public Drawable getMediaArt() {
+ // Do not show the poster art on control row.
+ return null;
+ }
+
+ @Override
+ public long getSupportedActions() {
+ return ACTION_PLAY_PAUSE | ACTION_FAST_FORWARD | ACTION_REWIND;
+ }
+
+ @Override
+ public int getCurrentSpeedId() {
+ return mPlaybackSpeedId;
+ }
+
+ @Override
+ public int getCurrentPosition() {
+ PlaybackState playbackState = mMediaController.getPlaybackState();
+ if (playbackState == null) {
+ return 0;
+ }
+ return (int) playbackState.getPosition();
+ }
+
+ /**
+ * Unregister media controller's callback.
+ */
+ void unregisterCallback() {
+ mMediaController.unregisterCallback(mMediaControllerCallback);
+ }
+
+ /**
+ * Update the secondary controls row.
+ * @param hasClosedCaption {@code true} to show the closed caption selection button,
+ * {@code false} to hide it.
+ * @param hasMultiAudio {@code true} to show the audio track selection button,
+ * {@code false} to hide it.
+ */
+ void updateSecondaryRow(boolean hasClosedCaption, boolean hasMultiAudio) {
+ if (hasClosedCaption) {
+ if (mSecondaryActionsAdapter.indexOf(mClosedCaptioningAction) < 0) {
+ mSecondaryActionsAdapter.add(0, mClosedCaptioningAction);
+ }
+ } else {
+ mSecondaryActionsAdapter.remove(mClosedCaptioningAction);
+ }
+ if (hasMultiAudio) {
+ if (mSecondaryActionsAdapter.indexOf(mMultiAudioAction) < 0) {
+ mSecondaryActionsAdapter.add(mMultiAudioAction);
+ }
+ } else {
+ mSecondaryActionsAdapter.remove(mMultiAudioAction);
+ }
+ getHost().notifyPlaybackRowChanged();
+ }
+
+ @Nullable
+ Boolean hasSecondaryRow() {
+ if (mSecondaryActionsAdapter == null) {
+ return null;
+ }
+ return mSecondaryActionsAdapter.size() != 0;
+ }
+
+ @Override
+ public void play(int speedId) {
+ if (getCurrentSpeedId() == speedId) {
+ return;
+ }
+ if (speedId == PLAYBACK_SPEED_NORMAL) {
+ mTransportControls.play();
+ } else if (speedId <= -PLAYBACK_SPEED_FAST_L0) {
+ mTransportControls.rewind();
+ } else if (speedId >= PLAYBACK_SPEED_FAST_L0){
+ mTransportControls.fastForward();
+ }
+ }
+
+ @Override
+ public void pause() {
+ mTransportControls.pause();
+ }
+
+ /**
+ * Notifies closed caption being enabled/disabled to update related UI.
+ */
+ void onSubtitleTrackStateChanged(boolean enabled) {
+ mClosedCaptioningAction.setIndex(enabled ?
+ ClosedCaptioningAction.ON : ClosedCaptioningAction.OFF);
+ }
+
+ private void onStateChanged(int state, long positionMs, int speedLevel) {
+ if (DEBUG) Log.d(TAG, "onStateChanged");
+ getControlsRow().setCurrentTime((int) positionMs);
+ if (state == mPlaybackState && mPlaybackSpeedLevel == speedLevel) {
+ // Only position is changed, no need to update controls row
+ return;
+ }
+ // NOTICE: The below two variables should only be used in this method.
+ // The only usage of them is to confirm if the state is changed or not.
+ mPlaybackState = state;
+ mPlaybackSpeedLevel = speedLevel;
+ switch (state) {
+ case PlaybackState.STATE_PLAYING:
+ mPlaybackSpeedId = PLAYBACK_SPEED_NORMAL;
+ setFadingEnabled(true);
+ mReadyToControl = true;
+ break;
+ case PlaybackState.STATE_PAUSED:
+ mPlaybackSpeedId = PLAYBACK_SPEED_PAUSED;
+ setFadingEnabled(true);
+ mReadyToControl = true;
+ break;
+ case PlaybackState.STATE_FAST_FORWARDING:
+ mPlaybackSpeedId = PLAYBACK_SPEED_FAST_L0 + speedLevel;
+ setFadingEnabled(false);
+ mReadyToControl = true;
+ break;
+ case PlaybackState.STATE_REWINDING:
+ mPlaybackSpeedId = -PLAYBACK_SPEED_FAST_L0 - speedLevel;
+ setFadingEnabled(false);
+ mReadyToControl = true;
+ break;
+ case PlaybackState.STATE_CONNECTING:
+ setFadingEnabled(false);
+ mReadyToControl = false;
+ break;
+ case PlaybackState.STATE_NONE:
+ mReadyToControl = false;
+ break;
+ default:
+ setFadingEnabled(true);
+ break;
+ }
+ onStateChanged();
+ }
+
+ private void showSideFragment(ArrayList<TvTrackInfo> trackInfos, String selectedTrackId) {
+ Bundle args = new Bundle();
+ args.putParcelableArrayList(DvrPlaybackSideFragment.TRACK_INFOS, trackInfos);
+ args.putString(DvrPlaybackSideFragment.SELECTED_TRACK_ID, selectedTrackId);
+ DvrPlaybackSideFragment sideFragment = new DvrPlaybackSideFragment();
+ sideFragment.setArguments(args);
+ mFragment.getFragmentManager().beginTransaction()
+ .hide(mFragment)
+ .replace(R.id.dvr_playback_side_fragment, sideFragment)
+ .addToBackStack(null)
+ .commit();
+ }
+
+ private class MediaControllerCallback extends MediaController.Callback {
+ @Override
+ public void onPlaybackStateChanged(PlaybackState state) {
+ if (DEBUG) Log.d(TAG, "Playback state changed: " + state.getState());
+ onStateChanged(state.getState(), state.getPosition(), (int) state.getPlaybackSpeed());
+ }
+
+ @Override
+ public void onMetadataChanged(MediaMetadata metadata) {
+ DvrPlaybackControlHelper.this.onMetadataChanged();
+ }
+ }
+
+ private static class MultiAudioAction extends MultiAction {
+ MultiAudioAction(Context context) {
+ super(AUDIO_ACTION_ID);
+ setDrawables(new Drawable[]{context.getDrawable(R.drawable.ic_tvoption_multi_track)});
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackMediaSessionHelper.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackMediaSessionHelper.java
new file mode 100644
index 00000000..843d2dbe
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackMediaSessionHelper.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.playback;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.MediaMetadata;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.PlaybackState;
+import android.media.tv.TvContract;
+import android.os.AsyncTask;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.data.Channel;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.dvr.DvrWatchedPositionManager;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.util.ImageLoader;
+import com.android.tv.util.TimeShiftUtils;
+import com.android.tv.util.Utils;
+
+class DvrPlaybackMediaSessionHelper {
+ private static final String TAG = "DvrPlaybackMediaSessionHelper";
+ private static final boolean DEBUG = false;
+
+ private int mNowPlayingCardWidth;
+ private int mNowPlayingCardHeight;
+ private int mSpeedLevel;
+ private long mProgramDurationMs;
+
+ private Activity mActivity;
+ private DvrPlayer mDvrPlayer;
+ private MediaSession mMediaSession;
+ private final DvrWatchedPositionManager mDvrWatchedPositionManager;
+ private final ChannelDataManager mChannelDataManager;
+
+ public DvrPlaybackMediaSessionHelper(Activity activity, String mediaSessionTag,
+ DvrPlayer dvrPlayer, DvrPlaybackOverlayFragment overlayFragment) {
+ mActivity = activity;
+ mDvrPlayer = dvrPlayer;
+ mDvrWatchedPositionManager =
+ TvApplication.getSingletons(activity).getDvrWatchedPositionManager();
+ mChannelDataManager = TvApplication.getSingletons(activity).getChannelDataManager();
+ mDvrPlayer.setCallback(new DvrPlayer.DvrPlayerCallback() {
+ @Override
+ public void onPlaybackStateChanged(int playbackState, int playbackSpeed) {
+ updateMediaSessionPlaybackState();
+ }
+
+ @Override
+ public void onPlaybackPositionChanged(long positionMs) {
+ updateMediaSessionPlaybackState();
+ if (mDvrPlayer.isPlaybackPrepared()) {
+ mDvrWatchedPositionManager
+ .setWatchedPosition(mDvrPlayer.getProgram().getId(), positionMs);
+ }
+ }
+
+ @Override
+ public void onPlaybackEnded() {
+ // TODO: Deal with watched over recordings in DVR library
+ RecordedProgram nextEpisode =
+ overlayFragment.getNextEpisode(mDvrPlayer.getProgram());
+ if (nextEpisode == null) {
+ mDvrPlayer.reset();
+ mActivity.finish();
+ } else {
+ Intent intent = new Intent(activity, DvrPlaybackActivity.class);
+ intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, nextEpisode.getId());
+ mActivity.startActivity(intent);
+ }
+ }
+ });
+ initializeMediaSession(mediaSessionTag);
+ }
+
+ /**
+ * Stops DVR player and release media session.
+ */
+ public void release() {
+ if (mDvrPlayer != null) {
+ mDvrPlayer.reset();
+ }
+ if (mMediaSession != null) {
+ mMediaSession.release();
+ mMediaSession = null;
+ }
+ }
+
+ /**
+ * Updates media session's playback state and speed.
+ */
+ public void updateMediaSessionPlaybackState() {
+ mMediaSession.setPlaybackState(new PlaybackState.Builder()
+ .setState(mDvrPlayer.getPlaybackState(), mDvrPlayer.getPlaybackPosition(),
+ mSpeedLevel).build());
+ }
+
+ /**
+ * Sets the recorded program for playback.
+ *
+ * @param program The recorded program to play. {@code null} to reset the DVR player.
+ */
+ public void setupPlayback(RecordedProgram program, long seekPositionMs) {
+ if (program != null) {
+ mDvrPlayer.setProgram(program, seekPositionMs);
+ setupMediaSession(program);
+ } else {
+ mDvrPlayer.reset();
+ mMediaSession.setActive(false);
+ }
+ }
+
+ /**
+ * Returns the recorded program now playing.
+ */
+ public RecordedProgram getProgram() {
+ return mDvrPlayer.getProgram();
+ }
+
+ /**
+ * Checks if the recorded program is the same as now playing one.
+ */
+ public boolean isCurrentProgram(RecordedProgram program) {
+ return program != null && program.equals(getProgram());
+ }
+
+ /**
+ * Returns playback state.
+ */
+ public int getPlaybackState() {
+ return mDvrPlayer.getPlaybackState();
+ }
+
+ /**
+ * Returns the underlying DVR player.
+ */
+ public DvrPlayer getDvrPlayer() {
+ return mDvrPlayer;
+ }
+
+ private void initializeMediaSession(String mediaSessionTag) {
+ mMediaSession = new MediaSession(mActivity, mediaSessionTag);
+ mMediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS
+ | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
+ mNowPlayingCardWidth = mActivity.getResources()
+ .getDimensionPixelSize(R.dimen.notif_card_img_max_width);
+ mNowPlayingCardHeight = mActivity.getResources()
+ .getDimensionPixelSize(R.dimen.notif_card_img_height);
+ mMediaSession.setCallback(new MediaSessionCallback());
+ mActivity.setMediaController(
+ new MediaController(mActivity, mMediaSession.getSessionToken()));
+ updateMediaSessionPlaybackState();
+ }
+
+ private void setupMediaSession(RecordedProgram program) {
+ mProgramDurationMs = program.getDurationMillis();
+ String cardTitleText = program.getTitle();
+ if (TextUtils.isEmpty(cardTitleText)) {
+ Channel channel = mChannelDataManager.getChannel(program.getChannelId());
+ cardTitleText = (channel != null) ? channel.getDisplayName()
+ : mActivity.getString(R.string.no_program_information);
+ }
+ final MediaMetadata currentMetadata = updateMetadataTextInfo(program.getId(), cardTitleText,
+ program.getDescription(), mProgramDurationMs);
+ String posterArtUri = program.getPosterArtUri();
+ if (posterArtUri == null) {
+ posterArtUri = TvContract.buildChannelLogoUri(program.getChannelId()).toString();
+ }
+ updatePosterArt(program, currentMetadata, null, posterArtUri);
+ mMediaSession.setActive(true);
+ }
+
+ private void updatePosterArt(RecordedProgram program, MediaMetadata currentMetadata,
+ @Nullable Bitmap posterArt, @Nullable String posterArtUri) {
+ if (posterArt != null) {
+ updateMetadataImageInfo(program, currentMetadata, posterArt, 0);
+ } else if (posterArtUri != null) {
+ ImageLoader.loadBitmap(mActivity, posterArtUri, mNowPlayingCardWidth,
+ mNowPlayingCardHeight,
+ new ProgramPosterArtCallback(mActivity, program, currentMetadata));
+ } else {
+ updateMetadataImageInfo(program, currentMetadata, null, R.drawable.default_now_card);
+ }
+ }
+
+ private class ProgramPosterArtCallback extends
+ ImageLoader.ImageLoaderCallback<Activity> {
+ private final RecordedProgram mRecordedProgram;
+ private final MediaMetadata mCurrentMetadata;
+
+ public ProgramPosterArtCallback(Activity activity, RecordedProgram program,
+ MediaMetadata metadata) {
+ super(activity);
+ mRecordedProgram = program;
+ mCurrentMetadata = metadata;
+ }
+
+ @Override
+ public void onBitmapLoaded(Activity activity, @Nullable Bitmap posterArt) {
+ if (isCurrentProgram(mRecordedProgram)) {
+ updatePosterArt(mRecordedProgram, mCurrentMetadata, posterArt, null);
+ }
+ }
+ }
+
+ private MediaMetadata updateMetadataTextInfo(final long programId, final String title,
+ final String subtitle, final long duration) {
+ MediaMetadata.Builder builder = new MediaMetadata.Builder();
+ builder.putString(MediaMetadata.METADATA_KEY_MEDIA_ID, Long.toString(programId))
+ .putString(MediaMetadata.METADATA_KEY_TITLE, title)
+ .putLong(MediaMetadata.METADATA_KEY_DURATION, duration);
+ if (subtitle != null) {
+ builder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE, subtitle);
+ }
+ MediaMetadata metadata = builder.build();
+ mMediaSession.setMetadata(metadata);
+ return metadata;
+ }
+
+ private void updateMetadataImageInfo(final RecordedProgram program,
+ final MediaMetadata currentMetadata, final Bitmap posterArt, final int imageResId) {
+ if (mMediaSession != null && (posterArt != null || imageResId != 0)) {
+ MediaMetadata.Builder builder = new MediaMetadata.Builder(currentMetadata);
+ if (posterArt != null) {
+ builder.putBitmap(MediaMetadata.METADATA_KEY_ART, posterArt);
+ mMediaSession.setMetadata(builder.build());
+ } else {
+ new AsyncTask<Void, Void, Bitmap>() {
+ @Override
+ protected Bitmap doInBackground(Void... arg0) {
+ return BitmapFactory.decodeResource(mActivity.getResources(), imageResId);
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap programPosterArt) {
+ if (mMediaSession != null && programPosterArt != null
+ && isCurrentProgram(program)) {
+ builder.putBitmap(MediaMetadata.METADATA_KEY_ART, programPosterArt);
+ mMediaSession.setMetadata(builder.build());
+ }
+ }
+ }.execute();
+ }
+ }
+ }
+
+ // An event was triggered by MediaController.TransportControls and must be handled here.
+ // Here we update the media itself to act on the event that was triggered.
+ private class MediaSessionCallback extends MediaSession.Callback {
+ @Override
+ public void onPrepare() {
+ if (!mDvrPlayer.isPlaybackPrepared()) {
+ mDvrPlayer.prepare(true);
+ }
+ }
+
+ @Override
+ public void onPlay() {
+ if (mDvrPlayer.isPlaybackPrepared()) {
+ mDvrPlayer.play();
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (mDvrPlayer.isPlaybackPrepared()) {
+ mDvrPlayer.pause();
+ }
+ }
+
+ @Override
+ public void onFastForward() {
+ if (!mDvrPlayer.isPlaybackPrepared()) {
+ return;
+ }
+ if (mDvrPlayer.getPlaybackState() == PlaybackState.STATE_FAST_FORWARDING) {
+ if (mSpeedLevel < TimeShiftUtils.MAX_SPEED_LEVEL) {
+ mSpeedLevel++;
+ } else {
+ return;
+ }
+ } else {
+ mSpeedLevel = 0;
+ }
+ mDvrPlayer.fastForward(
+ TimeShiftUtils.getPlaybackSpeed(mSpeedLevel, mProgramDurationMs));
+ }
+
+ @Override
+ public void onRewind() {
+ if (!mDvrPlayer.isPlaybackPrepared()) {
+ return;
+ }
+ if (mDvrPlayer.getPlaybackState() == PlaybackState.STATE_REWINDING) {
+ if (mSpeedLevel < TimeShiftUtils.MAX_SPEED_LEVEL) {
+ mSpeedLevel++;
+ } else {
+ return;
+ }
+ } else {
+ mSpeedLevel = 0;
+ }
+ mDvrPlayer.rewind(TimeShiftUtils.getPlaybackSpeed(mSpeedLevel, mProgramDurationMs));
+ }
+
+ @Override
+ public void onSeekTo(long positionMs) {
+ if (mDvrPlayer.isPlaybackPrepared()) {
+ mDvrPlayer.seekTo(positionMs);
+ }
+ }
+ }
+}
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
new file mode 100644
index 00000000..783ae682
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackOverlayFragment.java
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.playback;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Point;
+import android.hardware.display.DisplayManager;
+import android.media.tv.TvContentRating;
+import android.media.tv.TvTrackInfo;
+import android.os.Bundle;
+import android.media.session.PlaybackState;
+import android.media.tv.TvInputManager;
+import android.media.tv.TvView;
+import android.support.v17.leanback.app.PlaybackFragment;
+import android.support.v17.leanback.app.PlaybackFragmentGlueHost;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.BaseOnItemViewClickedListener;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.SinglePresenterSelector;
+import android.view.Display;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+import android.util.Log;
+
+import com.android.tv.R;
+import com.android.tv.TvApplication;
+import com.android.tv.data.BaseProgram;
+import com.android.tv.dialog.PinDialogFragment;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.ui.SortedArrayAdapter;
+import com.android.tv.dvr.ui.browse.DvrListRowPresenter;
+import com.android.tv.dvr.ui.browse.RecordingCardView;
+import com.android.tv.parental.ContentRatingsManager;
+import com.android.tv.util.TvSettings;
+import com.android.tv.util.TvTrackInfoUtils;
+import com.android.tv.util.Utils;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public class DvrPlaybackOverlayFragment extends PlaybackFragment {
+ // TODO: Handles audio focus. Deals with block and ratings.
+ private static final String TAG = "DvrPlaybackOverlayFrag";
+ private static final boolean DEBUG = false;
+
+ private static final String MEDIA_SESSION_TAG = "com.android.tv.dvr.mediasession";
+ private static final float DISPLAY_ASPECT_RATIO_EPSILON = 0.01f;
+
+ // mProgram is only used to store program from intent. Don't use it elsewhere.
+ private RecordedProgram mProgram;
+ private DvrPlayer mDvrPlayer;
+ private DvrPlaybackMediaSessionHelper mMediaSessionHelper;
+ private DvrPlaybackControlHelper mPlaybackControlHelper;
+ private ArrayObjectAdapter mRowsAdapter;
+ private SortedArrayAdapter<BaseProgram> mRelatedRecordingsRowAdapter;
+ private DvrPlaybackCardPresenter mRelatedRecordingCardPresenter;
+ private DvrDataManager mDvrDataManager;
+ private ContentRatingsManager mContentRatingsManager;
+ private TvView mTvView;
+ private View mBlockScreenView;
+ private ListRow mRelatedRecordingsRow;
+ private int mVerticalPaddingBase;
+ private int mPaddingWithoutRelatedRow;
+ private int mPaddingWithoutSecondaryRow;
+ private int mWindowWidth;
+ private int mWindowHeight;
+ private float mAppliedAspectRatio;
+ private float mWindowAspectRatio;
+ private boolean mPinChecked;
+ private boolean mStarted;
+ private DvrPlayer.OnTrackSelectedListener mOnSubtitleTrackSelectedListener =
+ new DvrPlayer.OnTrackSelectedListener() {
+ @Override
+ public void onTrackSelected(String selectedTrackId) {
+ mPlaybackControlHelper.onSubtitleTrackStateChanged(selectedTrackId != null);
+ mRowsAdapter.notifyArrayItemRangeChanged(0, 1);
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ if (DEBUG) Log.d(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+ mVerticalPaddingBase = getActivity().getResources()
+ .getDimensionPixelOffset(R.dimen.dvr_playback_overlay_padding_top_base);
+ mPaddingWithoutRelatedRow = getActivity().getResources()
+ .getDimensionPixelOffset(R.dimen.dvr_playback_overlay_padding_top_no_related_row);
+ mPaddingWithoutSecondaryRow = getActivity().getResources()
+ .getDimensionPixelOffset(R.dimen.dvr_playback_overlay_padding_top_no_secondary_row);
+ mDvrDataManager = TvApplication.getSingletons(getActivity()).getDvrDataManager();
+ mContentRatingsManager = TvApplication.getSingletons(getContext())
+ .getTvInputManagerHelper().getContentRatingsManager();
+ if (!mDvrDataManager.isRecordedProgramLoadFinished()) {
+ mDvrDataManager.addRecordedProgramLoadFinishedListener(
+ new DvrDataManager.OnRecordedProgramLoadFinishedListener() {
+ @Override
+ public void onRecordedProgramLoadFinished() {
+ mDvrDataManager.removeRecordedProgramLoadFinishedListener(this);
+ if (handleIntent(getActivity().getIntent(), true)) {
+ setUpRows();
+ preparePlayback(getActivity().getIntent());
+ }
+ }
+ }
+ );
+ } else if (!handleIntent(getActivity().getIntent(), true)) {
+ return;
+ }
+ Point size = new Point();
+ ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE))
+ .getDisplay(Display.DEFAULT_DISPLAY).getSize(size);
+ mWindowWidth = size.x;
+ mWindowHeight = size.y;
+ mWindowAspectRatio = mAppliedAspectRatio = (float) mWindowWidth / mWindowHeight;
+ setBackgroundType(PlaybackFragment.BG_LIGHT);
+ setFadingEnabled(true);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mStarted = true;
+ updateVerticalPosition();
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ mTvView = (TvView) getActivity().findViewById(R.id.dvr_tv_view);
+ mBlockScreenView = getActivity().findViewById(R.id.block_screen);
+ mDvrPlayer = new DvrPlayer(mTvView);
+ mMediaSessionHelper = new DvrPlaybackMediaSessionHelper(
+ getActivity(), MEDIA_SESSION_TAG, mDvrPlayer, this);
+ mPlaybackControlHelper = new DvrPlaybackControlHelper(getActivity(), this);
+ mRelatedRecordingsRow = getRelatedRecordingsRow();
+ mDvrPlayer.setOnTracksAvailabilityChangedListener(
+ new DvrPlayer.OnTracksAvailabilityChangedListener() {
+ @Override
+ public void onTracksAvailabilityChanged(boolean hasClosedCaption,
+ boolean hasMultiAudio) {
+ mPlaybackControlHelper.updateSecondaryRow(hasClosedCaption, hasMultiAudio);
+ if (hasClosedCaption) {
+ mDvrPlayer.setOnTrackSelectedListener(TvTrackInfo.TYPE_SUBTITLE,
+ mOnSubtitleTrackSelectedListener);
+ selectBestMatchedTrack(TvTrackInfo.TYPE_SUBTITLE);
+ } else {
+ mDvrPlayer.setOnTrackSelectedListener(TvTrackInfo.TYPE_SUBTITLE, null);
+ }
+ if (hasMultiAudio) {
+ selectBestMatchedTrack(TvTrackInfo.TYPE_AUDIO);
+ }
+ updateVerticalPosition();
+ mPlaybackControlHelper.getHost().notifyPlaybackRowChanged();
+ }
+ });
+ mDvrPlayer.setOnAspectRatioChangedListener(new DvrPlayer.OnAspectRatioChangedListener() {
+ @Override
+ public void onAspectRatioChanged(float videoAspectRatio) {
+ updateAspectRatio(videoAspectRatio);
+ }
+ });
+ mPinChecked = getActivity().getIntent()
+ .getBooleanExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_PIN_CHECKED, false);
+ mDvrPlayer.setOnContentBlockedListener(
+ new DvrPlayer.OnContentBlockedListener() {
+ @Override
+ public void onContentBlocked(TvContentRating contentRating) {
+ if (mPinChecked) {
+ mTvView.unblockContent(contentRating);
+ return;
+ }
+ mBlockScreenView.setVisibility(View.VISIBLE);
+ getActivity().getMediaController().getTransportControls().pause();
+ ((DvrPlaybackActivity) getActivity())
+ .setOnPinCheckListener(
+ new PinDialogFragment.OnPinCheckedListener() {
+ @Override
+ public void onPinChecked(
+ boolean checked, int type, String rating) {
+ ((DvrPlaybackActivity) getActivity())
+ .setOnPinCheckListener(null);
+ if (checked) {
+ mPinChecked = true;
+ mTvView.unblockContent(contentRating);
+ mBlockScreenView.setVisibility(View.GONE);
+ getActivity()
+ .getMediaController()
+ .getTransportControls()
+ .play();
+ }
+ }
+ });
+ PinDialogFragment.create(
+ PinDialogFragment.PIN_DIALOG_TYPE_UNLOCK_DVR,
+ contentRating.flattenToString())
+ .show(
+ getActivity().getFragmentManager(),
+ PinDialogFragment.DIALOG_TAG);
+ }
+ });
+ setOnItemViewClickedListener(new BaseOnItemViewClickedListener() {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+ RowPresenter.ViewHolder rowViewHolder, Object row) {
+ if (itemViewHolder.view instanceof RecordingCardView) {
+ setFadingEnabled(false);
+ long programId = ((RecordedProgram) itemViewHolder.view.getTag()).getId();
+ if (DEBUG) Log.d(TAG, "Play Related Recording:" + programId);
+ Intent intent = new Intent(getContext(), DvrPlaybackActivity.class);
+ intent.putExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, programId);
+ getContext().startActivity(intent);
+ }
+ }
+ });
+ if (mProgram != null) {
+ setUpRows();
+ preparePlayback(getActivity().getIntent());
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (DEBUG) Log.d(TAG, "onPause");
+ super.onPause();
+ if (mMediaSessionHelper.getPlaybackState() == PlaybackState.STATE_FAST_FORWARDING
+ || mMediaSessionHelper.getPlaybackState() == PlaybackState.STATE_REWINDING) {
+ getActivity().getMediaController().getTransportControls().pause();
+ }
+ if (mMediaSessionHelper.getPlaybackState() == PlaybackState.STATE_NONE) {
+ getActivity().requestVisibleBehind(false);
+ } else {
+ getActivity().requestVisibleBehind(true);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ if (DEBUG) Log.d(TAG, "onDestroy");
+ mPlaybackControlHelper.unregisterCallback();
+ mMediaSessionHelper.release();
+ mRelatedRecordingCardPresenter.unbindAllViewHolders();
+ super.onDestroy();
+ }
+
+ /**
+ * Passes the intent to the fragment.
+ */
+ public void onNewIntent(Intent intent) {
+ if (mDvrDataManager.isRecordedProgramLoadFinished() && handleIntent(intent, false)) {
+ preparePlayback(intent);
+ }
+ }
+
+ /**
+ * Should be called when windows' size is changed in order to notify DVR player
+ * to update it's view width/height and position.
+ */
+ public void onWindowSizeChanged(final int windowWidth, final int windowHeight) {
+ mWindowWidth = windowWidth;
+ mWindowHeight = windowHeight;
+ mWindowAspectRatio = (float) mWindowWidth / mWindowHeight;
+ updateAspectRatio(mAppliedAspectRatio);
+ }
+
+ /**
+ * Returns next recorded episode in the same series as now playing program.
+ */
+ public RecordedProgram getNextEpisode(RecordedProgram program) {
+ int position = mRelatedRecordingsRowAdapter.findInsertPosition(program);
+ if (position == mRelatedRecordingsRowAdapter.size()) {
+ return null;
+ } else {
+ return (RecordedProgram) mRelatedRecordingsRowAdapter.get(position);
+ }
+ }
+
+ /**
+ * Returns the tracks of the give type of the current playback.
+
+ * @param trackType Should be {@link TvTrackInfo#TYPE_SUBTITLE}
+ * or {@link TvTrackInfo#TYPE_AUDIO}. Or returns {@code null}.
+ */
+ public ArrayList<TvTrackInfo> getTracks(int trackType) {
+ if (trackType == TvTrackInfo.TYPE_AUDIO) {
+ return mDvrPlayer.getAudioTracks();
+ } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
+ return mDvrPlayer.getSubtitleTracks();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the ID of the selected track of the given type.
+ */
+ public String getSelectedTrackId(int trackType) {
+ return mDvrPlayer.getSelectedTrackId(trackType);
+ }
+
+ /**
+ * Returns the language setting of the given track type.
+
+ * @param trackType Should be {@link TvTrackInfo#TYPE_SUBTITLE}
+ * or {@link TvTrackInfo#TYPE_AUDIO}.
+ * @return {@code null} if no language has been set for the given track type.
+ */
+ TvTrackInfo getTrackSetting(int trackType) {
+ return TvSettings.getDvrPlaybackTrackSettings(getContext(), trackType);
+ }
+
+ /**
+ * Selects the given audio or subtitle track for DVR playback.
+ * @param trackType Should be {@link TvTrackInfo#TYPE_SUBTITLE}
+ * or {@link TvTrackInfo#TYPE_AUDIO}.
+ * @param selectedTrack {@code null} to disable the audio or subtitle track according to
+ * trackType.
+ */
+ void selectTrack(int trackType, TvTrackInfo selectedTrack) {
+ if (mDvrPlayer.isPlaybackPrepared()) {
+ mDvrPlayer.selectTrack(trackType, selectedTrack);
+ }
+ }
+
+ private boolean handleIntent(Intent intent, boolean finishActivity) {
+ mProgram = getProgramFromIntent(intent);
+ if (mProgram == null) {
+ Toast.makeText(getActivity(), getString(R.string.dvr_program_not_found),
+ Toast.LENGTH_SHORT).show();
+ if (finishActivity) {
+ getActivity().finish();
+ }
+ return false;
+ }
+ return true;
+ }
+
+ private void selectBestMatchedTrack(int trackType) {
+ TvTrackInfo selectedTrack = getTrackSetting(trackType);
+ if (selectedTrack != null) {
+ TvTrackInfo bestMatchedTrack = TvTrackInfoUtils.getBestTrackInfo(getTracks(trackType),
+ selectedTrack.getId(), selectedTrack.getLanguage(),
+ trackType == TvTrackInfo.TYPE_AUDIO ? selectedTrack.getAudioChannelCount() : 0);
+ if (bestMatchedTrack != null && (trackType == TvTrackInfo.TYPE_AUDIO || Utils
+ .isEqualLanguage(bestMatchedTrack.getLanguage(),
+ selectedTrack.getLanguage()))) {
+ selectTrack(trackType, bestMatchedTrack);
+ return;
+ }
+ }
+ if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
+ // Disables closed captioning if there's no matched language.
+ selectTrack(TvTrackInfo.TYPE_SUBTITLE, null);
+ }
+ }
+
+ private void updateAspectRatio(float videoAspectRatio) {
+ if (videoAspectRatio <= 0) {
+ // We don't have video's width or height information, use window's aspect ratio.
+ videoAspectRatio = mWindowAspectRatio;
+ }
+ if (Math.abs(mAppliedAspectRatio - videoAspectRatio) < DISPLAY_ASPECT_RATIO_EPSILON) {
+ // No need to change
+ return;
+ }
+ if (Math.abs(mWindowAspectRatio - videoAspectRatio) < DISPLAY_ASPECT_RATIO_EPSILON) {
+ ((ViewGroup) mTvView.getParent()).setPadding(0, 0, 0, 0);
+ } else if (videoAspectRatio < mWindowAspectRatio) {
+ int newPadding = (mWindowWidth - Math.round(mWindowHeight * videoAspectRatio)) / 2;
+ ((ViewGroup) mTvView.getParent()).setPadding(newPadding, 0, newPadding, 0);
+ } else {
+ int newPadding = (mWindowHeight - Math.round(mWindowWidth / videoAspectRatio)) / 2;
+ ((ViewGroup) mTvView.getParent()).setPadding(0, newPadding, 0, newPadding);
+ }
+ mAppliedAspectRatio = videoAspectRatio;
+ }
+
+ private void preparePlayback(Intent intent) {
+ mMediaSessionHelper.setupPlayback(mProgram, getSeekTimeFromIntent(intent));
+ mPlaybackControlHelper.updateSecondaryRow(false, false);
+ getActivity().getMediaController().getTransportControls().prepare();
+ updateRelatedRecordingsRow();
+ }
+
+ private void updateRelatedRecordingsRow() {
+ boolean wasEmpty = (mRelatedRecordingsRowAdapter.size() == 0);
+ mRelatedRecordingsRowAdapter.clear();
+ long programId = mProgram.getId();
+ String seriesId = mProgram.getSeriesId();
+ SeriesRecording seriesRecording = mDvrDataManager.getSeriesRecording(seriesId);
+ if (seriesRecording != null) {
+ if (DEBUG) Log.d(TAG, "Update related recordings with:" + seriesId);
+ List<RecordedProgram> relatedPrograms =
+ mDvrDataManager.getRecordedPrograms(seriesRecording.getId());
+ for (RecordedProgram program : relatedPrograms) {
+ if (programId != program.getId()) {
+ mRelatedRecordingsRowAdapter.add(program);
+ }
+ }
+ }
+ if (mRelatedRecordingsRowAdapter.size() == 0) {
+ mRowsAdapter.remove(mRelatedRecordingsRow);
+ } else if (wasEmpty){
+ mRowsAdapter.add(mRelatedRecordingsRow);
+ }
+ updateVerticalPosition();
+ mRowsAdapter.notifyArrayItemRangeChanged(1, 1);
+ }
+
+ private void setUpRows() {
+ mPlaybackControlHelper.createControlsRow();
+ mPlaybackControlHelper.setHost(new PlaybackFragmentGlueHost(this));
+ mRowsAdapter = (ArrayObjectAdapter) getAdapter();
+ ClassPresenterSelector selector =
+ (ClassPresenterSelector) mRowsAdapter.getPresenterSelector();
+ selector.addClassPresenter(ListRow.class, new DvrListRowPresenter(getContext()));
+ mRowsAdapter.setPresenterSelector(selector);
+ if (mStarted) {
+ // If it's started before setting up rows, vertical position has not been updated and
+ // should be updated here.
+ updateVerticalPosition();
+ }
+ }
+
+ private ListRow getRelatedRecordingsRow() {
+ mRelatedRecordingCardPresenter = new DvrPlaybackCardPresenter(getActivity());
+ mRelatedRecordingsRowAdapter = new RelatedRecordingsAdapter(mRelatedRecordingCardPresenter);
+ HeaderItem header = new HeaderItem(0,
+ getActivity().getString(R.string.dvr_playback_related_recordings));
+ return new ListRow(header, mRelatedRecordingsRowAdapter);
+ }
+
+ private RecordedProgram getProgramFromIntent(Intent intent) {
+ long programId = intent.getLongExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, -1);
+ return mDvrDataManager.getRecordedProgram(programId);
+ }
+
+ private long getSeekTimeFromIntent(Intent intent) {
+ return intent.getLongExtra(Utils.EXTRA_KEY_RECORDED_PROGRAM_SEEK_TIME,
+ TvInputManager.TIME_SHIFT_INVALID_TIME);
+ }
+
+ private void updateVerticalPosition() {
+ Boolean hasSecondaryRow = mPlaybackControlHelper.hasSecondaryRow();
+ if (hasSecondaryRow == null) {
+ return;
+ }
+
+ int verticalPadding = mVerticalPaddingBase;
+ if (mRelatedRecordingsRowAdapter.size() == 0) {
+ verticalPadding += mPaddingWithoutRelatedRow;
+ }
+ if (!hasSecondaryRow) {
+ verticalPadding += mPaddingWithoutSecondaryRow;
+ }
+ Fragment fragment = getChildFragmentManager().findFragmentById(R.id.playback_controls_dock);
+ View view = fragment == null ? null : fragment.getView();
+ if (view != null) {
+ view.setTranslationY(verticalPadding);
+ }
+ }
+
+ private class RelatedRecordingsAdapter extends SortedArrayAdapter<BaseProgram> {
+ RelatedRecordingsAdapter(DvrPlaybackCardPresenter presenter) {
+ super(new SinglePresenterSelector(presenter), BaseProgram.EPISODE_COMPARATOR);
+ }
+
+ @Override
+ public long getId(BaseProgram item) {
+ return item.getId();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java b/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java
new file mode 100644
index 00000000..e49870f1
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlaybackSideFragment.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.playback;
+
+import android.media.tv.TvTrackInfo;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.text.TextUtils;
+import android.transition.Transition;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.tv.R;
+import com.android.tv.util.TvSettings;
+
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Fragment for DVR playback closed-caption/multi-audio settings.
+ */
+public class DvrPlaybackSideFragment extends GuidedStepFragment {
+ /**
+ * The tag for passing track infos to side fragments.
+ */
+ public static final String TRACK_INFOS = "dvr_key_track_infos";
+ /**
+ * The tag for passing selected track's ID to side fragments.
+ */
+ public static final String SELECTED_TRACK_ID = "dvr_key_selected_track_id";
+
+ private static final int ACTION_ID_NO_SUBTITLE = -1;
+ private static final int CHECK_SET_ID = 1;
+
+ private List<TvTrackInfo> mTrackInfos;
+ private String mSelectedTrackId;
+ private TvTrackInfo mSelectedTrack;
+ private int mTrackType;
+ private DvrPlaybackOverlayFragment mOverlayFragment;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ mTrackInfos = getArguments().getParcelableArrayList(TRACK_INFOS);
+ mTrackType = mTrackInfos.get(0).getType();
+ mSelectedTrackId = getArguments().getString(SELECTED_TRACK_ID);
+ mOverlayFragment = ((DvrPlaybackOverlayFragment) getFragmentManager()
+ .findFragmentById(R.id.dvr_playback_controls_fragment));
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateBackgroundView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View backgroundView = super.onCreateBackgroundView(inflater, container, savedInstanceState);
+ backgroundView.setBackgroundColor(getResources()
+ .getColor(R.color.lb_playback_controls_background_light));
+ return backgroundView;
+ }
+
+ @Override
+ public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) {
+ if (mTrackType == TvTrackInfo.TYPE_SUBTITLE) {
+ actions.add(new GuidedAction.Builder(getActivity())
+ .id(ACTION_ID_NO_SUBTITLE)
+ .title(getString(R.string.closed_caption_option_item_off))
+ .checkSetId(CHECK_SET_ID)
+ .checked(mSelectedTrackId == null)
+ .build());
+ }
+ for (int i = 0; i < mTrackInfos.size(); i++) {
+ TvTrackInfo info = mTrackInfos.get(i);
+ boolean checked = TextUtils.equals(info.getId(), mSelectedTrackId);
+ GuidedAction action = new GuidedAction.Builder(getActivity())
+ .id(i)
+ .title(getTrackLabel(info, i))
+ .checkSetId(CHECK_SET_ID)
+ .checked(checked)
+ .build();
+ actions.add(action);
+ if (checked) {
+ mSelectedTrack = info;
+ }
+ }
+ }
+
+ @Override
+ public void onGuidedActionFocused(GuidedAction action) {
+ int actionId = (int) action.getId();
+ mOverlayFragment.selectTrack(mTrackType, actionId < 0 ? null : mTrackInfos.get(actionId));
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ int actionId = (int) action.getId();
+ mSelectedTrack = actionId < 0 ? null : mTrackInfos.get(actionId);
+ TvSettings.setDvrPlaybackTrackSettings(getContext(), mTrackType, mSelectedTrack);
+ getFragmentManager().popBackStack();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ // Workaround: when overlay fragment is faded out, any focus will lost due to overlay
+ // fragment's implementation. So we disable overlay fragment's fading here to prevent
+ // losing focus while users are interacting with the side fragment.
+ mOverlayFragment.setFadingEnabled(false);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ // We disable fading of overlay fragment to prevent side fragment from losing focus,
+ // therefore we should resume it here.
+ mOverlayFragment.setFadingEnabled(true);
+ mOverlayFragment.selectTrack(mTrackType, mSelectedTrack);
+ }
+
+ private String getTrackLabel(TvTrackInfo track, int trackIndex) {
+ if (track.getLanguage() != null) {
+ return new Locale(track.getLanguage()).getDisplayName();
+ }
+ return track.getType() == TvTrackInfo.TYPE_SUBTITLE ?
+ getString(R.string.closed_caption_unknown_language, trackIndex + 1)
+ : getString(R.string.multi_audio_unknown_language);
+ }
+
+ @Override
+ protected void onProvideFragmentTransitions() {
+ super.onProvideFragmentTransitions();
+ // Excludes the background scrim from transition to prevent the blinking caused by
+ // hiding the overlay fragment and sliding in the side fragment at the same time.
+ Transition t = getEnterTransition();
+ if (t != null) {
+ t.excludeTarget(R.id.guidedstep_background, true);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/dvr/ui/playback/DvrPlayer.java b/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
new file mode 100644
index 00000000..7226c666
--- /dev/null
+++ b/src/com/android/tv/dvr/ui/playback/DvrPlayer.java
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.ui.playback;
+
+import android.media.PlaybackParams;
+import android.media.session.PlaybackState;
+import android.media.tv.TvContentRating;
+import android.media.tv.TvInputManager;
+import android.media.tv.TvTrackInfo;
+import android.media.tv.TvView;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.tv.dvr.data.RecordedProgram;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+class DvrPlayer {
+ private static final String TAG = "DvrPlayer";
+ private static final boolean DEBUG = false;
+
+ /**
+ * The max rewinding speed supported by DVR player.
+ */
+ public static final int MAX_REWIND_SPEED = 256;
+ /**
+ * The max fast-forwarding speed supported by DVR player.
+ */
+ public static final int MAX_FAST_FORWARD_SPEED = 256;
+
+ private static final long SEEK_POSITION_MARGIN_MS = TimeUnit.SECONDS.toMillis(2);
+ private static final long REWIND_POSITION_MARGIN_MS = 32; // Workaround value. b/29994826
+
+ private RecordedProgram mProgram;
+ private long mInitialSeekPositionMs;
+ private final TvView mTvView;
+ private DvrPlayerCallback mCallback;
+ private OnAspectRatioChangedListener mOnAspectRatioChangedListener;
+ private OnContentBlockedListener mOnContentBlockedListener;
+ private OnTracksAvailabilityChangedListener mOnTracksAvailabilityChangedListener;
+ private OnTrackSelectedListener mOnAudioTrackSelectedListener;
+ private OnTrackSelectedListener mOnSubtitleTrackSelectedListener;
+ private String mSelectedAudioTrackId;
+ private String mSelectedSubtitleTrackId;
+ private float mAspectRatio = Float.NaN;
+ private int mPlaybackState = PlaybackState.STATE_NONE;
+ private long mTimeShiftCurrentPositionMs;
+ private boolean mPauseOnPrepared;
+ private boolean mHasClosedCaption;
+ private boolean mHasMultiAudio;
+ private final PlaybackParams mPlaybackParams = new PlaybackParams();
+ private final DvrPlayerCallback mEmptyCallback = new DvrPlayerCallback();
+ private long mStartPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
+ private boolean mTimeShiftPlayAvailable;
+
+ public static class DvrPlayerCallback {
+ /**
+ * Called when the playback position is changed. The normal updating frequency is
+ * around 1 sec., which is restricted to the implementation of
+ * {@link android.media.tv.TvInputService}.
+ */
+ public void onPlaybackPositionChanged(long positionMs) { }
+ /**
+ * Called when the playback state or the playback speed is changed.
+ */
+ public void onPlaybackStateChanged(int playbackState, int playbackSpeed) { }
+ /**
+ * Called when the playback toward the end.
+ */
+ public void onPlaybackEnded() { }
+ }
+
+ public interface OnAspectRatioChangedListener {
+ /**
+ * Called when the Video's aspect ratio is changed.
+ *
+ * @param videoAspectRatio The aspect ratio of video. 0 stands for unknown ratios.
+ * Listeners should handle it carefully.
+ */
+ void onAspectRatioChanged(float videoAspectRatio);
+ }
+
+ public interface OnContentBlockedListener {
+ /**
+ * Called when the Video's aspect ratio is changed.
+ */
+ void onContentBlocked(TvContentRating rating);
+ }
+
+ public interface OnTracksAvailabilityChangedListener {
+ /**
+ * Called when the Video's subtitle or audio tracks are changed.
+ */
+ void onTracksAvailabilityChanged(boolean hasClosedCaption, boolean hasMultiAudio);
+ }
+
+ public interface OnTrackSelectedListener {
+ /**
+ * Called when certain subtitle or audio track is selected.
+ */
+ void onTrackSelected(String selectedTrackId);
+ }
+
+ public DvrPlayer(TvView tvView) {
+ mTvView = tvView;
+ mTvView.setCaptionEnabled(true);
+ mPlaybackParams.setSpeed(1.0f);
+ setTvViewCallbacks();
+ setCallback(null);
+ }
+
+ /**
+ * Prepares playback.
+ *
+ * @param doPlay indicates DVR player do or do not start playback after media is prepared.
+ */
+ public void prepare(boolean doPlay) throws IllegalStateException {
+ if (DEBUG) Log.d(TAG, "prepare()");
+ if (mProgram == null) {
+ throw new IllegalStateException("Recorded program not set");
+ } else if (mPlaybackState != PlaybackState.STATE_NONE) {
+ throw new IllegalStateException("Playback is already prepared");
+ }
+ mTvView.timeShiftPlay(mProgram.getInputId(), mProgram.getUri());
+ mPlaybackState = PlaybackState.STATE_CONNECTING;
+ mPauseOnPrepared = !doPlay;
+ mCallback.onPlaybackStateChanged(mPlaybackState, 1);
+ }
+
+ /**
+ * Resumes playback.
+ */
+ public void play() throws IllegalStateException {
+ if (DEBUG) Log.d(TAG, "play()");
+ if (!isPlaybackPrepared()) {
+ throw new IllegalStateException("Recorded program not set or video not ready yet");
+ }
+ switch (mPlaybackState) {
+ case PlaybackState.STATE_FAST_FORWARDING:
+ case PlaybackState.STATE_REWINDING:
+ setPlaybackSpeed(1);
+ break;
+ default:
+ mTvView.timeShiftResume();
+ }
+ mPlaybackState = PlaybackState.STATE_PLAYING;
+ mCallback.onPlaybackStateChanged(mPlaybackState, 1);
+ }
+
+ /**
+ * Pauses playback.
+ */
+ public void pause() throws IllegalStateException {
+ if (DEBUG) Log.d(TAG, "pause()");
+ if (!isPlaybackPrepared()) {
+ throw new IllegalStateException("Recorded program not set or playback not started yet");
+ }
+ switch (mPlaybackState) {
+ case PlaybackState.STATE_FAST_FORWARDING:
+ case PlaybackState.STATE_REWINDING:
+ setPlaybackSpeed(1);
+ // falls through
+ case PlaybackState.STATE_PLAYING:
+ mTvView.timeShiftPause();
+ mPlaybackState = PlaybackState.STATE_PAUSED;
+ break;
+ default:
+ break;
+ }
+ mCallback.onPlaybackStateChanged(mPlaybackState, 1);
+ }
+
+ /**
+ * Fast-forwards playback with the given speed. If the given speed is larger than
+ * {@value #MAX_FAST_FORWARD_SPEED}, uses {@value #MAX_FAST_FORWARD_SPEED}.
+ */
+ public void fastForward(int speed) throws IllegalStateException {
+ if (DEBUG) Log.d(TAG, "fastForward()");
+ if (!isPlaybackPrepared()) {
+ throw new IllegalStateException("Recorded program not set or playback not started yet");
+ }
+ if (speed <= 0) {
+ throw new IllegalArgumentException("Speed cannot be negative or 0");
+ }
+ if (mTimeShiftCurrentPositionMs >= mProgram.getDurationMillis() - SEEK_POSITION_MARGIN_MS) {
+ return;
+ }
+ speed = Math.min(speed, MAX_FAST_FORWARD_SPEED);
+ if (DEBUG) Log.d(TAG, "Let's play with speed: " + speed);
+ setPlaybackSpeed(speed);
+ mPlaybackState = PlaybackState.STATE_FAST_FORWARDING;
+ mCallback.onPlaybackStateChanged(mPlaybackState, speed);
+ }
+
+ /**
+ * Rewinds playback with the given speed. If the given speed is larger than
+ * {@value #MAX_REWIND_SPEED}, uses {@value #MAX_REWIND_SPEED}.
+ */
+ public void rewind(int speed) throws IllegalStateException {
+ if (DEBUG) Log.d(TAG, "rewind()");
+ if (!isPlaybackPrepared()) {
+ throw new IllegalStateException("Recorded program not set or playback not started yet");
+ }
+ if (speed <= 0) {
+ throw new IllegalArgumentException("Speed cannot be negative or 0");
+ }
+ if (mTimeShiftCurrentPositionMs <= REWIND_POSITION_MARGIN_MS) {
+ return;
+ }
+ speed = Math.min(speed, MAX_REWIND_SPEED);
+ if (DEBUG) Log.d(TAG, "Let's play with speed: " + speed);
+ setPlaybackSpeed(-speed);
+ mPlaybackState = PlaybackState.STATE_REWINDING;
+ mCallback.onPlaybackStateChanged(mPlaybackState, speed);
+ }
+
+ /**
+ * Seeks playback to the specified position.
+ */
+ public void seekTo(long positionMs) throws IllegalStateException {
+ if (DEBUG) Log.d(TAG, "seekTo()");
+ if (!isPlaybackPrepared()) {
+ throw new IllegalStateException("Recorded program not set or playback not started yet");
+ }
+ if (mProgram == null || mPlaybackState == PlaybackState.STATE_NONE) {
+ return;
+ }
+ positionMs = getRealSeekPosition(positionMs, SEEK_POSITION_MARGIN_MS);
+ if (DEBUG) Log.d(TAG, "Now: " + getPlaybackPosition() + ", shift to: " + positionMs);
+ mTvView.timeShiftSeekTo(positionMs + mStartPositionMs);
+ if (mPlaybackState == PlaybackState.STATE_FAST_FORWARDING ||
+ mPlaybackState == PlaybackState.STATE_REWINDING) {
+ mPlaybackState = PlaybackState.STATE_PLAYING;
+ mTvView.timeShiftResume();
+ mCallback.onPlaybackStateChanged(mPlaybackState, 1);
+ }
+ }
+
+ /**
+ * Resets playback.
+ */
+ public void reset() {
+ if (DEBUG) Log.d(TAG, "reset()");
+ mCallback.onPlaybackStateChanged(PlaybackState.STATE_NONE, 1);
+ mPlaybackState = PlaybackState.STATE_NONE;
+ mTvView.reset();
+ mTimeShiftPlayAvailable = false;
+ mStartPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
+ mTimeShiftCurrentPositionMs = 0;
+ mPlaybackParams.setSpeed(1.0f);
+ mProgram = null;
+ mSelectedAudioTrackId = null;
+ mSelectedSubtitleTrackId = null;
+ }
+
+ /**
+ * Sets callbacks for playback.
+ */
+ public void setCallback(DvrPlayerCallback callback) {
+ if (callback != null) {
+ mCallback = callback;
+ } else {
+ mCallback = mEmptyCallback;
+ }
+ }
+
+ /**
+ * Sets the listener to aspect ratio changing.
+ */
+ public void setOnAspectRatioChangedListener(OnAspectRatioChangedListener listener) {
+ mOnAspectRatioChangedListener = listener;
+ }
+
+ /**
+ * Sets the listener to content blocking.
+ */
+ public void setOnContentBlockedListener(OnContentBlockedListener listener) {
+ mOnContentBlockedListener = listener;
+ }
+
+ /**
+ * Sets the listener to tracks changing.
+ */
+ public void setOnTracksAvailabilityChangedListener(
+ OnTracksAvailabilityChangedListener listener) {
+ mOnTracksAvailabilityChangedListener = listener;
+ }
+
+ /**
+ * Sets the listener to tracks of the given type being selected.
+ *
+ * @param trackType should be either {@link TvTrackInfo#TYPE_AUDIO}
+ * or {@link TvTrackInfo#TYPE_SUBTITLE}.
+ */
+ public void setOnTrackSelectedListener(int trackType, OnTrackSelectedListener listener) {
+ if (trackType == TvTrackInfo.TYPE_AUDIO) {
+ mOnAudioTrackSelectedListener = listener;
+ } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
+ mOnSubtitleTrackSelectedListener = listener;
+ }
+ }
+
+ /**
+ * Gets the listener to tracks of the given type being selected.
+ */
+ public OnTrackSelectedListener getOnTrackSelectedListener(int trackType) {
+ if (trackType == TvTrackInfo.TYPE_AUDIO) {
+ return mOnAudioTrackSelectedListener;
+ } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
+ return mOnSubtitleTrackSelectedListener;
+ }
+ return null;
+ }
+
+ /**
+ * Sets recorded programs for playback. If the player is playing another program, stops it.
+ */
+ public void setProgram(RecordedProgram program, long initialSeekPositionMs) {
+ if (mProgram != null && mProgram.equals(program)) {
+ return;
+ }
+ if (mPlaybackState != PlaybackState.STATE_NONE) {
+ reset();
+ }
+ mInitialSeekPositionMs = initialSeekPositionMs;
+ mProgram = program;
+ }
+
+ /**
+ * Returns the recorded program now playing.
+ */
+ public RecordedProgram getProgram() {
+ return mProgram;
+ }
+
+ /**
+ * Returns the currrent playback posistion in msecs.
+ */
+ public long getPlaybackPosition() {
+ return mTimeShiftCurrentPositionMs;
+ }
+
+ /**
+ * Returns the playback speed currently used.
+ */
+ public int getPlaybackSpeed() {
+ return (int) mPlaybackParams.getSpeed();
+ }
+
+ /**
+ * Returns the playback state defined in {@link android.media.session.PlaybackState}.
+ */
+ public int getPlaybackState() {
+ return mPlaybackState;
+ }
+
+ /**
+ * Returns the subtitle tracks of the current playback.
+ */
+ public ArrayList<TvTrackInfo> getSubtitleTracks() {
+ return new ArrayList<>(mTvView.getTracks(TvTrackInfo.TYPE_SUBTITLE));
+ }
+
+ /**
+ * Returns the audio tracks of the current playback.
+ */
+ public ArrayList<TvTrackInfo> getAudioTracks() {
+ return new ArrayList<>(mTvView.getTracks(TvTrackInfo.TYPE_AUDIO));
+ }
+
+ /**
+ * Returns the ID of the selected track of the given type.
+ */
+ public String getSelectedTrackId(int trackType) {
+ if (trackType == TvTrackInfo.TYPE_AUDIO) {
+ return mSelectedAudioTrackId;
+ } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
+ return mSelectedSubtitleTrackId;
+ }
+ return null;
+ }
+
+ /**
+ * Returns if playback of the recorded program is started.
+ */
+ public boolean isPlaybackPrepared() {
+ return mPlaybackState != PlaybackState.STATE_NONE
+ && mPlaybackState != PlaybackState.STATE_CONNECTING;
+ }
+
+ /**
+ * Selects the given track.
+ *
+ * @return ID of the selected track.
+ */
+ String selectTrack(int trackType, TvTrackInfo selectedTrack) {
+ String oldSelectedTrackId = getSelectedTrackId(trackType);
+ String newSelectedTrackId = selectedTrack == null ? null : selectedTrack.getId();
+ if (!TextUtils.equals(oldSelectedTrackId, newSelectedTrackId)) {
+ if (selectedTrack == null) {
+ mTvView.selectTrack(trackType, null);
+ return null;
+ } else {
+ List<TvTrackInfo> tracks = mTvView.getTracks(trackType);
+ if (tracks != null && tracks.contains(selectedTrack)) {
+ mTvView.selectTrack(trackType, newSelectedTrackId);
+ return newSelectedTrackId;
+ } else if (trackType == TvTrackInfo.TYPE_SUBTITLE && oldSelectedTrackId != null) {
+ // Track not found, disabled closed caption.
+ mTvView.selectTrack(trackType, null);
+ return null;
+ }
+ }
+ }
+ return oldSelectedTrackId;
+ }
+
+ private void setSelectedTrackId(int trackType, String trackId) {
+ if (trackType == TvTrackInfo.TYPE_AUDIO) {
+ mSelectedAudioTrackId = trackId;
+ } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
+ mSelectedSubtitleTrackId = trackId;
+ }
+ }
+
+ private void setPlaybackSpeed(int speed) {
+ mPlaybackParams.setSpeed(speed);
+ mTvView.timeShiftSetPlaybackParams(mPlaybackParams);
+ }
+
+ private long getRealSeekPosition(long seekPositionMs, long endMarginMs) {
+ return Math.max(0, Math.min(seekPositionMs, mProgram.getDurationMillis() - endMarginMs));
+ }
+
+ private void setTvViewCallbacks() {
+ mTvView.setTimeShiftPositionCallback(new TvView.TimeShiftPositionCallback() {
+ @Override
+ public void onTimeShiftStartPositionChanged(String inputId, long timeMs) {
+ if (DEBUG) Log.d(TAG, "onTimeShiftStartPositionChanged:" + timeMs);
+ mStartPositionMs = timeMs;
+ if (mTimeShiftPlayAvailable) {
+ resumeToWatchedPositionIfNeeded();
+ }
+ }
+
+ @Override
+ public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
+ if (DEBUG) Log.d(TAG, "onTimeShiftCurrentPositionChanged: " + timeMs);
+ if (!mTimeShiftPlayAvailable) {
+ // Workaround of b/31436263
+ return;
+ }
+ // Workaround of b/32211561, TIF won't report start position when TIS report
+ // its start position as 0. In that case, we have to do the prework of playback
+ // on the first time we get current position, and the start position should be 0
+ // at that time.
+ if (mStartPositionMs == TvInputManager.TIME_SHIFT_INVALID_TIME) {
+ mStartPositionMs = 0;
+ resumeToWatchedPositionIfNeeded();
+ }
+ timeMs -= mStartPositionMs;
+ if (mPlaybackState == PlaybackState.STATE_REWINDING
+ && timeMs <= REWIND_POSITION_MARGIN_MS) {
+ play();
+ } else {
+ mTimeShiftCurrentPositionMs = getRealSeekPosition(timeMs, 0);
+ mCallback.onPlaybackPositionChanged(mTimeShiftCurrentPositionMs);
+ if (timeMs >= mProgram.getDurationMillis()) {
+ pause();
+ mCallback.onPlaybackEnded();
+ }
+ }
+ }
+ });
+ mTvView.setCallback(new TvView.TvInputCallback() {
+ @Override
+ public void onTimeShiftStatusChanged(String inputId, int status) {
+ if (DEBUG) Log.d(TAG, "onTimeShiftStatusChanged:" + status);
+ if (status == TvInputManager.TIME_SHIFT_STATUS_AVAILABLE
+ && mPlaybackState == PlaybackState.STATE_CONNECTING) {
+ mTimeShiftPlayAvailable = true;
+ if (mStartPositionMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
+ // onTimeShiftStatusChanged is sometimes called after
+ // onTimeShiftStartPositionChanged is called. In this case,
+ // resumeToWatchedPositionIfNeeded needs to be called here.
+ resumeToWatchedPositionIfNeeded();
+ }
+ }
+ }
+
+ @Override
+ public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) {
+ boolean hasClosedCaption =
+ !mTvView.getTracks(TvTrackInfo.TYPE_SUBTITLE).isEmpty();
+ boolean hasMultiAudio = mTvView.getTracks(TvTrackInfo.TYPE_AUDIO).size() > 1;
+ if ((hasClosedCaption != mHasClosedCaption || hasMultiAudio != mHasMultiAudio)
+ && mOnTracksAvailabilityChangedListener != null) {
+ mOnTracksAvailabilityChangedListener
+ .onTracksAvailabilityChanged(hasClosedCaption, hasMultiAudio);
+ }
+ mHasClosedCaption = hasClosedCaption;
+ mHasMultiAudio = hasMultiAudio;
+ }
+
+ @Override
+ public void onTrackSelected(String inputId, int type, String trackId) {
+ if (type == TvTrackInfo.TYPE_AUDIO || type == TvTrackInfo.TYPE_SUBTITLE) {
+ setSelectedTrackId(type, trackId);
+ OnTrackSelectedListener listener = getOnTrackSelectedListener(type);
+ if (listener != null) {
+ listener.onTrackSelected(trackId);
+ }
+ } else if (type == TvTrackInfo.TYPE_VIDEO && trackId != null
+ && mOnAspectRatioChangedListener != null) {
+ List<TvTrackInfo> trackInfos = mTvView.getTracks(TvTrackInfo.TYPE_VIDEO);
+ if (trackInfos != null) {
+ for (TvTrackInfo trackInfo : trackInfos) {
+ if (trackInfo.getId().equals(trackId)) {
+ float videoAspectRatio;
+ int videoWidth = trackInfo.getVideoWidth();
+ int videoHeight = trackInfo.getVideoHeight();
+ if (videoWidth > 0 && videoHeight > 0) {
+ videoAspectRatio = trackInfo.getVideoPixelAspectRatio()
+ * trackInfo.getVideoWidth() / trackInfo.getVideoHeight();
+ } else {
+ // Aspect ratio is unknown. Pass the message to listeners.
+ videoAspectRatio = 0;
+ }
+ if (DEBUG) Log.d(TAG, "Aspect Ratio: " + videoAspectRatio);
+ if (mAspectRatio != videoAspectRatio || videoAspectRatio == 0) {
+ mOnAspectRatioChangedListener
+ .onAspectRatioChanged(videoAspectRatio);
+ mAspectRatio = videoAspectRatio;
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onContentBlocked(String inputId, TvContentRating rating) {
+ if (mOnContentBlockedListener != null) {
+ mOnContentBlockedListener.onContentBlocked(rating);
+ }
+ }
+ });
+ }
+
+ private void resumeToWatchedPositionIfNeeded() {
+ if (mInitialSeekPositionMs != TvInputManager.TIME_SHIFT_INVALID_TIME) {
+ mTvView.timeShiftSeekTo(getRealSeekPosition(mInitialSeekPositionMs,
+ SEEK_POSITION_MARGIN_MS) + mStartPositionMs);
+ mInitialSeekPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
+ }
+ if (mPauseOnPrepared) {
+ mTvView.timeShiftPause();
+ mPlaybackState = PlaybackState.STATE_PAUSED;
+ mPauseOnPrepared = false;
+ } else {
+ mTvView.timeShiftResume();
+ mPlaybackState = PlaybackState.STATE_PLAYING;
+ }
+ mCallback.onPlaybackStateChanged(mPlaybackState, 1);
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/experiments/ExperimentFlag.java b/src/com/android/tv/experiments/ExperimentFlag.java
index 8f60c2b5..c0cbd643 100644
--- a/src/com/android/tv/experiments/ExperimentFlag.java
+++ b/src/com/android/tv/experiments/ExperimentFlag.java
@@ -16,12 +16,19 @@
package com.android.tv.experiments;
+import android.support.annotation.VisibleForTesting;
/**
* Experiments return values based on user, device and other criteria.
*/
public final class ExperimentFlag<T> {
- private final T mDefaultValue;
+
+ private static boolean sAllowOverrides = false;
+
+ @VisibleForTesting
+ public static void initForTest() {
+ sAllowOverrides = true;
+ }
/** Returns a boolean experiment */
public static ExperimentFlag<Boolean> createFlag(
@@ -30,6 +37,11 @@ public final class ExperimentFlag<T> {
defaultValue);
}
+ private final T mDefaultValue;
+
+ private T mOverrideValue = null;
+ private boolean mOverridden = false;
+
private ExperimentFlag(
T defaultValue) {
mDefaultValue = defaultValue;
@@ -37,6 +49,22 @@ public final class ExperimentFlag<T> {
/** Returns value for this experiment */
public T get() {
- return mDefaultValue;
+ return sAllowOverrides && mOverridden ? mOverrideValue : mDefaultValue;
}
+
+ @VisibleForTesting
+ public void override(T t) {
+ if (sAllowOverrides) {
+ mOverridden = true;
+ mOverrideValue = t;
+ }
+ }
+
+ @VisibleForTesting
+ public void resetOverride() {
+ mOverridden = false;
+ }
+
+
+
}
diff --git a/src/com/android/tv/experiments/Experiments.java b/src/com/android/tv/experiments/Experiments.java
index f16c8d1e..53cce979 100644
--- a/src/com/android/tv/experiments/Experiments.java
+++ b/src/com/android/tv/experiments/Experiments.java
@@ -23,12 +23,15 @@ import com.android.tv.common.BuildConfig;
/**
* Set of experiments visible in AOSP.
*
- * <p>
- * This file is maintained by hand.
+ * <p>This file is maintained by hand.
*/
public final class Experiments {
public static final ExperimentFlag<Boolean> CLOUD_EPG = createFlag(
- false);
+ true);
+
+ public static final ExperimentFlag<Boolean> ENABLE_UNRATED_CONTENT_SETTINGS =
+ createFlag(
+ false);
/**
* Allow developer features such as the dev menu and other aids.
diff --git a/src/com/android/tv/guide/GenreListAdapter.java b/src/com/android/tv/guide/GenreListAdapter.java
index 2913599c..ce19eb2d 100644
--- a/src/com/android/tv/guide/GenreListAdapter.java
+++ b/src/com/android/tv/guide/GenreListAdapter.java
@@ -17,6 +17,7 @@
package com.android.tv.guide;
import android.content.Context;
+import android.support.annotation.MainThread;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
@@ -32,7 +33,7 @@ import java.util.List;
/**
* Adapts the genre items obtained from {@link GenreItems} to the program guide side panel.
*/
-public class GenreListAdapter extends RecyclerView.Adapter<GenreListAdapter.GenreRowHolder> {
+class GenreListAdapter extends RecyclerView.Adapter<GenreListAdapter.GenreRowHolder> {
private static final String TAG = "GenreListAdapter";
private static final boolean DEBUG = false;
@@ -41,7 +42,7 @@ public class GenreListAdapter extends RecyclerView.Adapter<GenreListAdapter.Genr
private final ProgramGuide mProgramGuide;
private String[] mGenreLabels;
- public GenreListAdapter(Context context, ProgramManager programManager, ProgramGuide guide) {
+ GenreListAdapter(Context context, ProgramManager programManager, ProgramGuide guide) {
mContext = context;
mProgramManager = programManager;
mProgramManager.addListener(new ProgramManager.ListenerAdapter() {
@@ -79,16 +80,28 @@ public class GenreListAdapter extends RecyclerView.Adapter<GenreListAdapter.Genr
@Override
public GenreRowHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
+ itemView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View view) {
+ // Animation is not meaningful now, skip it.
+ view.getStateListAnimator().jumpToCurrentState();
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View view) {
+ // Do nothing
+ }
+ });
return new GenreRowHolder(itemView, mProgramGuide);
}
- public static class GenreRowHolder extends RecyclerView.ViewHolder implements
+ static class GenreRowHolder extends RecyclerView.ViewHolder implements
View.OnFocusChangeListener {
private final ProgramGuide mProgramGuide;
private int mGenreId;
- // Should be called from main thread.
- public GenreRowHolder(View itemView, ProgramGuide programGuide) {
+ @MainThread
+ GenreRowHolder(View itemView, ProgramGuide programGuide) {
super(itemView);
mProgramGuide = programGuide;
}
diff --git a/src/com/android/tv/guide/GuideUtils.java b/src/com/android/tv/guide/GuideUtils.java
index 5d11f061..403d00b5 100644
--- a/src/com/android/tv/guide/GuideUtils.java
+++ b/src/com/android/tv/guide/GuideUtils.java
@@ -16,30 +16,38 @@
package com.android.tv.guide;
+import android.graphics.Rect;
+import android.support.annotation.NonNull;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+
+import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
-public class GuideUtils {
+class GuideUtils {
+ private static final int INVALID_INDEX = -1;
private static int sWidthPerHour = 0;
/**
* Sets the width in pixels that corresponds to an hour in program guide.
* Assume that this is called from main thread only, so, no synchronization.
*/
- public static void setWidthPerHour(int widthPerHour) {
+ static void setWidthPerHour(int widthPerHour) {
sWidthPerHour = widthPerHour;
}
/**
* Gets the number of pixels in program guide table that corresponds to the given milliseconds.
*/
- public static int convertMillisToPixel(long millis) {
+ static int convertMillisToPixel(long millis) {
return (int) (millis * sWidthPerHour / TimeUnit.HOURS.toMillis(1));
}
/**
* Gets the number of pixels in program guide table that corresponds to the given range.
*/
- public static int convertMillisToPixel(long startMillis, long endMillis) {
+ static int convertMillisToPixel(long startMillis, long endMillis) {
// Convert to pixels first to avoid accumulation of rounding errors.
return GuideUtils.convertMillisToPixel(endMillis)
- GuideUtils.convertMillisToPixel(startMillis);
@@ -48,9 +56,101 @@ public class GuideUtils {
/**
* Gets the time in millis that corresponds to the given pixels in the program guide.
*/
- public static long convertPixelToMillis(int pixel) {
+ static long convertPixelToMillis(int pixel) {
return pixel * TimeUnit.HOURS.toMillis(1) / sWidthPerHour;
}
+ /**
+ * Return the view should be focused in the given program row according to the focus range.
+
+ * @param keepCurrentProgramFocused If {@code true}, focuses on the current program if possible,
+ * else falls back the general logic.
+ */
+ static View findNextFocusedProgram(View programRow, int focusRangeLeft,
+ int focusRangeRight, boolean keepCurrentProgramFocused) {
+ ArrayList<View> focusables = new ArrayList<>();
+ findFocusables(programRow, focusables);
+
+ if (keepCurrentProgramFocused) {
+ // Select the current program if possible.
+ for (int i = 0; i < focusables.size(); ++i) {
+ View focusable = focusables.get(i);
+ if (focusable instanceof ProgramItemView
+ && isCurrentProgram((ProgramItemView) focusable)) {
+ return focusable;
+ }
+ }
+ }
+
+ // Find the largest focusable among fully overlapped focusables.
+ int maxFullyOverlappedWidth = Integer.MIN_VALUE;
+ int maxPartiallyOverlappedWidth = Integer.MIN_VALUE;
+ int nextFocusIndex = INVALID_INDEX;
+ for (int i = 0; i < focusables.size(); ++i) {
+ View focusable = focusables.get(i);
+ Rect focusableRect = new Rect();
+ focusable.getGlobalVisibleRect(focusableRect);
+ if (focusableRect.left <= focusRangeLeft && focusRangeRight <= focusableRect.right) {
+ // the old focused range is fully inside the focusable, return directly.
+ return focusable;
+ } else if (focusRangeLeft <= focusableRect.left
+ && focusableRect.right <= focusRangeRight) {
+ // the focusable is fully inside the old focused range, choose the widest one.
+ int width = focusableRect.width();
+ if (width > maxFullyOverlappedWidth) {
+ nextFocusIndex = i;
+ maxFullyOverlappedWidth = width;
+ }
+ } else if (maxFullyOverlappedWidth == Integer.MIN_VALUE) {
+ int overlappedWidth = (focusRangeLeft <= focusableRect.left) ?
+ focusRangeRight - focusableRect.left
+ : focusableRect.right - focusRangeLeft;
+ if (overlappedWidth > maxPartiallyOverlappedWidth) {
+ nextFocusIndex = i;
+ maxPartiallyOverlappedWidth = overlappedWidth;
+ }
+ }
+ }
+ if (nextFocusIndex != INVALID_INDEX) {
+ return focusables.get(nextFocusIndex);
+ }
+ return null;
+ }
+
+ /**
+ * Returns {@code true} if the program displayed in the give
+ * {@link com.android.tv.guide.ProgramItemView} is a current program.
+ */
+ static boolean isCurrentProgram(ProgramItemView view) {
+ return view.getTableEntry().isCurrentProgram();
+ }
+
+ /**
+ * Returns {@code true} if the given view is a descendant of the give container.
+ */
+ static boolean isDescendant(ViewGroup container, View view) {
+ if (view == null) {
+ return false;
+ }
+ for (ViewParent p = view.getParent(); p != null; p = p.getParent()) {
+ if (p == container) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static void findFocusables(View v, ArrayList<View> outFocusable) {
+ if (v.isFocusable()) {
+ outFocusable.add(v);
+ }
+ if (v instanceof ViewGroup) {
+ ViewGroup viewGroup = (ViewGroup) v;
+ for (int i = 0; i < viewGroup.getChildCount(); ++i) {
+ findFocusables(viewGroup.getChildAt(i), outFocusable);
+ }
+ }
+ }
+
private GuideUtils() { }
}
diff --git a/src/com/android/tv/guide/ProgramGrid.java b/src/com/android/tv/guide/ProgramGrid.java
index 77de5827..58436425 100644
--- a/src/com/android/tv/guide/ProgramGrid.java
+++ b/src/com/android/tv/guide/ProgramGrid.java
@@ -20,17 +20,15 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.support.v17.leanback.widget.VerticalGridView;
-import android.support.v7.widget.RecyclerView.LayoutManager;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.Range;
import android.view.View;
-import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import com.android.tv.R;
import com.android.tv.ui.OnRepeatedKeyInterceptListener;
-import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
/**
@@ -52,7 +50,7 @@ public class ProgramGrid extends VerticalGridView {
clearUpDownFocusState(newFocus);
}
mNextFocusByUpDown = null;
- if (newFocus != ProgramGrid.this && contains(newFocus)) {
+ if (GuideUtils.isDescendant(ProgramGrid.this, newFocus)) {
mLastFocusedView = newFocus;
}
}
@@ -90,8 +88,9 @@ public class ProgramGrid extends VerticalGridView {
private View mLastFocusedView;
private final Rect mTempRect = new Rect();
+ private int mLastUpDownDirection;
- private boolean mKeepCurrentProgram;
+ private boolean mKeepCurrentProgramFocused;
private ChildFocusListener mChildFocusListener;
private final OnRepeatedKeyInterceptListener mOnRepeatedKeyInterceptListener;
@@ -132,21 +131,6 @@ public class ProgramGrid extends VerticalGridView {
setOnKeyInterceptListener(mOnRepeatedKeyInterceptListener);
}
- /**
- * Initializes ProgramGrid. It should be called before the view is actually attached to
- * Window.
- */
- public void initialize(ProgramManager programManager) {
- mProgramManager = programManager;
- }
-
- /**
- * Registers a listener focus events occurring on children to the {@code ProgramGrid}.
- */
- public void setChildFocusListener(ChildFocusListener childFocusListener) {
- mChildFocusListener = childFocusListener;
- }
-
@Override
public void requestChildFocus(View child, View focused) {
if (mChildFocusListener != null) {
@@ -173,11 +157,11 @@ public class ProgramGrid extends VerticalGridView {
@Override
public View focusSearch(View focused, int direction) {
mNextFocusByUpDown = null;
- if (focused == null || !contains(focused)) {
+ if (focused == null || (focused != this && !GuideUtils.isDescendant(this, focused))) {
return super.focusSearch(focused, direction);
}
if (direction == View.FOCUS_UP || direction == View.FOCUS_DOWN) {
- updateUpDownFocusState(focused);
+ updateUpDownFocusState(focused, direction);
View nextFocus = focusFind(focused, direction);
if (nextFocus != null) {
return nextFocus;
@@ -186,15 +170,85 @@ public class ProgramGrid extends VerticalGridView {
return super.focusSearch(focused, direction);
}
+ @Override
+ public boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+ if (mLastFocusedView != null && mLastFocusedView.isShown()) {
+ if (mLastFocusedView.requestFocus()) {
+ return true;
+ }
+ }
+ return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
+ }
+
+ @Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ // It is required to properly handle OnRepeatedKeyInterceptListener. If the focused
+ // item's are at the almost end of screen, focus change to the next item doesn't work.
+ // It restricts that a focus item's position cannot be too far from the desired position.
+ View focusedView = findFocus();
+ if (focusedView != null && mOnRepeatedKeyInterceptListener.isFocusAccelerated()) {
+ int[] location = new int[2];
+ getLocationOnScreen(location);
+ int[] focusedLocation = new int[2];
+ focusedView.getLocationOnScreen(focusedLocation);
+ int y = focusedLocation[1] - location[1];
+ int minY = (mSelectionRow - 1) * mRowHeight;
+ if (y < minY) scrollBy(0, y - minY);
+ int maxY = (mSelectionRow + 1) * mRowHeight + mDetailHeight;
+ if (y > maxY) scrollBy(0, y - maxY);
+ }
+ updateInputLogo();
+ }
+
+ @Override
+ public void onViewRemoved(View view) {
+ // It is required to ensure input logo showing when the scroll is moved to most bottom.
+ updateInputLogo();
+ }
+
+ /**
+ * Initializes ProgramGrid. It should be called before the view is actually attached to
+ * Window.
+ */
+ void initialize(ProgramManager programManager) {
+ mProgramManager = programManager;
+ }
+
+ /**
+ * Registers a listener focus events occurring on children to the {@code ProgramGrid}.
+ */
+ void setChildFocusListener(ChildFocusListener childFocusListener) {
+ mChildFocusListener = childFocusListener;
+ }
+
+ void onItemSelectionReset() {
+ getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
+ }
+
/**
* Resets focus states. If the logic to keep the last focus needs to be cleared, it should
* be called.
*/
- public void resetFocusState() {
+ void resetFocusState() {
mLastFocusedView = null;
clearUpDownFocusState(null);
}
+ /** Returns the currently focused item's horizontal range. */
+ Range<Integer> getFocusRange() {
+ return new Range<>(mFocusRangeLeft, mFocusRangeRight);
+ }
+
+ /** Returns if the next focused item should be the current program if possible. */
+ boolean isKeepCurrentProgramFocused() {
+ return mKeepCurrentProgramFocused;
+ }
+
+ /** Returns the last up/down move direction of browsing */
+ int getLastUpDownDirection() {
+ return mLastUpDownDirection;
+ }
+
private View focusFind(View focused, int direction) {
int focusedChildIndex = getFocusedChildIndex();
if (focusedChildIndex == INVALID_INDEX) {
@@ -204,85 +258,26 @@ public class ProgramGrid extends VerticalGridView {
int nextChildIndex = direction == View.FOCUS_UP ? focusedChildIndex - 1
: focusedChildIndex + 1;
if (nextChildIndex < 0 || nextChildIndex >= getChildCount()) {
- return focused;
- }
- View nextChild = getChildAt(nextChildIndex);
- ArrayList<View> focusables = new ArrayList<>();
- findFocusables(nextChild, focusables);
-
- int index = INVALID_INDEX;
- if (mKeepCurrentProgram) {
- // Select the current program if possible.
- for (int i = 0; i < focusables.size(); ++i) {
- View focusable = focusables.get(i);
- if (!(focusable instanceof ProgramItemView)) {
- continue;
- }
- if (((ProgramItemView) focusable).getTableEntry().isCurrentProgram()) {
- index = i;
- break;
- }
- }
- if (index != INVALID_INDEX) {
- mNextFocusByUpDown = focusables.get(index);
- return mNextFocusByUpDown;
- } else {
- mKeepCurrentProgram = false;
- }
- }
-
- // Find the largest focusable among fully overlapped focusables.
- int maxWidth = Integer.MIN_VALUE;
- for (int i = 0; i < focusables.size(); ++i) {
- View focusable = focusables.get(i);
- Rect focusableRect = mTempRect;
- focusable.getGlobalVisibleRect(focusableRect);
- if (mFocusRangeLeft <= focusableRect.left && focusableRect.right <= mFocusRangeRight) {
- int width = focusableRect.width();
- if (width > maxWidth) {
- index = i;
- maxWidth = width;
- }
- } else if (focusableRect.left <= mFocusRangeLeft
- && mFocusRangeRight <= focusableRect.right) {
- // focusableRect contains [mLeft, mRight].
- index = i;
- break;
- }
- }
- if (index != INVALID_INDEX) {
- mNextFocusByUpDown = focusables.get(index);
- return mNextFocusByUpDown;
- }
-
- // Find the largest overlapped view among partially overlapped focusables.
- maxWidth = Integer.MIN_VALUE;
- for (int i = 0; i < focusables.size(); ++i) {
- View focusable = focusables.get(i);
- Rect focusableRect = mTempRect;
- focusable.getGlobalVisibleRect(focusableRect);
- if (mFocusRangeLeft <= focusableRect.left && focusableRect.left <= mFocusRangeRight) {
- int overlappedWidth = mFocusRangeRight - focusableRect.left;
- if (overlappedWidth > maxWidth) {
- index = i;
- maxWidth = overlappedWidth;
- }
- } else if (mFocusRangeLeft <= focusableRect.right
- && focusableRect.right <= mFocusRangeRight) {
- int overlappedWidth = focusableRect.right - mFocusRangeLeft;
- if (overlappedWidth > maxWidth) {
- index = i;
- maxWidth = overlappedWidth;
- }
+ // Wraparound if reached head or end
+ if (getSelectedPosition() == 0) {
+ scrollToPosition(getAdapter().getItemCount() - 1);
+ return null;
+ } else if (getSelectedPosition() == getAdapter().getItemCount() - 1) {
+ scrollToPosition(0);
+ return null;
}
+ return focused;
}
- if (index != INVALID_INDEX) {
- mNextFocusByUpDown = focusables.get(index);
- return mNextFocusByUpDown;
+ View nextFocusedProgram = GuideUtils.findNextFocusedProgram(getChildAt(nextChildIndex),
+ mFocusRangeLeft, mFocusRangeRight, mKeepCurrentProgramFocused);
+ if (nextFocusedProgram != null) {
+ nextFocusedProgram.getGlobalVisibleRect(mTempRect);
+ mNextFocusByUpDown = nextFocusedProgram;
+
+ } else {
+ Log.w(TAG, "focusFind doesn't find proper focusable");
}
-
- Log.w(TAG, "focusFind doesn't find proper focusable");
- return null;
+ return nextFocusedProgram;
}
// Returned value is not the position of VerticalGridView. But it's the index of ViewGroup
@@ -296,7 +291,8 @@ public class ProgramGrid extends VerticalGridView {
return INVALID_INDEX;
}
- private void updateUpDownFocusState(View focused) {
+ private void updateUpDownFocusState(View focused, int direction) {
+ mLastUpDownDirection = direction;
int rightMostFocusablePosition = getRightMostFocusablePosition();
Rect focusedRect = mTempRect;
@@ -319,11 +315,13 @@ public class ProgramGrid extends VerticalGridView {
}
private void clearUpDownFocusState(View focus) {
+ mLastUpDownDirection = 0;
mFocusRangeLeft = 0;
mFocusRangeRight = getRightMostFocusablePosition();
mNextFocusByUpDown = null;
- mKeepCurrentProgram = focus != null && focus instanceof ProgramItemView
- && ((ProgramItemView) focus).getTableEntry().isCurrentProgram();
+ // If focus is not a program item, drop focus to the current program when back to the grid
+ mKeepCurrentProgramFocused = !(focus instanceof ProgramItemView)
+ || GuideUtils.isCurrentProgram((ProgramItemView) focus);
}
private int getRightMostFocusablePosition() {
@@ -333,56 +331,6 @@ public class ProgramGrid extends VerticalGridView {
return mTempRect.right - GuideUtils.convertMillisToPixel(FOCUS_AREA_RIGHT_MARGIN_MILLIS);
}
- private boolean contains(View v) {
- if (v == this) {
- return true;
- }
- if (v == null || v == v.getRootView()) {
- return false;
- }
- return contains((View) v.getParent());
- }
-
- public void onItemSelectionReset() {
- getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
- }
-
- @Override
- public boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
- if (mLastFocusedView != null && mLastFocusedView.isShown()) {
- if (mLastFocusedView.requestFocus()) {
- return true;
- }
- }
- return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
- }
-
- @Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- // It is required to properly handle OnRepeatedKeyInterceptListener. If the focused
- // item's are at the almost end of screen, focus change to the next item doesn't work.
- // It restricts that a focus item's position cannot be too far from the desired position.
- View focusedView = findFocus();
- if (focusedView != null && mOnRepeatedKeyInterceptListener.isFocusAccelerated()) {
- int[] location = new int[2];
- getLocationOnScreen(location);
- int[] focusedLocation = new int[2];
- focusedView.getLocationOnScreen(focusedLocation);
- int y = focusedLocation[1] - location[1];
- int minY = (mSelectionRow - 1) * mRowHeight;
- if (y < minY) scrollBy(0, y - minY);
- int maxY = (mSelectionRow + 1) * mRowHeight + mDetailHeight;
- if (y > maxY) scrollBy(0, y - maxY);
- }
- updateInputLogo();
- }
-
- @Override
- public void onViewRemoved(View view) {
- // It is required to ensure input logo showing when the scroll is moved to most bottom.
- updateInputLogo();
- }
-
private int getFirstVisibleChildIndex() {
final LayoutManager mLayoutManager = getLayoutManager();
int top = mLayoutManager.getPaddingTop();
@@ -398,7 +346,7 @@ public class ProgramGrid extends VerticalGridView {
return -1;
}
- public void updateInputLogo() {
+ private void updateInputLogo() {
int childCount = getChildCount();
if (childCount == 0) {
return;
@@ -409,25 +357,13 @@ public class ProgramGrid extends VerticalGridView {
}
View childView = getChildAt(firstVisibleChildIndex);
int childAdapterPosition = getChildAdapterPosition(childView);
- ((ProgramTableAdapter.ProgramRowHolder) getChildViewHolder(childView))
+ ((ProgramTableAdapter.ProgramRowViewHolder) getChildViewHolder(childView))
.updateInputLogo(childAdapterPosition, true);
for (int i = firstVisibleChildIndex + 1; i < childCount; i++) {
childView = getChildAt(i);
- ((ProgramTableAdapter.ProgramRowHolder) getChildViewHolder(childView))
+ ((ProgramTableAdapter.ProgramRowViewHolder) getChildViewHolder(childView))
.updateInputLogo(childAdapterPosition, false);
childAdapterPosition = getChildAdapterPosition(childView);
}
}
-
- private static void findFocusables(View v, ArrayList<View> outFocusable) {
- if (v.isFocusable()) {
- outFocusable.add(v);
- }
- if (v instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) v;
- for (int i = 0; i < viewGroup.getChildCount(); ++i) {
- findFocusables(viewGroup.getChildAt(i), outFocusable);
- }
- }
- }
}
diff --git a/src/com/android/tv/guide/ProgramGuide.java b/src/com/android/tv/guide/ProgramGuide.java
index 120b3dba..dd5444e2 100644
--- a/src/com/android/tv/guide/ProgramGuide.java
+++ b/src/com/android/tv/guide/ProgramGuide.java
@@ -48,7 +48,7 @@ import com.android.tv.ChannelTuner;
import com.android.tv.Features;
import com.android.tv.MainActivity;
import com.android.tv.R;
-import com.android.tv.analytics.DurationTimer;
+import com.android.tv.util.DurationTimer;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.WeakHandler;
import com.android.tv.data.ChannelDataManager;
@@ -143,6 +143,7 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
private int mLastRequestedGenreId = GenreItems.ID_ALL_CHANNELS;
private boolean mIsDuringResetRowSelection;
private final Handler mHandler = new ProgramGuideHandler(this);
+ private boolean mActive;
private final Runnable mHideRunnable = new Runnable() {
@Override
@@ -217,7 +218,7 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
.getDimensionPixelOffset(R.dimen.program_guide_side_panel_alignment_y));
mSidePanelGridView.setWindowAlignmentOffsetPercent(
VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
- // TODO: Remove this check when we ship TV with epg search enabled.
+
if (Features.EPG_SEARCH.isEnabled(mActivity)) {
mSearchOrb = (SearchOrbView) mContainer.findViewById(
R.id.program_guide_side_panel_search_orb);
@@ -250,8 +251,7 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
res.getInteger(R.integer.max_recycled_view_pool_epg_header_row_item));
mTimelineRow.setAdapter(mTimeListAdapter);
- ProgramTableAdapter programTableAdapter = new ProgramTableAdapter(mActivity,
- mProgramManager, this);
+ ProgramTableAdapter programTableAdapter = new ProgramTableAdapter(mActivity, this);
programTableAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
@@ -304,13 +304,6 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
R.animator.program_guide_side_panel_enter_full,
0,
R.animator.program_guide_table_enter_full);
- mShowAnimatorFull.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- ((ViewGroup) mSidePanel).setDescendantFocusability(
- ViewGroup.FOCUS_AFTER_DESCENDANTS);
- }
- });
mShowAnimatorPartial = createAnimator(
R.animator.program_guide_side_panel_enter_partial,
@@ -383,34 +376,6 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
|| mSharedPreference.getBoolean(KEY_SHOW_GUIDE_PARTIAL, true);
}
- private void updateGuidePosition() {
- // Align EPG at vertical center, if EPG table height is less than the screen size.
- Resources res = mActivity.getResources();
- int screenHeight = mContainer.getHeight();
- if (screenHeight <= 0) {
- // mContainer is not initialized yet.
- return;
- }
- int startPadding = res.getDimensionPixelOffset(R.dimen.program_guide_table_margin_start);
- int topPadding = res.getDimensionPixelOffset(R.dimen.program_guide_table_margin_top);
- int bottomPadding = res.getDimensionPixelOffset(R.dimen.program_guide_table_margin_bottom);
- int tableHeight = res.getDimensionPixelOffset(R.dimen.program_guide_table_header_row_height)
- + mDetailHeight + mRowHeight * mGrid.getAdapter().getItemCount() + topPadding
- + bottomPadding;
- if (tableHeight > screenHeight) {
- // EPG height is longer that the screen height.
- mTable.setPaddingRelative(startPadding, topPadding, 0, 0);
- LayoutParams layoutParams = mTable.getLayoutParams();
- layoutParams.height = LayoutParams.WRAP_CONTENT;
- mTable.setLayoutParams(layoutParams);
- } else {
- mTable.setPaddingRelative(startPadding, topPadding, 0, bottomPadding);
- LayoutParams layoutParams = mTable.getLayoutParams();
- layoutParams.height = tableHeight;
- mTable.setLayoutParams(layoutParams);
- }
- }
-
@Override
public void onRequestChildFocus(View oldFocus, View newFocus) {
if (oldFocus != null && newFocus != null) {
@@ -431,40 +396,6 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
}
}
- private Animator createAnimator(int sidePanelAnimResId, int sidePanelGridAnimResId,
- int tableAnimResId) {
- List<Animator> animatorList = new ArrayList<>();
-
- Animator sidePanelAnimator = AnimatorInflater.loadAnimator(mActivity, sidePanelAnimResId);
- sidePanelAnimator.setTarget(mSidePanel);
- animatorList.add(sidePanelAnimator);
-
- if (sidePanelGridAnimResId != 0) {
- Animator sidePanelGridAnimator = AnimatorInflater.loadAnimator(mActivity,
- sidePanelGridAnimResId);
- sidePanelGridAnimator.setTarget(mSidePanelGridView);
- sidePanelGridAnimator.addListener(
- new HardwareLayerAnimatorListenerAdapter(mSidePanelGridView));
- animatorList.add(sidePanelGridAnimator);
- }
- Animator tableAnimator = AnimatorInflater.loadAnimator(mActivity, tableAnimResId);
- tableAnimator.setTarget(mTable);
- tableAnimator.addListener(new HardwareLayerAnimatorListenerAdapter(mTable));
- animatorList.add(tableAnimator);
-
- AnimatorSet set = new AnimatorSet();
- set.playTogether(animatorList);
- return set;
- }
-
- /**
- * Returns {@code true} if the program guide should process the input events.
- */
- public boolean isActive() {
- return mContainer.getVisibility() == View.VISIBLE && !mHideAnimatorFull.isStarted()
- && !mHideAnimatorPartial.isStarted();
- }
-
/**
* Show the program guide. This reveals the side panel, and the program guide table is shown
* partially.
@@ -494,14 +425,11 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
mTimeListAdapter.update(mStartUtcTime);
mTimelineRow.resetScroll();
+ mContainer.setVisibility(View.VISIBLE);
+ mActive = true;
if (!mShowGuidePartial) {
- // Avoid changing focus from the genre side panel to the grid during animation.
- // The descendant focus is changed to FOCUS_AFTER_DESCENDANTS after the animation.
- ((ViewGroup) mSidePanel).setDescendantFocusability(
- ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+ mTable.requestFocus();
}
-
- mContainer.setVisibility(View.VISIBLE);
positionCurrentTimeIndicator();
mSidePanelGridView.setSelectedPosition(0);
if (DEBUG) {
@@ -536,13 +464,13 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
}
});
}
+ updateGuidePosition();
runnableAfterAnimatorReady.run();
if (mShowGuidePartial) {
mShowAnimatorPartial.start();
} else {
mShowAnimatorFull.start();
}
- updateGuidePosition();
}
};
mContainer.getViewTreeObserver().addOnGlobalLayoutListener(mOnLayoutListenerForShow);
@@ -564,7 +492,8 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
cancelHide();
mProgramManager.programGuideVisibilityChanged(false);
mProgramManager.removeListener(mProgramManagerListener);
- if (isFull()) {
+ mActive = false;
+ if (!mShowGuidePartial) {
mHideAnimatorFull.start();
} else {
mHideAnimatorPartial.start();
@@ -587,50 +516,21 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
}
}
+ /**
+ * Schedules hiding the program guide.
+ */
public void scheduleHide() {
cancelHide();
mHandler.postDelayed(mHideRunnable, mShowDurationMillis);
}
/**
- * Returns the scroll offset of the time line row in pixels.
- */
- public int getTimelineRowScrollOffset() {
- return mTimelineRow.getScrollOffset();
- }
-
- /**
- * Cancel hiding the program guide.
+ * Cancels hiding the program guide.
*/
public void cancelHide() {
mHandler.removeCallbacks(mHideRunnable);
}
- // Returns if program table is full screen mode.
- private boolean isFull() {
- return mPartialToFullAnimator.isStarted() || mTable.getTranslationX() == 0;
- }
-
- private void startFull() {
- if (isFull() || mAccessibilityManager.isEnabled()) {
- // If accessibility service is enabled, focus cannot be moved to side panel due to it's
- // hidden. Therefore, we don't hide side panel when accessibility service is enabled.
- return;
- }
- mShowGuidePartial = false;
- mSharedPreference.edit().putBoolean(KEY_SHOW_GUIDE_PARTIAL, mShowGuidePartial).apply();
- mPartialToFullAnimator.start();
- }
-
- private void startPartial() {
- if (!isFull()) {
- return;
- }
- mShowGuidePartial = true;
- mSharedPreference.edit().putBoolean(KEY_SHOW_GUIDE_PARTIAL, mShowGuidePartial).apply();
- mFullToPartialAnimator.start();
- }
-
/**
* Process the {@code KEYCODE_BACK} key event.
*/
@@ -639,16 +539,30 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
}
/**
- * Gets {@link VerticalGridView} for "genre select" side panel.
+ * Returns {@code true} if the program guide should process the input events.
*/
- public VerticalGridView getSidePanel() {
- return mSidePanelGridView;
+ public boolean isActive() {
+ return mActive;
+ }
+
+ /**
+ * Returns {@code true} if the program guide is shown, i.e. showing animation is done and
+ * hiding animation is not started yet.
+ */
+ public boolean isRunningAnimation() {
+ return mShowAnimatorPartial.isStarted() || mShowAnimatorFull.isStarted()
+ || mHideAnimatorPartial.isStarted() || mHideAnimatorFull.isStarted();
+ }
+
+ /** Returns if program table is in full screen mode. **/
+ boolean isFull() {
+ return !mShowGuidePartial;
}
/**
* Requests change genre to {@code genreId}.
*/
- public void requestGenreChange(int genreId) {
+ void requestGenreChange(int genreId) {
if (mLastRequestedGenreId == genreId) {
// When Recycler.onLayout() removes its children to recycle,
// View tries to find next focus candidate immediately
@@ -679,6 +593,104 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
mProgramTableFadeOutAnimator.start();
}
+ /**
+ * Returns the scroll offset of the time line row in pixels.
+ */
+ int getTimelineRowScrollOffset() {
+ return mTimelineRow.getScrollOffset();
+ }
+
+ /** Returns the program grid view that hold all component views. */
+ ProgramGrid getProgramGrid() {
+ return mGrid;
+ }
+
+ /**
+ * Gets {@link VerticalGridView} for "genre select" side panel.
+ */
+ VerticalGridView getSidePanel() {
+ return mSidePanelGridView;
+ }
+
+ /** Returns the program manager the program guide is using to provide program information. */
+ ProgramManager getProgramManager() {
+ return mProgramManager;
+ }
+
+ private void updateGuidePosition() {
+ // Align EPG at vertical center, if EPG table height is less than the screen size.
+ Resources res = mActivity.getResources();
+ int screenHeight = mContainer.getHeight();
+ if (screenHeight <= 0) {
+ // mContainer is not initialized yet.
+ return;
+ }
+ int startPadding = res.getDimensionPixelOffset(R.dimen.program_guide_table_margin_start);
+ int topPadding = res.getDimensionPixelOffset(R.dimen.program_guide_table_margin_top);
+ int bottomPadding = res.getDimensionPixelOffset(R.dimen.program_guide_table_margin_bottom);
+ int tableHeight = res.getDimensionPixelOffset(R.dimen.program_guide_table_header_row_height)
+ + mDetailHeight + mRowHeight * mGrid.getAdapter().getItemCount() + topPadding
+ + bottomPadding;
+ if (tableHeight > screenHeight) {
+ // EPG height is longer that the screen height.
+ mTable.setPaddingRelative(startPadding, topPadding, 0, 0);
+ LayoutParams layoutParams = mTable.getLayoutParams();
+ layoutParams.height = LayoutParams.WRAP_CONTENT;
+ mTable.setLayoutParams(layoutParams);
+ } else {
+ mTable.setPaddingRelative(startPadding, topPadding, 0, bottomPadding);
+ LayoutParams layoutParams = mTable.getLayoutParams();
+ layoutParams.height = tableHeight;
+ mTable.setLayoutParams(layoutParams);
+ }
+ }
+
+ private Animator createAnimator(int sidePanelAnimResId, int sidePanelGridAnimResId,
+ int tableAnimResId) {
+ List<Animator> animatorList = new ArrayList<>();
+
+ Animator sidePanelAnimator = AnimatorInflater.loadAnimator(mActivity, sidePanelAnimResId);
+ sidePanelAnimator.setTarget(mSidePanel);
+ animatorList.add(sidePanelAnimator);
+
+ if (sidePanelGridAnimResId != 0) {
+ Animator sidePanelGridAnimator = AnimatorInflater.loadAnimator(mActivity,
+ sidePanelGridAnimResId);
+ sidePanelGridAnimator.setTarget(mSidePanelGridView);
+ sidePanelGridAnimator.addListener(
+ new HardwareLayerAnimatorListenerAdapter(mSidePanelGridView));
+ animatorList.add(sidePanelGridAnimator);
+ }
+ Animator tableAnimator = AnimatorInflater.loadAnimator(mActivity, tableAnimResId);
+ tableAnimator.setTarget(mTable);
+ tableAnimator.addListener(new HardwareLayerAnimatorListenerAdapter(mTable));
+ animatorList.add(tableAnimator);
+
+ AnimatorSet set = new AnimatorSet();
+ set.playTogether(animatorList);
+ return set;
+ }
+
+ private void startFull() {
+ if (!mShowGuidePartial || mAccessibilityManager.isEnabled()) {
+ // If accessibility service is enabled, focus cannot be moved to side panel due to it's
+ // hidden. Therefore, we don't hide side panel when accessibility service is enabled.
+ return;
+ }
+ mShowGuidePartial = false;
+ mSharedPreference.edit().putBoolean(KEY_SHOW_GUIDE_PARTIAL, mShowGuidePartial).apply();
+ mPartialToFullAnimator.start();
+ }
+
+ private void startPartial() {
+ if (mShowGuidePartial) {
+ return;
+ }
+ mShowGuidePartial = true;
+ mSharedPreference.edit().putBoolean(KEY_SHOW_GUIDE_PARTIAL, mShowGuidePartial).apply();
+ mFullToPartialAnimator.start();
+ }
+
private void startCurrentTimeIndicator(long initialDelay) {
mHandler.postDelayed(mUpdateTimeIndicator, initialDelay);
}
@@ -775,10 +787,12 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
mDetailInAnimator.cancel();
}
- int direction = 0;
- if (outRow != null && inRow != null) {
- // -1 means the selection goes downwards and 1 goes upwards
- direction = outRow.getTop() < inRow.getTop() ? -1 : 1;
+ int operationDirection = mGrid.getLastUpDownDirection();
+ int animationPadding = 0;
+ if (operationDirection == View.FOCUS_UP) {
+ animationPadding = mDetailPadding;
+ } else if (operationDirection == View.FOCUS_DOWN) {
+ animationPadding = -mDetailPadding;
}
View outDetail = outRow != null ? outRow.findViewById(R.id.detail) : null;
@@ -788,7 +802,7 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
Animator fadeOutAnimator = ObjectAnimator.ofPropertyValuesHolder(outDetailContent,
PropertyValuesHolder.ofFloat(View.ALPHA, outDetail.getAlpha(), 0f),
PropertyValuesHolder.ofFloat(View.TRANSLATION_Y,
- outDetailContent.getTranslationY(), direction * mDetailPadding));
+ outDetailContent.getTranslationY(), animationPadding));
fadeOutAnimator.setStartDelay(0);
fadeOutAnimator.setDuration(mAnimationDuration);
fadeOutAnimator.addListener(new HardwareLayerAnimatorListenerAdapter(outDetailContent));
@@ -842,8 +856,7 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
});
Animator fadeInAnimator = ObjectAnimator.ofPropertyValuesHolder(inDetailContent,
PropertyValuesHolder.ofFloat(View.ALPHA, 0f, 1f),
- PropertyValuesHolder.ofFloat(View.TRANSLATION_Y,
- direction * -mDetailPadding, 0f));
+ PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, -animationPadding, 0f));
fadeInAnimator.setDuration(mAnimationDuration);
fadeInAnimator.addListener(new HardwareLayerAnimatorListenerAdapter(inDetailContent));
@@ -910,7 +923,7 @@ public class ProgramGuide implements ProgramGrid.ChildFocusListener {
}
private static class ProgramGuideHandler extends WeakHandler<ProgramGuide> {
- public ProgramGuideHandler(ProgramGuide ref) {
+ ProgramGuideHandler(ProgramGuide ref) {
super(ref);
}
diff --git a/src/com/android/tv/guide/ProgramItemView.java b/src/com/android/tv/guide/ProgramItemView.java
index 4c7a4404..b23d578c 100644
--- a/src/com/android/tv/guide/ProgramItemView.java
+++ b/src/com/android/tv/guide/ProgramItemView.java
@@ -44,8 +44,8 @@ import com.android.tv.analytics.Tracker;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.Channel;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.guide.ProgramManager.TableEntry;
import com.android.tv.util.ToastUtils;
import com.android.tv.util.Utils;
@@ -73,6 +73,7 @@ public class ProgramItemView extends TextView {
private static TextAppearanceSpan sEpisodeTitleStyle;
private static TextAppearanceSpan sGrayedOutEpisodeTitleStyle;
+ private ProgramGuide mProgramGuide;
private DvrManager mDvrManager;
private TableEntry mTableEntry;
private int mMaxWidthForRipple;
@@ -106,18 +107,19 @@ public class ProgramItemView extends TextView {
}, entry.getWidth() > ((ProgramItemView) view).mMaxWidthForRipple ? 0
: view.getResources()
.getInteger(R.integer.program_guide_ripple_anim_duration));
- } else if (CommonFeatures.DVR.isEnabled(view.getContext())) {
+ } else if (entry.program != null && CommonFeatures.DVR.isEnabled(view.getContext())) {
DvrManager dvrManager = singletons.getDvrManager();
if (entry.entryStartUtcMillis > System.currentTimeMillis()
&& dvrManager.isProgramRecordable(entry.program)) {
if (entry.scheduledRecording == null) {
- if (DvrUiHelper.checkStorageStatusAndShowErrorMessage(tvActivity,
- channel.getInputId())
- && DvrUiHelper.handleCreateSchedule(tvActivity, entry.program)) {
- String msg = view.getContext().getString(
- R.string.dvr_msg_program_scheduled, entry.program.getTitle());
- ToastUtils.show(view.getContext(), msg, Toast.LENGTH_SHORT);
- }
+ DvrUiHelper.checkStorageStatusAndShowErrorMessage(tvActivity,
+ channel.getInputId(), new Runnable() {
+ @Override
+ public void run() {
+ DvrUiHelper.requestRecordingFutureProgram(tvActivity,
+ entry.program, false);
+ }
+ });
} else {
dvrManager.removeScheduledRecording(entry.scheduledRecording);
String msg = view.getResources().getString(
@@ -158,6 +160,11 @@ public class ProgramItemView extends TextView {
}
if (entry.isCurrentProgram()) {
Drawable background = getBackground();
+ if (!mProgramGuide.isActive() || mProgramGuide.isRunningAnimation()) {
+ // If program guide is not active or is during showing/hiding,
+ // the animation is unnecessary, skip it.
+ background.jumpToCurrentState();
+ }
int progress = getProgress(entry.entryStartUtcMillis, entry.entryEndUtcMillis);
setProgress(background, R.id.reverse_progress, MAX_PROGRESS - progress);
}
@@ -247,8 +254,9 @@ public class ProgramItemView extends TextView {
}
@SuppressLint("SwitchIntDef")
- public void setValues(TableEntry entry, int selectedGenreId, long fromUtcMillis,
- long toUtcMillis, String gapTitle) {
+ public void setValues(ProgramGuide programGuide, TableEntry entry, int selectedGenreId,
+ long fromUtcMillis, long toUtcMillis, String gapTitle) {
+ mProgramGuide = programGuide;
mTableEntry = entry;
ViewGroup.LayoutParams layoutParams = getLayoutParams();
@@ -376,6 +384,7 @@ public class ProgramItemView extends TextView {
}
setTag(null);
+ mProgramGuide = null;
mTableEntry = null;
}
diff --git a/src/com/android/tv/guide/ProgramListAdapter.java b/src/com/android/tv/guide/ProgramListAdapter.java
index 03aea5ad..c1fcdd40 100644
--- a/src/com/android/tv/guide/ProgramListAdapter.java
+++ b/src/com/android/tv/guide/ProgramListAdapter.java
@@ -32,11 +32,12 @@ import com.android.tv.guide.ProgramManager.TableEntry;
* Adapts a program list for a specific channel from {@link ProgramManager} to a row of the program
* guide table.
*/
-public class ProgramListAdapter extends RecyclerView.Adapter<ProgramListAdapter.ProgramViewHolder>
+class ProgramListAdapter extends RecyclerView.Adapter<ProgramListAdapter.ProgramItemViewHolder>
implements TableEntriesUpdatedListener {
private static final String TAG = "ProgramListAdapter";
private static final boolean DEBUG = false;
+ private final ProgramGuide mProgramGuide;
private final ProgramManager mProgramManager;
private final int mChannelIndex;
private final String mNoInfoProgramTitle;
@@ -44,9 +45,10 @@ public class ProgramListAdapter extends RecyclerView.Adapter<ProgramListAdapter.
private long mChannelId;
- public ProgramListAdapter(Resources res, ProgramManager programManager, int channelIndex) {
+ ProgramListAdapter(Resources res, ProgramGuide programGuide, int channelIndex) {
setHasStableIds(true);
- mProgramManager = programManager;
+ mProgramGuide = programGuide;
+ mProgramManager = programGuide.getProgramManager();
mChannelIndex = channelIndex;
mNoInfoProgramTitle = res.getString(R.string.program_title_for_no_information);
mBlockedProgramTitle = res.getString(R.string.program_title_for_blocked_channel);
@@ -65,10 +67,6 @@ public class ProgramListAdapter extends RecyclerView.Adapter<ProgramListAdapter.
}
}
- public ProgramManager getProgramManager() {
- return mProgramManager;
- }
-
@Override
public int getItemCount() {
return mProgramManager.getTableEntryCount(mChannelId);
@@ -85,38 +83,40 @@ public class ProgramListAdapter extends RecyclerView.Adapter<ProgramListAdapter.
}
@Override
- public void onBindViewHolder(ProgramViewHolder holder, int position) {
+ public void onBindViewHolder(ProgramItemViewHolder holder, int position) {
TableEntry tableEntry = mProgramManager.getTableEntry(mChannelId, position);
String gapTitle = tableEntry.isBlocked() ? mBlockedProgramTitle : mNoInfoProgramTitle;
- holder.onBind(tableEntry, this.getProgramManager(), gapTitle);
+ holder.onBind(tableEntry, mProgramGuide, gapTitle);
}
@Override
- public void onViewRecycled(ProgramViewHolder holder) {
+ public void onViewRecycled(ProgramItemViewHolder holder) {
holder.onUnbind();
}
@Override
- public ProgramViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ public ProgramItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
- return new ProgramViewHolder(itemView);
+ return new ProgramItemViewHolder(itemView);
}
- public static class ProgramViewHolder extends RecyclerView.ViewHolder {
+ static class ProgramItemViewHolder extends RecyclerView.ViewHolder {
// Should be called from main thread.
- public ProgramViewHolder(View itemView) {
+ ProgramItemViewHolder(View itemView) {
super(itemView);
}
- public void onBind(TableEntry entry, ProgramManager programManager, String gapTitle) {
+ void onBind(TableEntry entry, ProgramGuide programGuide, String gapTitle) {
if (DEBUG) {
Log.d(TAG, "onBind. View = " + itemView + ", Entry = " + entry);
}
- ((ProgramItemView) itemView).setValues(entry, programManager.getSelectedGenreId(),
- programManager.getFromUtcMillis(), programManager.getToUtcMillis(), gapTitle);
+ ProgramManager programManager = programGuide.getProgramManager();
+ ((ProgramItemView) itemView).setValues(programGuide, entry,
+ programManager.getSelectedGenreId(), programManager.getFromUtcMillis(),
+ programManager.getToUtcMillis(), gapTitle);
}
- public void onUnbind() {
+ void onUnbind() {
((ProgramItemView) itemView).clearValues();
}
}
diff --git a/src/com/android/tv/guide/ProgramManager.java b/src/com/android/tv/guide/ProgramManager.java
index e3d919df..4ec3f77e 100644
--- a/src/com/android/tv/guide/ProgramManager.java
+++ b/src/com/android/tv/guide/ProgramManager.java
@@ -29,7 +29,7 @@ import com.android.tv.data.ProgramDataManager;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrScheduleManager;
import com.android.tv.dvr.DvrScheduleManager.OnConflictStateChangeListener;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
@@ -68,107 +68,6 @@ public class ProgramManager {
private long mFromUtcMillis;
private long mToUtcMillis;
- /**
- * Entry for program guide table. An "entry" can be either an actual program or a gap between
- * programs. This is needed for {@link ProgramListAdapter} because
- * {@link android.support.v17.leanback.widget.HorizontalGridView} ignores margins between items.
- */
- public static class TableEntry {
- /** Channel ID which this entry is included. */
- public final long channelId;
-
- /** Program corresponding to the entry. {@code null} means that this entry is a gap. */
- public final Program program;
-
- public final ScheduledRecording scheduledRecording;
-
- /** Start time of entry in UTC milliseconds. */
- public final long entryStartUtcMillis;
-
- /** End time of entry in UTC milliseconds */
- public final long entryEndUtcMillis;
-
- private final boolean mIsBlocked;
-
- private TableEntry(long channelId, long startUtcMillis, long endUtcMillis) {
- this(channelId, null, startUtcMillis, endUtcMillis, false);
- }
-
- private TableEntry(long channelId, long startUtcMillis, long endUtcMillis,
- boolean blocked) {
- this(channelId, null, null, startUtcMillis, endUtcMillis, blocked);
- }
-
- private TableEntry(long channelId, Program program, long entryStartUtcMillis,
- long entryEndUtcMillis, boolean isBlocked) {
- this(channelId, program, null, entryStartUtcMillis, entryEndUtcMillis, isBlocked);
- }
-
- private TableEntry(long channelId, Program program, ScheduledRecording scheduledRecording,
- long entryStartUtcMillis, long entryEndUtcMillis, boolean isBlocked) {
- this.channelId = channelId;
- this.program = program;
- this.scheduledRecording = scheduledRecording;
- this.entryStartUtcMillis = entryStartUtcMillis;
- this.entryEndUtcMillis = entryEndUtcMillis;
- mIsBlocked = isBlocked;
- }
-
- /**
- * A stable id useful for {@link android.support.v7.widget.RecyclerView.Adapter}.
- */
- public long getId() {
- // using a negative entryEndUtcMillis keeps it from conflicting with program Id
- return program != null ? program.getId() : -entryEndUtcMillis;
- }
-
- /**
- * Returns true if this is a gap.
- */
- public boolean isGap() {
- return !Program.isValid(program);
- }
-
- /**
- * Returns true if this channel is blocked.
- */
- public boolean isBlocked() {
- return mIsBlocked;
- }
-
- /**
- * Returns true if this program is on the air.
- */
- public boolean isCurrentProgram() {
- long current = System.currentTimeMillis();
- return entryStartUtcMillis <= current && entryEndUtcMillis > current;
- }
-
- /**
- * Returns if this program has the genre.
- */
- public boolean hasGenre(int genreId) {
- return !isGap() && program.hasGenre(genreId);
- }
-
- /**
- * Returns the width of table entry, in pixels.
- */
- public int getWidth() {
- return GuideUtils.convertMillisToPixel(entryStartUtcMillis, entryEndUtcMillis);
- }
-
- @Override
- public String toString() {
- return "TableEntry{"
- + "hashCode=" + hashCode()
- + ", channelId=" + channelId
- + ", program=" + program
- + ", startTime=" + Utils.toTimeString(entryStartUtcMillis)
- + ", endTimeTime=" + Utils.toTimeString(entryEndUtcMillis) + "}";
- }
- }
-
private List<Channel> mChannels = new ArrayList<>();
private final Map<Long, List<TableEntry>> mChannelIdEntriesMap = new HashMap<>();
private final List<List<Channel>> mGenreChannelList = new ArrayList<>();
@@ -293,7 +192,7 @@ public class ProgramManager {
mDvrScheduleManager = dvrScheduleManager;
}
- public void programGuideVisibilityChanged(boolean visible) {
+ void programGuideVisibilityChanged(boolean visible) {
mProgramDataManager.setPauseProgramUpdate(visible);
if (visible) {
mChannelDataManager.addListener(mChannelDataManagerListener);
@@ -325,87 +224,51 @@ public class ProgramManager {
/**
* Adds a {@link Listener}.
*/
- public void addListener(Listener listener) {
+ void addListener(Listener listener) {
mListeners.add(listener);
}
/**
* Registers a listener to be invoked when table entries are updated.
*/
- public void addTableEntriesUpdatedListener(TableEntriesUpdatedListener listener) {
+ void addTableEntriesUpdatedListener(TableEntriesUpdatedListener listener) {
mTableEntriesUpdatedListeners.add(listener);
}
/**
* Registers a listener to be invoked when a table entry is changed.
*/
- public void addTableEntryChangedListener(TableEntryChangedListener listener) {
+ void addTableEntryChangedListener(TableEntryChangedListener listener) {
mTableEntryChangedListeners.add(listener);
}
/**
* Removes a {@link Listener}.
*/
- public void removeListener(Listener listener) {
+ void removeListener(Listener listener) {
mListeners.remove(listener);
}
/**
* Removes a previously installed table entries update listener.
*/
- public void removeTableEntriesUpdatedListener(TableEntriesUpdatedListener listener) {
+ void removeTableEntriesUpdatedListener(TableEntriesUpdatedListener listener) {
mTableEntriesUpdatedListeners.remove(listener);
}
/**
* Removes a previously installed table entry changed listener.
*/
- public void removeTableEntryChangedListener(TableEntryChangedListener listener) {
+ void removeTableEntryChangedListener(TableEntryChangedListener listener) {
mTableEntryChangedListeners.remove(listener);
}
/**
- * Build genre filters based on the current programs.
- * This categories channels by its current program's canonical genres
- * and subsequent @{link resetChannelListWithGenre(int)} calls will reset channel list
- * with built channel list.
- * This is expected to be called whenever program guide is shown.
- */
- public void buildGenreFilters() {
- if (DEBUG) Log.d(TAG, "buildGenreFilters");
-
- mGenreChannelList.clear();
- for (int i = 0; i < GenreItems.getGenreCount(); i++) {
- mGenreChannelList.add(new ArrayList<>());
- }
- for (Channel channel : mChannels) {
- // TODO: Use programs in visible area instead of using current programs only.
- Program currentProgram = mProgramDataManager.getCurrentProgram(channel.getId());
- if (currentProgram != null && currentProgram.getCanonicalGenres() != null) {
- for (String genre : currentProgram.getCanonicalGenres()) {
- mGenreChannelList.get(GenreItems.getId(genre)).add(channel);
- }
- }
- }
- mGenreChannelList.set(GenreItems.ID_ALL_CHANNELS, mChannels);
- mFilteredGenreIds.clear();
- mFilteredGenreIds.add(0);
- for (int i = 1; i < GenreItems.getGenreCount(); i++) {
- if (mGenreChannelList.get(i).size() > 0) {
- mFilteredGenreIds.add(i);
- }
- }
- mSelectedGenreId = GenreItems.ID_ALL_CHANNELS;
- mFilteredChannels = mChannels;
- notifyGenresUpdated();
- }
-
- /**
* Resets channel list with given genre.
* Caller should call {@link #buildGenreFilters()} prior to call this API to make
* This notifies channel updates to listeners.
*/
- public void resetChannelListWithGenre(int genreId) {
+ void resetChannelListWithGenre(int genreId) {
if (genreId == mSelectedGenreId) {
return;
}
@@ -422,13 +285,154 @@ public class ProgramManager {
}
/**
+ * Update the initial time range to manage. It updates program entries and genre as well.
+ */
+ void updateInitialTimeRange(long startUtcMillis, long endUtcMillis) {
+ mStartUtcMillis = startUtcMillis;
+ if (endUtcMillis > mEndUtcMillis) {
+ mEndUtcMillis = endUtcMillis;
+ }
+
+ mProgramDataManager.setPrefetchTimeRange(mStartUtcMillis);
+ updateChannels(true);
+ setTimeRange(startUtcMillis, endUtcMillis);
+ }
+
+
+ /**
+ * Shifts the time range by the given time. Also makes ProgramGuide scroll the views.
+ */
+ void shiftTime(long timeMillisToScroll) {
+ long fromUtcMillis = mFromUtcMillis + timeMillisToScroll;
+ long toUtcMillis = mToUtcMillis + timeMillisToScroll;
+ if (fromUtcMillis < mStartUtcMillis) {
+ fromUtcMillis = mStartUtcMillis;
+ toUtcMillis += mStartUtcMillis - fromUtcMillis;
+ }
+ if (toUtcMillis > mEndUtcMillis) {
+ fromUtcMillis -= toUtcMillis - mEndUtcMillis;
+ toUtcMillis = mEndUtcMillis;
+ }
+ setTimeRange(fromUtcMillis, toUtcMillis);
+ }
+
+ /**
+ * Returned the scrolled(shifted) time in milliseconds.
+ */
+ long getShiftedTime() {
+ return mFromUtcMillis - mStartUtcMillis;
+ }
+
+ /**
+ * Returns the start time set by {@link #updateInitialTimeRange}.
+ */
+ long getStartTime() {
+ return mStartUtcMillis;
+ }
+
+ /**
+ * Returns the program index of the program with {@code entryId} or -1 if not found.
+ */
+ int getProgramIdIndex(long channelId, long entryId) {
+ List<TableEntry> entries = mChannelIdEntriesMap.get(channelId);
+ if (entries != null) {
+ for (int i = 0; i < entries.size(); i++) {
+ if (entries.get(i).getId() == entryId) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the program index of the program at {@code time} or -1 if not found.
+ */
+ int getProgramIndexAtTime(long channelId, long time) {
+ List<TableEntry> entries = mChannelIdEntriesMap.get(channelId);
+ for (int i = 0; i < entries.size(); ++i) {
+ TableEntry entry = entries.get(i);
+ if (entry.entryStartUtcMillis <= time
+ && time < entry.entryEndUtcMillis) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the start time of currently managed time range, in UTC millisecond.
+ */
+ long getFromUtcMillis() {
+ return mFromUtcMillis;
+ }
+
+ /**
+ * Returns the end time of currently managed time range, in UTC millisecond.
+ */
+ long getToUtcMillis() {
+ return mToUtcMillis;
+ }
+
+ /**
+ * Returns the number of the currently managed channels.
+ */
+ int getChannelCount() {
+ return mFilteredChannels.size();
+ }
+
+ /**
+ * Returns a {@link Channel} at a given {@code channelIndex} of the currently managed channels.
+ * Returns {@code null} if such a channel is not found.
+ */
+ Channel getChannel(int channelIndex) {
+ if (channelIndex < 0 || channelIndex >= getChannelCount()) {
+ return null;
+ }
+ return mFilteredChannels.get(channelIndex);
+ }
+
+ /**
+ * Returns the index of provided {@link Channel} within the currently managed channels.
+ * Returns -1 if such a channel is not found.
+ */
+ int getChannelIndex(Channel channel) {
+ return mFilteredChannels.indexOf(channel);
+ }
+
+ /**
+ * Returns the index of channel with {@code channelId} within the currently managed channels.
+ * Returns -1 if such a channel is not found.
+ */
+ int getChannelIndex(long channelId) {
+ return getChannelIndex(mChannelDataManager.getChannel(channelId));
+ }
+
+ /**
+ * Returns the number of "entries", which lies within the currently managed time range, for a
+ * given {@code channelId}.
+ */
+ int getTableEntryCount(long channelId) {
+ return mChannelIdEntriesMap.get(channelId).size();
+ }
+
+ /**
+ * Returns an entry as {@link Program} for a given {@code channelId} and {@code index} of
+ * entries within the currently managed time range. Returned {@link Program} can be a dummy one
+ * (e.g., whose channelId is INVALID_ID), when it corresponds to a gap between programs.
+ */
+ TableEntry getTableEntry(long channelId, int index) {
+ return mChannelIdEntriesMap.get(channelId).get(index);
+ }
+
+ /**
* Returns list genre ID's which has a channel.
*/
- public List<Integer> getFilteredGenreIds() {
+ List<Integer> getFilteredGenreIds() {
return mFilteredGenreIds;
}
- public int getSelectedGenreId() {
+ int getSelectedGenreId() {
return mSelectedGenreId;
}
@@ -439,11 +443,24 @@ public class ProgramManager {
mChannels = mChannelDataManager.getBrowsableChannelList();
mSelectedGenreId = GenreItems.ID_ALL_CHANNELS;
mFilteredChannels = mChannels;
+ updateTableEntriesWithoutNotification(clearPreviousTableEntries);
+ // Channel update notification should be called after updating table entries, so that
+ // the listener can get the entries.
notifyChannelsUpdated();
- updateTableEntries(clearPreviousTableEntries);
+ notifyTableEntriesUpdated();
+ buildGenreFilters();
}
private void updateTableEntries(boolean clear) {
+ updateTableEntriesWithoutNotification(clear);
+ notifyTableEntriesUpdated();
+ buildGenreFilters();
+ }
+
+ /**
+ * Updates the table entries without notifying the change.
+ */
+ private void updateTableEntriesWithoutNotification(boolean clear) {
if (clear) {
mChannelIdEntriesMap.clear();
}
@@ -491,46 +508,41 @@ public class ProgramManager {
}
}
}
-
- notifyTableEntriesUpdated();
- buildGenreFilters();
- }
-
- private void notifyGenresUpdated() {
- for (Listener listener : mListeners) {
- listener.onGenresUpdated();
- }
}
- private void notifyChannelsUpdated() {
- for (Listener listener : mListeners) {
- listener.onChannelsUpdated();
- }
- }
+ /**
+ * Build genre filters based on the current programs.
+ * This categories channels by its current program's canonical genres
+ * and subsequent @{link resetChannelListWithGenre(int)} calls will reset channel list
+ * with built channel list.
+ * This is expected to be called whenever program guide is shown.
+ */
+ private void buildGenreFilters() {
+ if (DEBUG) Log.d(TAG, "buildGenreFilters");
- private void notifyTimeRangeUpdated() {
- for (Listener listener : mListeners) {
- listener.onTimeRangeUpdated();
+ mGenreChannelList.clear();
+ for (int i = 0; i < GenreItems.getGenreCount(); i++) {
+ mGenreChannelList.add(new ArrayList<>());
}
- }
-
- private void notifyTableEntriesUpdated() {
- for (TableEntriesUpdatedListener listener : mTableEntriesUpdatedListeners) {
- listener.onTableEntriesUpdated();
+ for (Channel channel : mChannels) {
+ Program currentProgram = mProgramDataManager.getCurrentProgram(channel.getId());
+ if (currentProgram != null && currentProgram.getCanonicalGenres() != null) {
+ for (String genre : currentProgram.getCanonicalGenres()) {
+ mGenreChannelList.get(GenreItems.getId(genre)).add(channel);
+ }
+ }
}
- }
-
- private void notifyTableEntryUpdated(TableEntry entry) {
- for (TableEntryChangedListener listener : mTableEntryChangedListeners) {
- listener.onTableEntryChanged(entry);
+ mGenreChannelList.set(GenreItems.ID_ALL_CHANNELS, mChannels);
+ mFilteredGenreIds.clear();
+ mFilteredGenreIds.add(0);
+ for (int i = 1; i < GenreItems.getGenreCount(); i++) {
+ if (mGenreChannelList.get(i).size() > 0) {
+ mFilteredGenreIds.add(i);
+ }
}
- }
-
- private void updateEntry(TableEntry old, TableEntry newEntry) {
- List<TableEntry> entries = mChannelIdEntriesMap.get(old.channelId);
- int index = entries.indexOf(old);
- entries.set(index, newEntry);
- notifyTableEntryUpdated(newEntry);
+ mSelectedGenreId = GenreItems.ID_ALL_CHANNELS;
+ mFilteredChannels = mChannels;
+ notifyGenresUpdated();
}
@Nullable
@@ -551,32 +563,11 @@ public class ProgramManager {
return null;
}
- /**
- * Returns the start time of currently managed time range, in UTC millisecond.
- */
- public long getFromUtcMillis() {
- return mFromUtcMillis;
- }
-
- /**
- * Returns the end time of currently managed time range, in UTC millisecond.
- */
- public long getToUtcMillis() {
- return mToUtcMillis;
- }
-
- /**
- * Update the initial time range to manage. It updates program entries and genre as well.
- */
- public void updateInitialTimeRange(long startUtcMillis, long endUtcMillis) {
- mStartUtcMillis = startUtcMillis;
- if (endUtcMillis > mEndUtcMillis) {
- mEndUtcMillis = endUtcMillis;
- }
-
- mProgramDataManager.setPrefetchTimeRange(mStartUtcMillis);
- updateChannels(true);
- setTimeRange(startUtcMillis, endUtcMillis);
+ private void updateEntry(TableEntry old, TableEntry newEntry) {
+ List<TableEntry> entries = mChannelIdEntriesMap.get(old.channelId);
+ int index = entries.indexOf(old);
+ entries.set(index, newEntry);
+ notifyTableEntryUpdated(newEntry);
}
private void setTimeRange(long fromUtcMillis, long toUtcMillis) {
@@ -592,57 +583,6 @@ public class ProgramManager {
}
}
- /**
- * Returns the number of the currently managed channels.
- */
- public int getChannelCount() {
- return mFilteredChannels.size();
- }
-
- /**
- * Returns a {@link Channel} at a given {@code channelIndex} of the currently managed channels.
- * Returns {@code null} if such a channel is not found.
- */
- public Channel getChannel(int channelIndex) {
- if (channelIndex < 0 || channelIndex >= getChannelCount()) {
- return null;
- }
- return mFilteredChannels.get(channelIndex);
- }
-
- /**
- * Returns the index of provided {@link Channel} within the currently managed channels.
- * Returns -1 if such a channel is not found.
- */
- public int getChannelIndex(Channel channel) {
- return mFilteredChannels.indexOf(channel);
- }
-
- /**
- * Returns the index of channel with {@code channelId} within the currently managed channels.
- * Returns -1 if such a channel is not found.
- */
- public int getChannelIndex(long channelId) {
- return getChannelIndex(mChannelDataManager.getChannel(channelId));
- }
-
- /**
- * Returns the number of "entries", which lies within the currently managed time range, for a
- * given {@code channelId}.
- */
- public int getTableEntryCount(long channelId) {
- return mChannelIdEntriesMap.get(channelId).size();
- }
-
- /**
- * Returns an entry as {@link Program} for a given {@code channelId} and {@code index} of
- * entries within the currently managed time range. Returned {@link Program} can be a dummy one
- * (e.g., whose channelId is INVALID_ID), when it corresponds to a gap between programs.
- */
- public TableEntry getTableEntry(long channelId, int index) {
- return mChannelIdEntriesMap.get(channelId).get(index);
- }
-
private List<TableEntry> createProgramEntries(long channelId, boolean parentalControlsEnabled) {
List<TableEntry> entries = new ArrayList<>();
boolean channelLocked = parentalControlsEnabled
@@ -690,89 +630,159 @@ public class ProgramManager {
return entries;
}
- public interface Listener {
- void onGenresUpdated();
- void onChannelsUpdated();
- void onTimeRangeUpdated();
+ private void notifyGenresUpdated() {
+ for (Listener listener : mListeners) {
+ listener.onGenresUpdated();
+ }
}
- public interface TableEntriesUpdatedListener {
- void onTableEntriesUpdated();
+ private void notifyChannelsUpdated() {
+ for (Listener listener : mListeners) {
+ listener.onChannelsUpdated();
+ }
}
- public interface TableEntryChangedListener {
- void onTableEntryChanged(TableEntry entry);
+ private void notifyTimeRangeUpdated() {
+ for (Listener listener : mListeners) {
+ listener.onTimeRangeUpdated();
+ }
}
- public static class ListenerAdapter implements Listener {
- @Override
- public void onGenresUpdated() { }
-
- @Override
- public void onChannelsUpdated() { }
+ private void notifyTableEntriesUpdated() {
+ for (TableEntriesUpdatedListener listener : mTableEntriesUpdatedListeners) {
+ listener.onTableEntriesUpdated();
+ }
+ }
- @Override
- public void onTimeRangeUpdated() { }
+ private void notifyTableEntryUpdated(TableEntry entry) {
+ for (TableEntryChangedListener listener : mTableEntryChangedListeners) {
+ listener.onTableEntryChanged(entry);
+ }
}
/**
- * Shifts the time range by the given time. Also makes ProgramGuide scroll the views.
+ * Entry for program guide table. An "entry" can be either an actual program or a gap between
+ * programs. This is needed for {@link ProgramListAdapter} because
+ * {@link android.support.v17.leanback.widget.HorizontalGridView} ignores margins between items.
*/
- public void shiftTime(long timeMillisToScroll) {
- long fromUtcMillis = mFromUtcMillis + timeMillisToScroll;
- long toUtcMillis = mToUtcMillis + timeMillisToScroll;
- if (fromUtcMillis < mStartUtcMillis) {
- fromUtcMillis = mStartUtcMillis;
- toUtcMillis += mStartUtcMillis - fromUtcMillis;
+ static class TableEntry {
+ /** Channel ID which this entry is included. */
+ final long channelId;
+
+ /** Program corresponding to the entry. {@code null} means that this entry is a gap. */
+ final Program program;
+
+ final ScheduledRecording scheduledRecording;
+
+ /** Start time of entry in UTC milliseconds. */
+ final long entryStartUtcMillis;
+
+ /** End time of entry in UTC milliseconds */
+ final long entryEndUtcMillis;
+
+ private final boolean mIsBlocked;
+
+ private TableEntry(long channelId, long startUtcMillis, long endUtcMillis) {
+ this(channelId, null, startUtcMillis, endUtcMillis, false);
}
- if (toUtcMillis > mEndUtcMillis) {
- fromUtcMillis -= toUtcMillis - mEndUtcMillis;
- toUtcMillis = mEndUtcMillis;
+
+ private TableEntry(long channelId, long startUtcMillis, long endUtcMillis,
+ boolean blocked) {
+ this(channelId, null, null, startUtcMillis, endUtcMillis, blocked);
+ }
+
+ private TableEntry(long channelId, Program program, long entryStartUtcMillis,
+ long entryEndUtcMillis, boolean isBlocked) {
+ this(channelId, program, null, entryStartUtcMillis, entryEndUtcMillis, isBlocked);
+ }
+
+ private TableEntry(long channelId, Program program, ScheduledRecording scheduledRecording,
+ long entryStartUtcMillis, long entryEndUtcMillis, boolean isBlocked) {
+ this.channelId = channelId;
+ this.program = program;
+ this.scheduledRecording = scheduledRecording;
+ this.entryStartUtcMillis = entryStartUtcMillis;
+ this.entryEndUtcMillis = entryEndUtcMillis;
+ mIsBlocked = isBlocked;
+ }
+
+ /**
+ * A stable id useful for {@link android.support.v7.widget.RecyclerView.Adapter}.
+ */
+ long getId() {
+ // using a negative entryEndUtcMillis keeps it from conflicting with program Id
+ return program != null ? program.getId() : -entryEndUtcMillis;
+ }
+
+ /**
+ * Returns true if this is a gap.
+ */
+ boolean isGap() {
+ return !Program.isValid(program);
+ }
+
+ /**
+ * Returns true if this channel is blocked.
+ */
+ boolean isBlocked() {
+ return mIsBlocked;
+ }
+
+ /**
+ * Returns true if this program is on the air.
+ */
+ boolean isCurrentProgram() {
+ long current = System.currentTimeMillis();
+ return entryStartUtcMillis <= current && entryEndUtcMillis > current;
+ }
+
+ /**
+ * Returns if this program has the genre.
+ */
+ boolean hasGenre(int genreId) {
+ return !isGap() && program.hasGenre(genreId);
+ }
+
+ /**
+ * Returns the width of table entry, in pixels.
+ */
+ int getWidth() {
+ return GuideUtils.convertMillisToPixel(entryStartUtcMillis, entryEndUtcMillis);
+ }
+
+ @Override
+ public String toString() {
+ return "TableEntry{"
+ + "hashCode=" + hashCode()
+ + ", channelId=" + channelId
+ + ", program=" + program
+ + ", startTime=" + Utils.toTimeString(entryStartUtcMillis)
+ + ", endTimeTime=" + Utils.toTimeString(entryEndUtcMillis) + "}";
}
- setTimeRange(fromUtcMillis, toUtcMillis);
}
- /**
- * Returned the scrolled(shifted) time in milliseconds.
- */
- public long getShiftedTime() {
- return mFromUtcMillis - mStartUtcMillis;
+ interface Listener {
+ void onGenresUpdated();
+ void onChannelsUpdated();
+ void onTimeRangeUpdated();
}
- /**
- * Returns the start time set by {@link #updateInitialTimeRange}.
- */
- public long getStartTime() {
- return mStartUtcMillis;
+ interface TableEntriesUpdatedListener {
+ void onTableEntriesUpdated();
}
- /**
- * Returns the program index of the program with {@code entryId} or -1 if not found.
- */
- public int getProgramIdIndex(long channelId, long entryId) {
- List<TableEntry> entries = mChannelIdEntriesMap.get(channelId);
- if (entries != null) {
- for (int i = 0; i < entries.size(); i++) {
- if (entries.get(i).getId() == entryId) {
- return i;
- }
- }
- }
- return -1;
+ interface TableEntryChangedListener {
+ void onTableEntryChanged(TableEntry entry);
}
- /**
- * Returns the program index of the program at {@code time} or -1 if not found.
- */
- public int getProgramIndexAtTime(long channelId, long time) {
- List<TableEntry> entries = mChannelIdEntriesMap.get(channelId);
- for (int i = 0; i < entries.size(); ++i) {
- TableEntry entry = entries.get(i);
- if (entry.entryStartUtcMillis <= time
- && time < entry.entryEndUtcMillis) {
- return i;
- }
- }
- return -1;
+ static class ListenerAdapter implements Listener {
+ @Override
+ public void onGenresUpdated() { }
+
+ @Override
+ public void onChannelsUpdated() { }
+
+ @Override
+ public void onTimeRangeUpdated() { }
}
}
diff --git a/src/com/android/tv/guide/ProgramRow.java b/src/com/android/tv/guide/ProgramRow.java
index 2c98ab2d..fefc724c 100644
--- a/src/com/android/tv/guide/ProgramRow.java
+++ b/src/com/android/tv/guide/ProgramRow.java
@@ -21,9 +21,11 @@ import android.graphics.Rect;
import android.support.v7.widget.LinearLayoutManager;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.Range;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import com.android.tv.MainActivity;
import com.android.tv.data.Channel;
import com.android.tv.guide.ProgramManager.TableEntry;
import com.android.tv.util.Utils;
@@ -37,6 +39,7 @@ public class ProgramRow extends TimelineGridView {
private static final long ONE_HOUR_MILLIS = TimeUnit.HOURS.toMillis(1);
private static final long HALF_HOUR_MILLIS = ONE_HOUR_MILLIS / 2;
+ private ProgramGuide mProgramGuide;
private ProgramManager mProgramManager;
private boolean mKeepFocusToCurrentProgram;
@@ -44,8 +47,8 @@ public class ProgramRow extends TimelineGridView {
interface ChildFocusListener {
/**
- * Is called after focus is moved. It used {@link ChildFocusListener#isChild} to decide if
- * old and new focuses are listener's children.
+ * Is called after focus is moved. Caller should check if old and new focuses are
+ * listener's children.
* See {@code ProgramRow#setChildFocusListener(ChildFocusListener)}.
*/
void onChildFocus(View oldFocus, View newFocus);
@@ -213,7 +216,6 @@ public class ProgramRow extends TimelineGridView {
// so give focus back in onChildAttachedToWindow().
mKeepFocusToCurrentProgram = true;
}
- // TODO: Try to keep focus for non-current program.
}
super.onChildDetachedFromWindow(child);
}
@@ -237,16 +239,18 @@ public class ProgramRow extends TimelineGridView {
@Override
public boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
- // Give focus to the current program by default.
- // Note that this logic is used only if requestFocus() is called to the ProgramRow,
- // so focus finding logic will not be blocked by this.
- View currentProgram = getCurrentProgramView();
- if (currentProgram != null) {
- return currentProgram.requestFocus();
+ ProgramGrid programGrid = mProgramGuide.getProgramGrid();
+
+ // Give focus according to the previous focused range
+ Range<Integer> focusRange = programGrid.getFocusRange();
+ View nextFocus = GuideUtils.findNextFocusedProgram(this, focusRange.getLower(),
+ focusRange.getUpper(), programGrid.isKeepCurrentProgramFocused());
+
+ if (nextFocus != null) {
+ return nextFocus.requestFocus();
}
if (DEBUG) Log.d(TAG, "onRequestFocusInDescendants");
-
boolean result = super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
if (!result) {
// The default focus search logic of LeanbackLibrary is sometimes failed.
@@ -276,10 +280,11 @@ public class ProgramRow extends TimelineGridView {
}
/**
- * Sets the instance of {@link ProgramManager}
+ * Sets the instance of {@link ProgramGuide}
*/
- public void setProgramManager(ProgramManager programManager) {
- mProgramManager = programManager;
+ public void setProgramGuide(ProgramGuide programGuide) {
+ mProgramGuide = programGuide;
+ mProgramManager = programGuide.getProgramManager();
}
/**
@@ -300,7 +305,7 @@ public class ProgramRow extends TimelineGridView {
.scrollToPositionWithOffset(position, offset);
// Workaround to b/31598505. When a program's duration is too long,
// RecyclerView.onScrolled() will not be called after scrollToPositionWithOffset().
- // Therefore we have to update children's visible areas by ourselves in theis case.
+ // Therefore we have to update children's visible areas by ourselves in this case.
// Since scrollToPositionWithOffset() will call requestLayout(), we can listen to this
// behavior to ensure program items' visible areas are correctly updated after layouts
// are adjusted, i.e., scrolling is over.
diff --git a/src/com/android/tv/guide/ProgramTableAdapter.java b/src/com/android/tv/guide/ProgramTableAdapter.java
index e4a67972..99f853b1 100644
--- a/src/com/android/tv/guide/ProgramTableAdapter.java
+++ b/src/com/android/tv/guide/ProgramTableAdapter.java
@@ -45,19 +45,21 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.tv.R;
import com.android.tv.TvApplication;
+import com.android.tv.common.TvCommonUtils;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
import com.android.tv.data.Program.CriticScore;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.guide.ProgramManager.TableEntriesUpdatedListener;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.ui.HardwareLayerAnimatorListenerAdapter;
@@ -73,7 +75,7 @@ import java.util.List;
/**
* Adapts the {@link ProgramListAdapter} list to the body of the program guide table.
*/
-public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapter.ProgramRowHolder>
+class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapter.ProgramRowViewHolder>
implements ProgramManager.TableEntryChangedListener {
private static final String TAG = "ProgramTableAdapter";
private static final boolean DEBUG = false;
@@ -112,8 +114,7 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
private final int mDvrPaddingStartWithTrack;
private final int mDvrPaddingStartWithOutTrack;
- public ProgramTableAdapter(Context context, ProgramManager programManager,
- ProgramGuide programGuide) {
+ ProgramTableAdapter(Context context, ProgramGuide programGuide) {
mContext = context;
mAccessibilityManager =
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
@@ -125,8 +126,8 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
mDvrManager = null;
mDvrDataManager = null;
}
- mProgramManager = programManager;
mProgramGuide = programGuide;
+ mProgramManager = programGuide.getProgramManager();
Resources res = context.getResources();
mChannelLogoWidth = res.getDimensionPixelSize(
@@ -193,7 +194,7 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
mProgramListAdapters.clear();
for (int i = 0; i < mProgramManager.getChannelCount(); i++) {
ProgramListAdapter listAdapter = new ProgramListAdapter(mContext.getResources(),
- mProgramManager, i);
+ mProgramGuide, i);
mProgramManager.addTableEntriesUpdatedListener(listAdapter);
mProgramListAdapters.add(listAdapter);
}
@@ -211,12 +212,12 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
}
@Override
- public void onBindViewHolder(ProgramRowHolder holder, int position) {
+ public void onBindViewHolder(ProgramRowViewHolder holder, int position) {
holder.onBind(position);
}
@Override
- public void onBindViewHolder(ProgramRowHolder holder, int position, List<Object> payloads) {
+ public void onBindViewHolder(ProgramRowViewHolder holder, int position, List<Object> payloads) {
if (!payloads.isEmpty()) {
holder.updateDetailView();
} else {
@@ -225,11 +226,11 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
}
@Override
- public ProgramRowHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ public ProgramRowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
ProgramRow programRow = (ProgramRow) itemView.findViewById(R.id.row);
programRow.setRecycledViewPool(mRecycledViewPool);
- return new ProgramRowHolder(itemView);
+ return new ProgramRowViewHolder(itemView);
}
@Override
@@ -241,18 +242,7 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
notifyItemChanged(channelIndex, true);
}
- @Override
- public void onViewAttachedToWindow(ProgramRowHolder holder) {
- holder.onAttachedToWindow();
- }
-
- @Override
- public void onViewDetachedFromWindow(ProgramRowHolder holder) {
- holder.onDetachedFromWindow();
- }
-
- // TODO: make it static
- public class ProgramRowHolder extends RecyclerView.ViewHolder
+ class ProgramRowViewHolder extends RecyclerView.ViewHolder
implements ProgramRow.ChildFocusListener {
private final ViewGroup mContainer;
@@ -269,6 +259,12 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
}
}
};
+ private final Runnable mUpdateDetailViewRunnable = new Runnable() {
+ @Override
+ public void run() {
+ updateDetailView();
+ }
+ };
private final RecyclerView.OnScrollListener mOnScrollListener =
new RecyclerView.OnScrollListener() {
@@ -282,8 +278,9 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
new ViewTreeObserver.OnGlobalFocusChangeListener() {
@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
- onChildFocus(isChild(oldFocus) ? oldFocus : null,
- isChild(newFocus) ? newFocus : null);
+ onChildFocus(
+ GuideUtils.isDescendant(mContainer, oldFocus) ? oldFocus : null,
+ GuideUtils.isDescendant(mContainer, newFocus) ? newFocus : null);
}
};
@@ -312,11 +309,38 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
private final ImageView mInputLogoView;
private boolean mIsInputLogoVisible;
+ private AccessibilityStateChangeListener mAccessibilityStateChangeListener =
+ new AccessibilityManager.AccessibilityStateChangeListener() {
+ @Override
+ public void onAccessibilityStateChanged(boolean enable) {
+ enable &= !TvCommonUtils.isRunningInTest();
+ mDetailView.setFocusable(enable);
+ mChannelHeaderView.setFocusable(enable);
+ }
+ };
- public ProgramRowHolder(View itemView) {
+ ProgramRowViewHolder(View itemView) {
super(itemView);
mContainer = (ViewGroup) itemView;
+ mContainer.addOnAttachStateChangeListener(
+ new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ mContainer.getViewTreeObserver()
+ .addOnGlobalFocusChangeListener(mGlobalFocusChangeListener);
+ mAccessibilityManager.addAccessibilityStateChangeListener(
+ mAccessibilityStateChangeListener);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ mContainer.getViewTreeObserver()
+ .removeOnGlobalFocusChangeListener(mGlobalFocusChangeListener);
+ mAccessibilityManager.removeAccessibilityStateChangeListener(
+ mAccessibilityStateChangeListener);
+ }
+ });
mProgramRow = (ProgramRow) mContainer.findViewById(R.id.row);
mDetailView = (ViewGroup) mContainer.findViewById(R.id.detail);
@@ -339,23 +363,18 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
mChannelLogoView = (ImageView) mContainer.findViewById(R.id.channel_logo);
mChannelBlockView = (ImageView) mContainer.findViewById(R.id.channel_block);
mInputLogoView = (ImageView) mContainer.findViewById(R.id.input_logo);
- mDetailView.setFocusable(mAccessibilityManager.isEnabled());
- mChannelHeaderView.setFocusable(mAccessibilityManager.isEnabled());
- mAccessibilityManager.addAccessibilityStateChangeListener(
- new AccessibilityManager.AccessibilityStateChangeListener() {
- @Override
- public void onAccessibilityStateChanged(boolean enable) {
- mDetailView.setFocusable(enable);
- mChannelHeaderView.setFocusable(enable);
- }
- });
+
+ boolean accessibilityEnabled = mAccessibilityManager.isEnabled()
+ && !TvCommonUtils.isRunningInTest();
+ mDetailView.setFocusable(accessibilityEnabled);
+ mChannelHeaderView.setFocusable(accessibilityEnabled);
}
public void onBind(int position) {
onBindChannel(mProgramManager.getChannel(position));
mProgramRow.swapAdapter(mProgramListAdapters.get(position), true);
- mProgramRow.setProgramManager(mProgramManager);
+ mProgramRow.setProgramGuide(mProgramGuide);
mProgramRow.setChannel(mProgramManager.getChannel(position));
mProgramRow.setChildFocusListener(this);
mProgramRow.resetScroll(mProgramGuide.getTimelineRowScrollOffset());
@@ -416,24 +435,11 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
}
}
- public boolean isChild(View view) {
- if (view == null) {
- return false;
- }
- for (ViewParent p = view.getParent(); p != null; p = p.getParent()) {
- if (p == mContainer) {
- return true;
- }
- }
- return false;
- }
-
@Override
public void onChildFocus(View oldFocus, View newFocus) {
if (newFocus == null) {
return;
- }
- // When the accessibility service is enabled, focus might be put on channel's header or
+ } // When the accessibility service is enabled, focus might be put on channel's header or
// detail view, besides program items.
if (newFocus == mChannelHeaderView) {
mSelectedEntry = ((ProgramItemView) mProgramRow.getChildAt(0)).getTableEntry();
@@ -443,7 +449,15 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
mSelectedEntry = ((ProgramItemView) newFocus).getTableEntry();
}
if (oldFocus == null) {
- updateDetailView();
+ // Focus moved from other row.
+ if (mProgramGuide.getProgramGrid().isInLayout()) {
+ // We need to post runnable to avoid updating detail view when
+ // the recycler view is in layout, which may cause detail view not
+ // laid out according to the updated contents.
+ mHandler.post(mUpdateDetailViewRunnable);
+ } else {
+ updateDetailView();
+ }
return;
}
@@ -508,16 +522,6 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
});
}
- private void onAttachedToWindow() {
- mContainer.getViewTreeObserver()
- .addOnGlobalFocusChangeListener(mGlobalFocusChangeListener);
- }
-
- private void onDetachedFromWindow() {
- mContainer.getViewTreeObserver()
- .removeOnGlobalFocusChangeListener(mGlobalFocusChangeListener);
- }
-
private void updateDetailView() {
if (mSelectedEntry == null) {
// The view holder is never on focus before.
@@ -556,10 +560,8 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
program.getStartTimeUtcMillis(),
program.getEndTimeUtcMillis(), false));
- boolean trackMetaDataVisible = false;
- trackMetaDataVisible |=
- updateTextView(mAspectRatioView, Utils.getAspectRatioString(
- program.getVideoWidth(), program.getVideoHeight()));
+ boolean trackMetaDataVisible = updateTextView(mAspectRatioView, Utils
+ .getAspectRatioString(program.getVideoWidth(), program.getVideoHeight()));
int videoDefinitionLevel = Utils.getVideoDefinitionLevelFromSize(
program.getVideoWidth(), program.getVideoHeight());
@@ -658,7 +660,9 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
if (TextUtils.isEmpty(name)) {
return mContext.getString(R.string.program_guide_content_locked);
} else {
- return mContext.getString(R.string.program_guide_content_locked_format, name);
+ return TvContentRating.UNRATED.equals(blockedRating)
+ ? mContext.getString(R.string.program_guide_content_locked_unrated)
+ : mContext.getString(R.string.program_guide_content_locked_format, name);
}
}
@@ -666,7 +670,7 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
* Update tv input logo. It should be called when the visible child item in ProgramGrid
* changed.
*/
- public void updateInputLogo(int lastPosition, boolean forceShow) {
+ void updateInputLogo(int lastPosition, boolean forceShow) {
if (mChannel == null) {
mInputLogoView.setVisibility(View.GONE);
mIsInputLogoVisible = false;
@@ -731,7 +735,7 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
mInputLogoView.setVisibility(View.VISIBLE);
}
- private void updateCriticScoreView(ProgramRowHolder holder, final long programId,
+ private void updateCriticScoreView(ProgramRowViewHolder holder, final long programId,
CriticScore criticScore, View view) {
TextView criticScoreSource = (TextView) view.findViewById(R.id.critic_score_source);
TextView criticScoreText = (TextView) view.findViewById(R.id.critic_score_score);
@@ -759,11 +763,11 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
}
}
- private static ImageLoaderCallback<ProgramRowHolder> createCriticScoreLogoCallback(
- ProgramRowHolder holder, final long programId, ImageView logoView) {
- return new ImageLoaderCallback<ProgramRowHolder>(holder) {
+ private static ImageLoaderCallback<ProgramRowViewHolder> createCriticScoreLogoCallback(
+ ProgramRowViewHolder holder, final long programId, ImageView logoView) {
+ return new ImageLoaderCallback<ProgramRowViewHolder>(holder) {
@Override
- public void onBitmapLoaded(ProgramRowHolder holder, @Nullable Bitmap logoImage) {
+ public void onBitmapLoaded(ProgramRowViewHolder holder, @Nullable Bitmap logoImage) {
if (logoImage == null || holder.mSelectedEntry == null
|| holder.mSelectedEntry.program == null
|| holder.mSelectedEntry.program.getId() != programId) {
@@ -776,11 +780,11 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
};
}
- private static ImageLoaderCallback<ProgramRowHolder> createProgramPosterArtCallback(
- ProgramRowHolder holder, final Program program) {
- return new ImageLoaderCallback<ProgramRowHolder>(holder) {
+ private static ImageLoaderCallback<ProgramRowViewHolder> createProgramPosterArtCallback(
+ ProgramRowViewHolder holder, final Program program) {
+ return new ImageLoaderCallback<ProgramRowViewHolder>(holder) {
@Override
- public void onBitmapLoaded(ProgramRowHolder holder, @Nullable Bitmap posterArt) {
+ public void onBitmapLoaded(ProgramRowViewHolder holder, @Nullable Bitmap posterArt) {
if (posterArt == null || holder.mSelectedEntry == null
|| holder.mSelectedEntry.program == null) {
return;
@@ -794,11 +798,11 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
};
}
- private static ImageLoaderCallback<ProgramRowHolder> createChannelLogoLoadedCallback(
- ProgramRowHolder holder, final long channelId) {
- return new ImageLoaderCallback<ProgramRowHolder>(holder) {
+ private static ImageLoaderCallback<ProgramRowViewHolder> createChannelLogoLoadedCallback(
+ ProgramRowViewHolder holder, final long channelId) {
+ return new ImageLoaderCallback<ProgramRowViewHolder>(holder) {
@Override
- public void onBitmapLoaded(ProgramRowHolder holder, @Nullable Bitmap logo) {
+ public void onBitmapLoaded(ProgramRowViewHolder holder, @Nullable Bitmap logo) {
if (logo == null || holder.mChannel == null
|| holder.mChannel.getId() != channelId) {
return;
@@ -808,11 +812,11 @@ public class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapte
};
}
- private static ImageLoaderCallback<ProgramRowHolder> createTvInputLogoLoadedCallback(
- final TvInputInfo info, ProgramRowHolder holder) {
- return new ImageLoaderCallback<ProgramRowHolder>(holder) {
+ private static ImageLoaderCallback<ProgramRowViewHolder> createTvInputLogoLoadedCallback(
+ final TvInputInfo info, ProgramRowViewHolder holder) {
+ return new ImageLoaderCallback<ProgramRowViewHolder>(holder) {
@Override
- public void onBitmapLoaded(ProgramRowHolder holder, @Nullable Bitmap logo) {
+ public void onBitmapLoaded(ProgramRowViewHolder holder, @Nullable Bitmap logo) {
if (logo != null && holder.mChannel != null && info.getId()
.equals(holder.mChannel.getInputId())) {
holder.updateInputLogoInternal(logo);
diff --git a/src/com/android/tv/guide/TimeListAdapter.java b/src/com/android/tv/guide/TimeListAdapter.java
index 868fed46..d9e96a40 100644
--- a/src/com/android/tv/guide/TimeListAdapter.java
+++ b/src/com/android/tv/guide/TimeListAdapter.java
@@ -16,6 +16,7 @@
package com.android.tv.guide;
+import android.content.Context;
import android.content.res.Resources;
import android.support.v7.widget.RecyclerView;
import android.text.format.DateFormat;
@@ -25,26 +26,40 @@ import android.view.ViewGroup;
import android.widget.TextView;
import com.android.tv.R;
+import com.android.tv.util.Utils;
import java.util.Date;
+import java.util.Locale;
import java.util.concurrent.TimeUnit;
/**
* Adapts the time range from {@link ProgramManager} to the timeline header row of the program
* guide table.
*/
-public class TimeListAdapter extends RecyclerView.Adapter<TimeListAdapter.TimeViewHolder> {
+class TimeListAdapter extends RecyclerView.Adapter<TimeListAdapter.TimeViewHolder> {
private static final long TIME_UNIT_MS = TimeUnit.MINUTES.toMillis(30);
+
+ // Ex. 3:00 AM
+ private static final String TIME_PATTERN_SAME_DAY = "h:mm a";
+ // Ex. Oct 21, 3:00 AM
+ private static final String TIME_PATTERN_DIFFERENT_DAY = "MMM d, h:mm a";
+
private static int sRowHeaderOverlapping;
// Nearest half hour at or before the start time.
private long mStartUtcMs;
+ private final String mTimePatternSameDay;
+ private final String mTimePatternDifferentDay;
- public TimeListAdapter(Resources res) {
+ TimeListAdapter(Resources res) {
if (sRowHeaderOverlapping == 0) {
sRowHeaderOverlapping = Math.abs(res.getDimensionPixelOffset(
R.dimen.program_guide_table_header_row_overlap));
}
+ Locale locale = res.getConfiguration().locale;
+ mTimePatternSameDay = DateFormat.getBestDateTimePattern(locale, TIME_PATTERN_SAME_DAY);
+ mTimePatternDifferentDay =
+ DateFormat.getBestDateTimePattern(locale, TIME_PATTERN_DIFFERENT_DAY);
}
public void update(long startTimeMs) {
@@ -68,10 +83,14 @@ public class TimeListAdapter extends RecyclerView.Adapter<TimeListAdapter.TimeVi
long endTime = startTime + TIME_UNIT_MS;
View itemView = holder.itemView;
-
- TextView textView = (TextView) itemView.findViewById(R.id.time);
- String time = DateFormat.getTimeFormat(itemView.getContext()).format(new Date(startTime));
- textView.setText(time);
+ Date timeDate = new Date(startTime);
+ String timeString;
+ if (Utils.isInGivenDay(System.currentTimeMillis(), startTime)) {
+ timeString = DateFormat.format(mTimePatternSameDay, timeDate).toString();
+ } else {
+ timeString = DateFormat.format(mTimePatternDifferentDay, timeDate).toString();
+ }
+ ((TextView) itemView.findViewById(R.id.time)).setText(timeString);
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) itemView.getLayoutParams();
lp.width = GuideUtils.convertMillisToPixel(startTime, endTime);
@@ -90,8 +109,8 @@ public class TimeListAdapter extends RecyclerView.Adapter<TimeListAdapter.TimeVi
return new TimeViewHolder(itemView);
}
- public static class TimeViewHolder extends RecyclerView.ViewHolder {
- public TimeViewHolder(View itemView) {
+ static class TimeViewHolder extends RecyclerView.ViewHolder {
+ TimeViewHolder(View itemView) {
super(itemView);
}
}
diff --git a/src/com/android/tv/license/License.java b/src/com/android/tv/license/License.java
new file mode 100644
index 00000000..c1cbd09e
--- /dev/null
+++ b/src/com/android/tv/license/License.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 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.tv.license;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Container class to store the name of a library and the filename of its associated license file.
+ */
+public final class License implements Comparable<License>, Parcelable {
+ // Name of the third-party library.
+ private final String mLibraryName;
+ // Byte offset in the file to the start of the license text.
+ private final long mLicenseOffset;
+ // Byte length of the license text.
+ private final int mLicenseLength;
+ // Path to the archive that has bundled licenses.
+ // Empty string if the license is bundled in the apk itself.
+ private final String mPath;
+
+ /**
+ * Create an object representing a stored license. The text for all licenses is stored in a
+ * single file, so the offset and length describe this license's position within the file.
+ *
+ * @param path a path to an .apk-compatible archive that contains the license. An empty string
+ * in case the license is contained within the app itself.
+ */
+ static License create(String libraryName, long licenseOffset, int licenseLength, String path) {
+ return new License(libraryName, licenseOffset, licenseLength, path);
+ }
+
+ public static final Parcelable.Creator<License> CREATOR =
+ new Parcelable.Creator<License>() {
+ @Override
+ public License createFromParcel(Parcel in) {
+ return new License(in);
+ }
+
+ @Override
+ public License[] newArray(int size) {
+ return new License[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mLibraryName);
+ dest.writeLong(mLicenseOffset);
+ dest.writeInt(mLicenseLength);
+ dest.writeString(mPath);
+ }
+
+ @Override
+ public int compareTo(License o) {
+ return mLibraryName.compareToIgnoreCase(o.getLibraryName());
+ }
+
+ @Override
+ public String toString() {
+ return getLibraryName();
+ }
+
+ private License(String libraryName, long licenseOffset, int licenseLength, String path) {
+ this.mLibraryName = libraryName;
+ this.mLicenseOffset = licenseOffset;
+ this.mLicenseLength = licenseLength;
+ this.mPath = path;
+ }
+
+ private License(Parcel in) {
+ mLibraryName = in.readString();
+ mLicenseOffset = in.readLong();
+ mLicenseLength = in.readInt();
+ mPath = in.readString();
+ }
+
+ String getLibraryName() {
+ return mLibraryName;
+ }
+
+ long getLicenseOffset() {
+ return mLicenseOffset;
+ }
+
+ int getLicenseLength() {
+ return mLicenseLength;
+ }
+
+ public String getPath() {
+ return mPath;
+ }
+}
diff --git a/src/com/android/tv/license/LicenseDialogFragment.java b/src/com/android/tv/license/LicenseDialogFragment.java
new file mode 100644
index 00000000..b0e09776
--- /dev/null
+++ b/src/com/android/tv/license/LicenseDialogFragment.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 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.tv.license;
+
+import android.app.DialogFragment;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.text.method.ScrollingMovementMethod;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.TextView;
+
+import com.android.tv.R;
+import com.android.tv.dialog.SafeDismissDialogFragment;
+
+/** A DialogFragment that shows a License in a text view. */
+public class LicenseDialogFragment extends SafeDismissDialogFragment {
+ public static final String DIALOG_TAG = LicenseDialogFragment.class.getSimpleName();
+
+ private static final String LICENSE = "LICENSE";
+
+ private License mLicense;
+ private String mTrackerLabel;
+
+ /**
+ * Create a new LicenseDialogFragment to show a particular license.
+ *
+ * @param license The License to show.
+ */
+ public static LicenseDialogFragment newInstance(License license) {
+ LicenseDialogFragment f = new LicenseDialogFragment();
+ Bundle args = new Bundle();
+ args.putParcelable(LICENSE, license);
+ f.setArguments(args);
+ return f;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mLicense = getArguments().getParcelable(LICENSE);
+ String title = mLicense.getLibraryName();
+ mTrackerLabel = getArguments().getString(title + "_license");
+ int style =
+ TextUtils.isEmpty(title)
+ ? DialogFragment.STYLE_NO_TITLE
+ : DialogFragment.STYLE_NORMAL;
+ setStyle(style, 0);
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ TextView textView = new TextView(getActivity());
+ String licenseText = Licenses.getLicenseText(getContext(), mLicense);
+ textView.setText(licenseText != null ? licenseText : "");
+ textView.setMovementMethod(new ScrollingMovementMethod());
+ int verticalOverscan =
+ getResources().getDimensionPixelSize(R.dimen.vertical_overscan_safe_margin);
+ int horizontalOverscan =
+ getResources().getDimensionPixelSize(R.dimen.horizontal_overscan_safe_margin);
+ textView.setPadding(
+ horizontalOverscan, verticalOverscan, horizontalOverscan, verticalOverscan);
+ return textView;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ // Ensure the dialog is fullscreen, even if the TextView doesn't have its content yet.
+ getDialog().getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+ getDialog().setTitle(mLicense.getLibraryName());
+ }
+
+ @Override
+ public String getTrackerLabel() {
+ return mTrackerLabel;
+ }
+}
diff --git a/src/com/android/tv/license/LicenseSideFragment.java b/src/com/android/tv/license/LicenseSideFragment.java
new file mode 100644
index 00000000..fd92467c
--- /dev/null
+++ b/src/com/android/tv/license/LicenseSideFragment.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 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.tv.license;
+
+import android.content.Context;
+
+import com.android.tv.R;
+import com.android.tv.ui.sidepanel.ActionItem;
+import com.android.tv.ui.sidepanel.SideFragment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Opens a dialog showing open source licenses. */
+public final class LicenseSideFragment extends SideFragment {
+
+ public static final String TRACKER_LABEL = "Open Source Licenses";
+
+ public class LicenseActionItem extends ActionItem {
+ private final License license;
+
+ public LicenseActionItem(License license) {
+ super(license.getLibraryName());
+ this.license = license;
+ }
+
+ @Override
+ protected void onSelected() {
+ LicenseDialogFragment dialog = LicenseDialogFragment.newInstance(license);
+ getMainActivity()
+ .getOverlayManager()
+ .showDialogFragment(LicenseDialogFragment.DIALOG_TAG, dialog, true);
+ }
+ }
+
+ private List<LicenseActionItem> licenses;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ licenses = toActionItems(Licenses.getLicenses(context));
+ }
+
+ private List<LicenseActionItem> toActionItems(ArrayList<License> licenses) {
+ List<LicenseActionItem> items = new ArrayList<>(licenses.size());
+ for (License license : licenses) {
+ items.add(new LicenseActionItem(license));
+ }
+ return items;
+ }
+
+ @Override
+ protected String getTitle() {
+ return getResources().getString(R.string.settings_menu_licenses);
+ }
+
+ @Override
+ public String getTrackerLabel() {
+ return TRACKER_LABEL;
+ }
+
+ @Override
+ protected List<LicenseActionItem> getItemList() {
+ return licenses;
+ }
+}
diff --git a/src/com/android/tv/license/LicenseUtils.java b/src/com/android/tv/license/LicenseUtils.java
index b972aad6..cf3fe751 100644
--- a/src/com/android/tv/license/LicenseUtils.java
+++ b/src/com/android/tv/license/LicenseUtils.java
@@ -26,21 +26,9 @@ import java.io.InputStream;
* Utilities for showing open source licenses.
*/
public final class LicenseUtils {
- public final static String LICENSE_FILE = "file:///android_asset/licenses.html";
public final static String RATING_SOURCE_FILE =
"file:///android_asset/rating_sources.html";
- private final static File licenseFile = new File(LICENSE_FILE);
- /**
- * Checks if the license.html asset is include in the apk.
- */
- public static boolean hasLicenses(AssetManager am) {
- try (InputStream is = am.open("licenses.html")) {
- return true;
- } catch (IOException e) {
- return false;
- }
- }
/**
* Checks if the rating_attribution.html asset is include in the apk.
diff --git a/src/com/android/tv/license/Licenses.java b/src/com/android/tv/license/Licenses.java
new file mode 100644
index 00000000..4b8a7ffc
--- /dev/null
+++ b/src/com/android/tv/license/Licenses.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 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.tv.license;
+
+import android.content.Context;
+import android.support.annotation.RawRes;
+
+import com.android.tv.R;
+import com.android.tv.common.SoftPreconditions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * A helper for extracting licenses embedded using
+ * third_party_licenses.build:third_party_licenses().
+ */
+public final class Licenses {
+
+ public static final String TAG = "Licenses";
+ public static boolean hasLicenses(Context context) {
+ return !getTextFromResource(
+ context.getApplicationContext(), R.raw.third_party_license_metadata, 0, -1)
+ .isEmpty();
+ }
+
+ /** Return the licenses bundled into this app. */
+ public static ArrayList<License> getLicenses(Context context) {
+ return getLicenseListFromMetadata(
+ getTextFromResource(
+ context.getApplicationContext(), R.raw.third_party_license_metadata, 0, -1),
+ "");
+ }
+
+ /**
+ * Returns a list of {@link License}s parsed from a license metadata file.
+ *
+ * @param metadata a {@code String} containing the contents of a license metadata file.
+ * @param filePath a path to a package archive with licenses or empty string for the app package
+ */
+ private static ArrayList<License> getLicenseListFromMetadata(String metadata, String filePath) {
+ String[] entries = metadata.split("\n");
+ ArrayList<License> licenses = new ArrayList<License>(entries.length);
+ for (String entry : entries) {
+ int delimiter = entry.indexOf(' ');
+ String[] licenseLocation = entry.substring(0, delimiter).split(":");
+ SoftPreconditions.checkState(
+ licenseLocation.length == 2 && delimiter > 0,
+ TAG,
+ "Invalid license meta-data line:\n" + entry);
+ long licenseOffset = Long.parseLong(licenseLocation[0]);
+ int licenseLength = Integer.parseInt(licenseLocation[1]);
+ licenses.add(
+ License.create(
+ entry.substring(delimiter + 1),
+ licenseOffset,
+ licenseLength,
+ filePath));
+ }
+ Collections.sort(licenses);
+ return licenses;
+ }
+
+ /** Return the text of a bundled license file. */
+ public static String getLicenseText(Context context, License license) {
+ long offset = license.getLicenseOffset();
+ int length = license.getLicenseLength();
+ return getTextFromResource(context, R.raw.third_party_licenses, offset, length);
+ }
+
+ private static String getTextFromResource(
+ Context context, @RawRes int resourcesIdentifier, long offset, int length) {
+ InputStream stream =
+ context.getApplicationContext().getResources().openRawResource(resourcesIdentifier);
+ return getTextFromInputStream(stream, offset, length);
+ }
+
+ private static String getTextFromInputStream(InputStream stream, long offset, int length) {
+ byte[] buffer = new byte[1024];
+ ByteArrayOutputStream textArray = new ByteArrayOutputStream();
+
+ try {
+ stream.skip(offset);
+ int bytesRemaining = length > 0 ? length : Integer.MAX_VALUE;
+ int bytes = 0;
+
+ while (bytesRemaining > 0
+ && (bytes = stream.read(buffer, 0, Math.min(bytesRemaining, buffer.length)))
+ != -1) {
+ textArray.write(buffer, 0, bytes);
+ bytesRemaining -= bytes;
+ }
+ stream.close();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to read license or metadata text.", e);
+ }
+ try {
+ return textArray.toString("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(
+ "Unsupported encoding UTF8. This should always be supported.", e);
+ }
+ }
+}
diff --git a/src/com/android/tv/menu/ActionCardView.java b/src/com/android/tv/menu/ActionCardView.java
index 54892cac..2fd70bfb 100644
--- a/src/com/android/tv/menu/ActionCardView.java
+++ b/src/com/android/tv/menu/ActionCardView.java
@@ -19,8 +19,8 @@ package com.android.tv.menu;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
-import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.tv.R;
@@ -28,7 +28,7 @@ import com.android.tv.R;
/**
* A view to render an item of TV options.
*/
-public class ActionCardView extends FrameLayout implements ItemListRowView.CardView<MenuAction> {
+public class ActionCardView extends RelativeLayout implements ItemListRowView.CardView<MenuAction> {
private static final String TAG = MenuView.TAG;
private static final boolean DEBUG = MenuView.DEBUG;
@@ -66,7 +66,7 @@ public class ActionCardView extends FrameLayout implements ItemListRowView.CardV
}
mIconView.setImageDrawable(action.getDrawable(getContext()));
mLabelView.setText(action.getActionName(getContext()));
- mStateView.setText(action.getActionDescription(getContext()));
+ mStateView.setText(action.getActionDescription());
if (action.isEnabled()) {
setEnabled(true);
setFocusable(true);
diff --git a/src/com/android/tv/menu/AppLinkCardView.java b/src/com/android/tv/menu/AppLinkCardView.java
index bfb5e3f1..94ccd37f 100644
--- a/src/com/android/tv/menu/AppLinkCardView.java
+++ b/src/com/android/tv/menu/AppLinkCardView.java
@@ -24,6 +24,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
import android.support.annotation.Nullable;
import android.support.v7.graphics.Palette;
import android.text.TextUtils;
@@ -40,10 +41,12 @@ import com.android.tv.util.BitmapUtils;
import com.android.tv.util.ImageLoader;
import com.android.tv.util.TvInputManagerHelper;
+import java.util.Objects;
+
/**
* A view to render an app link card.
*/
-public class AppLinkCardView extends BaseCardView<Channel> {
+public class AppLinkCardView extends BaseCardView<ChannelsRowItem> {
private static final String TAG = MenuView.TAG;
private static final boolean DEBUG = MenuView.DEBUG;
@@ -53,9 +56,9 @@ public class AppLinkCardView extends BaseCardView<Channel> {
private final int mIconHeight;
private final int mIconPadding;
private final int mIconColorFilter;
+ private final Drawable mDefaultDrawable;
private ImageView mImageView;
- private View mGradientView;
private TextView mAppInfoView;
private View mMetaViewHolder;
private Channel mChannel;
@@ -82,6 +85,7 @@ public class AppLinkCardView extends BaseCardView<Channel> {
mPackageManager = context.getPackageManager();
mTvInputManagerHelper = ((MainActivity) context).getTvInputManagerHelper();
mIconColorFilter = getResources().getColor(R.color.app_link_card_icon_color_filter, null);
+ mDefaultDrawable = getResources().getDrawable(R.drawable.ic_recent_thumbnail_default, null);
}
/**
@@ -92,65 +96,153 @@ public class AppLinkCardView extends BaseCardView<Channel> {
}
@Override
- public void onBind(Channel channel, boolean selected) {
+ public void onBind(ChannelsRowItem item, boolean selected) {
+ Channel newChannel = item.getChannel();
+ boolean channelChanged = !Objects.equals(mChannel, newChannel);
+ String previousPosterArtUri = mChannel == null ? null : mChannel.getAppLinkPosterArtUri();
+ boolean posterArtChanged = previousPosterArtUri == null
+ || newChannel.getAppLinkPosterArtUri() == null
+ || !TextUtils.equals(previousPosterArtUri, newChannel.getAppLinkPosterArtUri());
+ mChannel = newChannel;
if (DEBUG) {
- Log.d(TAG, "onBind(channelName=" + channel.getDisplayName() + ", selected=" + selected
+ Log.d(TAG, "onBind(channelName=" + mChannel.getDisplayName() + ", selected=" + selected
+ ")");
}
- mChannel = channel;
ApplicationInfo appInfo = mTvInputManagerHelper.getTvInputAppInfo(mChannel.getInputId());
- int linkType = mChannel.getAppLinkType(getContext());
- mIntent = mChannel.getAppLinkIntent(getContext());
+ if (channelChanged) {
+ int linkType = mChannel.getAppLinkType(getContext());
+ mIntent = mChannel.getAppLinkIntent(getContext());
- switch (linkType) {
- case Channel.APP_LINK_TYPE_CHANNEL:
- setText(mChannel.getAppLinkText());
- mAppInfoView.setVisibility(VISIBLE);
- mGradientView.setVisibility(VISIBLE);
- mAppInfoView.setCompoundDrawablePadding(mIconPadding);
- mAppInfoView.setCompoundDrawables(null, null, null, null);
- mAppInfoView.setText(mPackageManager.getApplicationLabel(appInfo));
- if (!TextUtils.isEmpty(mChannel.getAppLinkIconUri())) {
- mChannel.loadBitmap(getContext(), Channel.LOAD_IMAGE_TYPE_APP_LINK_ICON,
- mIconWidth, mIconHeight, createChannelLogoCallback(this, mChannel,
- Channel.LOAD_IMAGE_TYPE_APP_LINK_ICON));
- } else if (appInfo.icon != 0) {
- Drawable appIcon = mPackageManager.getApplicationIcon(appInfo);
- BitmapUtils.setColorFilterToDrawable(mIconColorFilter, appIcon);
- appIcon.setBounds(0, 0, mIconWidth, mIconHeight);
- mAppInfoView.setCompoundDrawables(appIcon, null, null, null);
- }
- break;
- case Channel.APP_LINK_TYPE_APP:
- setText(getContext().getString(
- R.string.channels_item_app_link_app_launcher,
- mPackageManager.getApplicationLabel(appInfo)));
- mAppInfoView.setVisibility(GONE);
- mGradientView.setVisibility(GONE);
- break;
- default:
- mAppInfoView.setVisibility(GONE);
- mGradientView.setVisibility(GONE);
- Log.d(TAG, "Should not be here.");
- }
+ CharSequence appLabel;
+ switch (linkType) {
+ case Channel.APP_LINK_TYPE_CHANNEL:
+ setText(mChannel.getAppLinkText());
+ mAppInfoView.setVisibility(VISIBLE);
+ mAppInfoView.setCompoundDrawablePadding(mIconPadding);
+ mAppInfoView.setCompoundDrawablesRelative(null, null, null, null);
+ appLabel = mTvInputManagerHelper
+ .getTvInputApplicationLabel(mChannel.getInputId());
+ if (appLabel != null) {
+ mAppInfoView.setText(appLabel);
+ } else {
+ new AsyncTask<Void, Void, CharSequence>() {
+ private final String mLoadTvInputId = mChannel.getInputId();
- if (mChannel.getAppLinkColor() == 0) {
- mMetaViewHolder.setBackgroundResource(R.color.channel_card_meta_background);
- } else {
- mMetaViewHolder.setBackgroundColor(mChannel.getAppLinkColor());
- }
+ @Override
+ protected CharSequence doInBackground(Void... params) {
+ if (appInfo != null) {
+ return mPackageManager.getApplicationLabel(appInfo);
+ }
+ return null;
+ }
- if (!TextUtils.isEmpty(mChannel.getAppLinkPosterArtUri())) {
- mImageView.setImageResource(R.drawable.ic_recent_thumbnail_default);
- mChannel.loadBitmap(getContext(), Channel.LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART,
- mCardImageWidth, mCardImageHeight, createChannelLogoCallback(this, mChannel,
- Channel.LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART));
- } else {
- setCardImageWithBanner(appInfo);
+ @Override
+ protected void onPostExecute(CharSequence appLabel) {
+ mTvInputManagerHelper.setTvInputApplicationLabel(
+ mLoadTvInputId, appLabel);
+ if (mLoadTvInputId != mChannel.getInputId()
+ || !isAttachedToWindow()) {
+ return;
+ }
+ mAppInfoView.setText(appLabel);
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ if (!TextUtils.isEmpty(mChannel.getAppLinkIconUri())) {
+ mChannel.loadBitmap(getContext(), Channel.LOAD_IMAGE_TYPE_APP_LINK_ICON,
+ mIconWidth, mIconHeight, createChannelLogoCallback(
+ this, mChannel, Channel.LOAD_IMAGE_TYPE_APP_LINK_ICON));
+ } else if (appInfo.icon != 0) {
+ Drawable appIcon = mTvInputManagerHelper
+ .getTvInputApplicationIcon(mChannel.getInputId());
+ if (appIcon != null) {
+ BitmapUtils.setColorFilterToDrawable(mIconColorFilter, appIcon);
+ appIcon.setBounds(0, 0, mIconWidth, mIconHeight);
+ mAppInfoView.setCompoundDrawablesRelative(appIcon, null, null, null);
+ } else {
+ new AsyncTask<Void, Void, Drawable>() {
+ private final String mLoadTvInputId = mChannel.getInputId();
+
+ @Override
+ protected Drawable doInBackground(Void... params) {
+ return mPackageManager.getApplicationIcon(appInfo);
+ }
+
+ @Override
+ protected void onPostExecute(Drawable appIcon) {
+ mTvInputManagerHelper.setTvInputApplicationIcon(
+ mLoadTvInputId, appIcon);
+ if (!mLoadTvInputId.equals(mChannel.getInputId())
+ || !isAttachedToWindow()) {
+ return;
+ }
+ BitmapUtils.setColorFilterToDrawable(mIconColorFilter, appIcon);
+ appIcon.setBounds(0, 0, mIconWidth, mIconHeight);
+ mAppInfoView.setCompoundDrawablesRelative(
+ appIcon, null, null, null);
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ }
+ break;
+ case Channel.APP_LINK_TYPE_APP:
+ appLabel = mTvInputManagerHelper
+ .getTvInputApplicationLabel(mChannel.getInputId());
+ if (appLabel != null) {
+ setText(getContext()
+ .getString(R.string.channels_item_app_link_app_launcher, appLabel));
+ } else {
+ new AsyncTask<Void, Void, CharSequence>() {
+ private final String mLoadTvInputId = mChannel.getInputId();
+
+ @Override
+ protected CharSequence doInBackground(Void... params) {
+ if (appInfo != null) {
+ return mPackageManager.getApplicationLabel(appInfo);
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(CharSequence appLabel) {
+ mTvInputManagerHelper.setTvInputApplicationLabel(
+ mLoadTvInputId, appLabel);
+ if (!mLoadTvInputId.equals(mChannel.getInputId())
+ || !isAttachedToWindow()) {
+ return;
+ }
+ setText(getContext()
+ .getString(
+ R.string.channels_item_app_link_app_launcher,
+ appLabel));
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ mAppInfoView.setVisibility(GONE);
+ break;
+ default:
+ mAppInfoView.setVisibility(GONE);
+ Log.d(TAG, "Should not be here.");
+ }
+
+ if (mChannel.getAppLinkColor() == 0) {
+ mMetaViewHolder.setBackgroundResource(R.color.channel_card_meta_background);
+ } else {
+ mMetaViewHolder.setBackgroundColor(mChannel.getAppLinkColor());
+ }
}
- // Call super.onBind() at the end intentionally. In order to correctly handle extension of
- // text view, text should be set before calling super.onBind.
- super.onBind(channel, selected);
+ if (posterArtChanged) {
+ mImageView.setImageDrawable(mDefaultDrawable);
+ mImageView.setForeground(null);
+ if (!TextUtils.isEmpty(mChannel.getAppLinkPosterArtUri())) {
+ mChannel.loadBitmap(getContext(), Channel.LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART,
+ mCardImageWidth, mCardImageHeight, createChannelLogoCallback(this, mChannel,
+ Channel.LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART));
+ } else {
+ setCardImageWithBanner(appInfo);
+ }
+ }
+ super.onBind(item, selected);
}
private static ImageLoader.ImageLoaderCallback<AppLinkCardView> createChannelLogoCallback(
@@ -182,13 +274,14 @@ public class AppLinkCardView extends BaseCardView<Channel> {
}
}
BitmapUtils.setColorFilterToDrawable(mIconColorFilter, drawable);
- mAppInfoView.setCompoundDrawables(drawable, null, null, null);
+ mAppInfoView.setCompoundDrawablesRelative(drawable, null, null, null);
} else if (type == Channel.LOAD_IMAGE_TYPE_APP_LINK_POSTER_ART) {
if (bitmap == null) {
setCardImageWithBanner(
mTvInputManagerHelper.getTvInputAppInfo(mChannel.getInputId()));
} else {
mImageView.setImageBitmap(bitmap);
+ mImageView.setForeground(getContext().getDrawable(R.drawable.card_image_gradient));
if (mChannel.getAppLinkColor() == 0) {
extractAndSetMetaViewBackgroundColor(bitmap);
}
@@ -200,7 +293,6 @@ public class AppLinkCardView extends BaseCardView<Channel> {
protected void onFinishInflate() {
super.onFinishInflate();
mImageView = (ImageView) findViewById(R.id.image);
- mGradientView = findViewById(R.id.image_gradient);
mAppInfoView = (TextView) findViewById(R.id.app_info);
mMetaViewHolder = findViewById(R.id.app_link_text_holder);
}
@@ -209,37 +301,85 @@ public class AppLinkCardView extends BaseCardView<Channel> {
// 1) Provided poster art image, 2) Activity banner, 3) Activity icon, 4) Application banner,
// 5) Application icon, and 6) default image.
private void setCardImageWithBanner(ApplicationInfo appInfo) {
- Drawable banner = null;
- if (mIntent != null) {
- try {
- banner = mPackageManager.getActivityBanner(mIntent);
- if (banner == null) {
- banner = mPackageManager.getActivityIcon(mIntent);
+ new AsyncTask<Void, Void, Drawable>() {
+ private String mLoadTvInputId = mChannel.getInputId();
+ @Override
+ protected Drawable doInBackground(Void... params) {
+ Drawable banner = null;
+ if (mIntent != null) {
+ try {
+ banner = mPackageManager.getActivityBanner(mIntent);
+ if (banner == null) {
+ banner = mPackageManager.getActivityIcon(mIntent);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // do nothing.
+ }
}
- } catch (PackageManager.NameNotFoundException e) {
- // do nothing.
+ return banner;
}
- }
- if (banner == null && appInfo != null) {
- if (appInfo.banner != 0) {
- banner = mPackageManager.getApplicationBanner(appInfo);
- }
- if (banner == null && appInfo.icon != 0) {
- banner = mPackageManager.getApplicationIcon(appInfo);
+ @Override
+ protected void onPostExecute(Drawable banner) {
+ if (mLoadTvInputId != mChannel.getInputId() || !isAttachedToWindow()) {
+ return;
+ }
+ if (banner != null) {
+ setCardImageWithBannerInternal(banner);
+ } else {
+ setCardImageWithApplicationInfoBanner(appInfo);
+ }
}
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ private void setCardImageWithApplicationInfoBanner(ApplicationInfo appInfo) {
+ Drawable appBanner =
+ mTvInputManagerHelper.getTvInputApplicationBanner(mChannel.getInputId());
+ if (appBanner != null) {
+ setCardImageWithBannerInternal(appBanner);
+ } else {
+ new AsyncTask<Void, Void, Drawable>() {
+ private final String mLoadTvInputId = mChannel.getInputId();
+ @Override
+ protected Drawable doInBackground(Void... params) {
+ Drawable banner = null;
+ if (appInfo != null) {
+ if (appInfo.banner != 0) {
+ banner = mPackageManager.getApplicationBanner(appInfo);
+ }
+ if (banner == null && appInfo.icon != 0) {
+ banner = mPackageManager.getApplicationIcon(appInfo);
+ }
+ }
+ return banner;
+ }
+
+ @Override
+ protected void onPostExecute(Drawable banner) {
+ mTvInputManagerHelper.setTvInputApplicationBanner(mLoadTvInputId, banner);
+ if (!TextUtils.equals(mLoadTvInputId, mChannel.getInputId())
+ || !isAttachedToWindow()) {
+ return;
+ }
+ setCardImageWithBannerInternal(banner);
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
+ }
+ private void setCardImageWithBannerInternal(Drawable banner) {
if (banner == null) {
- mImageView.setImageResource(R.drawable.ic_recent_thumbnail_default);
+ mImageView.setImageDrawable(mDefaultDrawable);
mImageView.setBackgroundResource(R.color.channel_card);
} else {
- Bitmap bitmap =
- Bitmap.createBitmap(mCardImageWidth, mCardImageHeight, Bitmap.Config.ARGB_8888);
+ Bitmap bitmap = Bitmap.createBitmap(
+ mCardImageWidth, mCardImageHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
banner.setBounds(0, 0, mCardImageWidth, mCardImageHeight);
banner.draw(canvas);
mImageView.setImageDrawable(banner);
+ mImageView.setForeground(getContext().getDrawable(R.drawable.card_image_gradient));
if (mChannel.getAppLinkColor() == 0) {
extractAndSetMetaViewBackgroundColor(bitmap);
}
diff --git a/src/com/android/tv/menu/BaseCardView.java b/src/com/android/tv/menu/BaseCardView.java
index c6a34a5d..4c5e6c78 100644
--- a/src/com/android/tv/menu/BaseCardView.java
+++ b/src/com/android/tv/menu/BaseCardView.java
@@ -22,6 +22,7 @@ import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Outline;
import android.support.annotation.Nullable;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
@@ -35,9 +36,6 @@ import com.android.tv.R;
* A base class to render a card.
*/
public abstract class BaseCardView<T> extends LinearLayout implements ItemListRowView.CardView<T> {
- private static final String TAG = "BaseCardView";
- private static final boolean DEBUG = false;
-
private static final float SCALE_FACTOR_0F = 0f;
private static final float SCALE_FACTOR_1F = 1f;
@@ -57,6 +55,11 @@ public abstract class BaseCardView<T> extends LinearLayout implements ItemListRo
private TextView mTextViewFocused;
private final int mCardImageWidth;
private final float mCardHeight;
+ private boolean mSelected;
+
+ private int mTextResId;
+ private String mTextString;
+ private boolean mTextChanged;
public BaseCardView(Context context) {
this(context, null);
@@ -103,23 +106,9 @@ public abstract class BaseCardView<T> extends LinearLayout implements ItemListRo
/**
* Called when the view is displayed.
- *
- * Before onBind is called, this view's text should be set to determine if it'll be extended
- * or not in focus state.
*/
@Override
public void onBind(T item, boolean selected) {
- if (mTextView != null && mTextViewFocused != null) {
- mTextViewFocused.measure(
- MeasureSpec.makeMeasureSpec(mCardImageWidth, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
- mExtendViewOnFocus = mTextViewFocused.getLineCount() > 1;
- if (mExtendViewOnFocus) {
- setTextViewFocusedAlpha(selected ? 1f : 0f);
- } else {
- setTextViewFocusedAlpha(1f);
- }
- }
setFocusAnimatedValue(selected ? SCALE_FACTOR_1F : SCALE_FACTOR_0F);
}
@@ -128,6 +117,7 @@ public abstract class BaseCardView<T> extends LinearLayout implements ItemListRo
@Override
public void onSelected() {
+ mSelected = true;
if (isAttachedToWindow() && getVisibility() == View.VISIBLE) {
startFocusAnimation(SCALE_FACTOR_1F);
} else {
@@ -138,6 +128,7 @@ public abstract class BaseCardView<T> extends LinearLayout implements ItemListRo
@Override
public void onDeselected() {
+ mSelected = false;
if (isAttachedToWindow() && getVisibility() == View.VISIBLE) {
startFocusAnimation(SCALE_FACTOR_0F);
} else {
@@ -150,11 +141,17 @@ public abstract class BaseCardView<T> extends LinearLayout implements ItemListRo
* Sets text of this card view.
*/
public void setText(int resId) {
- if (mTextViewFocused != null) {
- mTextViewFocused.setText(resId);
- }
- if (mTextView != null) {
- mTextView.setText(resId);
+ if (mTextResId != resId) {
+ mTextResId = resId;
+ mTextString = null;
+ mTextChanged = true;
+ if (mTextViewFocused != null) {
+ mTextViewFocused.setText(resId);
+ }
+ if (mTextView != null) {
+ mTextView.setText(resId);
+ }
+ onTextViewUpdated();
}
}
@@ -162,12 +159,33 @@ public abstract class BaseCardView<T> extends LinearLayout implements ItemListRo
* Sets text of this card view.
*/
public void setText(String text) {
- if (mTextViewFocused != null) {
- mTextViewFocused.setText(text);
+ if (!TextUtils.equals(text, mTextString)) {
+ mTextString = text;
+ mTextResId = 0;
+ mTextChanged = true;
+ if (mTextViewFocused != null) {
+ mTextViewFocused.setText(text);
+ }
+ if (mTextView != null) {
+ mTextView.setText(text);
+ }
+ onTextViewUpdated();
}
- if (mTextView != null) {
- mTextView.setText(text);
+ }
+
+ private void onTextViewUpdated() {
+ if (mTextView != null && mTextViewFocused != null) {
+ mTextViewFocused.measure(
+ MeasureSpec.makeMeasureSpec(mCardImageWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ mExtendViewOnFocus = mTextViewFocused.getLineCount() > 1;
+ if (mExtendViewOnFocus) {
+ setTextViewFocusedAlpha(mSelected ? 1f : 0f);
+ } else {
+ setTextViewFocusedAlpha(1f);
+ }
}
+ setFocusAnimatedValue(mSelected ? SCALE_FACTOR_1F : SCALE_FACTOR_0F);
}
/**
@@ -209,12 +227,18 @@ public abstract class BaseCardView<T> extends LinearLayout implements ItemListRo
setScaleX(scale);
setScaleY(scale);
setTranslationZ(mFocusTranslationZ * animatedValue);
- if (mExtendViewOnFocus) {
+ if (mTextView != null && mTextViewFocused != null) {
ViewGroup.LayoutParams params = mTextView.getLayoutParams();
- params.height = Math.round(mTextViewHeight
- + (mExtendedTextViewHeight - mTextViewHeight) * animatedValue);
- setTextViewLayoutParams(params);
- setTextViewFocusedAlpha(animatedValue);
+ int height = mExtendViewOnFocus ? Math.round(mTextViewHeight
+ + (mExtendedTextViewHeight - mTextViewHeight) * animatedValue)
+ : (int) mTextViewHeight;
+ if (height != params.height) {
+ params.height = height;
+ setTextViewLayoutParams(params);
+ }
+ if (mExtendViewOnFocus) {
+ setTextViewFocusedAlpha(animatedValue);
+ }
}
}
diff --git a/src/com/android/tv/menu/ChannelCardView.java b/src/com/android/tv/menu/ChannelCardView.java
index 1c8015a6..2ecb6af7 100644
--- a/src/com/android/tv/menu/ChannelCardView.java
+++ b/src/com/android/tv/menu/ChannelCardView.java
@@ -34,10 +34,12 @@ import com.android.tv.data.Program;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.util.ImageLoader;
+import java.util.Objects;
+
/**
* A view to render channel card.
*/
-public class ChannelCardView extends BaseCardView<Channel> {
+public class ChannelCardView extends BaseCardView<ChannelsRowItem> {
private static final String TAG = MenuView.TAG;
private static final boolean DEBUG = MenuView.DEBUG;
@@ -45,11 +47,11 @@ public class ChannelCardView extends BaseCardView<Channel> {
private final int mCardImageHeight;
private ImageView mImageView;
- private View mGradientView;
private TextView mChannelNumberNameView;
private ProgressBar mProgressBar;
private Channel mChannel;
private Program mProgram;
+ private String mPosterArtUri;
private final MainActivity mMainActivity;
public ChannelCardView(Context context) {
@@ -71,39 +73,72 @@ public class ChannelCardView extends BaseCardView<Channel> {
protected void onFinishInflate() {
super.onFinishInflate();
mImageView = (ImageView) findViewById(R.id.image);
- mGradientView = findViewById(R.id.image_gradient);
+ mImageView.setBackgroundResource(R.color.channel_card);
mChannelNumberNameView = (TextView) findViewById(R.id.channel_number_and_name);
mProgressBar = (ProgressBar) findViewById(R.id.progress);
}
@Override
- public void onBind(Channel channel, boolean selected) {
+ public void onBind(ChannelsRowItem item, boolean selected) {
if (DEBUG) {
- Log.d(TAG, "onBind(channelName=" + channel.getDisplayName() + ", selected=" + selected
- + ")");
+ Log.d(TAG, "onBind(channelName=" + item.getChannel().getDisplayName() + ", selected="
+ + selected + ")");
}
- mChannel = channel;
- mProgram = null;
- mChannelNumberNameView.setText(mChannel.getDisplayText());
- mChannelNumberNameView.setVisibility(VISIBLE);
- mImageView.setImageResource(R.drawable.ic_recent_thumbnail_default);
- mImageView.setBackgroundResource(R.color.channel_card);
- mGradientView.setVisibility(View.GONE);
- mProgressBar.setVisibility(GONE);
+ updateChannel(item);
+ updateProgram();
+ super.onBind(item, selected);
+ }
- setTextViewEnabled(true);
- if (mMainActivity.getParentalControlSettings().isParentalControlsEnabled()
- && mChannel.isLocked()) {
+ private void updateChannel(ChannelsRowItem item) {
+ if (!item.getChannel().equals(mChannel)) {
+ mChannel = item.getChannel();
+ mChannelNumberNameView.setText(mChannel.getDisplayText());
+ mChannelNumberNameView.setVisibility(VISIBLE);
+ }
+ }
+
+ private void updateProgram() {
+ ParentalControlSettings parental = mMainActivity.getParentalControlSettings();
+ if (parental.isParentalControlsEnabled() && mChannel.isLocked()) {
setText(R.string.program_title_for_blocked_channel);
- return;
+ mProgram = null;
+ } else {
+ Program currentProgram =
+ mMainActivity.getProgramDataManager().getCurrentProgram(mChannel.getId());
+ if (!Objects.equals(currentProgram, mProgram)) {
+ mProgram = currentProgram;
+ if (mProgram == null || TextUtils.isEmpty(mProgram.getTitle())) {
+ setTextViewEnabled(false);
+ setText(R.string.program_title_for_no_information);
+ } else {
+ setTextViewEnabled(true);
+ setText(mProgram.getTitle());
+ }
+ }
+ }
+ if (mProgram == null) {
+ mProgressBar.setVisibility(GONE);
+ setPosterArt(null);
} else {
- setText("");
+ // Update progress.
+ mProgressBar.setVisibility(View.VISIBLE);
+ long startTime = mProgram.getStartTimeUtcMillis();
+ long endTime = mProgram.getEndTimeUtcMillis();
+ long currTime = System.currentTimeMillis();
+ if (currTime <= startTime) {
+ mProgressBar.setProgress(0);
+ } else if (currTime >= endTime) {
+ mProgressBar.setProgress(100);
+ } else {
+ mProgressBar.setProgress(
+ (int) (100 * (currTime - startTime) / (endTime - startTime)));
+ }
+ // Update image.
+ if (!parental.isParentalControlsEnabled()
+ || !parental.isRatingBlocked(mProgram.getContentRatings())) {
+ setPosterArt(mProgram.getPosterArtUri());
+ }
}
-
- updateProgramInformation();
- // Call super.onBind() at the end intentionally. In order to correctly handle extension of
- // text view, text should be set before calling super.onBind.
- super.onBind(channel, selected);
}
private static ImageLoader.ImageLoaderCallback<ChannelCardView> createProgramPosterArtCallback(
@@ -121,49 +156,20 @@ public class ChannelCardView extends BaseCardView<Channel> {
};
}
- private void updatePosterArt(Bitmap posterArt) {
- mImageView.setImageBitmap(posterArt);
- mGradientView.setVisibility(View.VISIBLE);
- }
-
- private void updateProgramInformation() {
- if (mChannel == null) {
- return;
- }
- mProgram = mMainActivity.getProgramDataManager().getCurrentProgram(mChannel.getId());
- if (mProgram == null || TextUtils.isEmpty(mProgram.getTitle())) {
- setTextViewEnabled(false);
- setText(R.string.program_title_for_no_information);
- } else {
- setText(mProgram.getTitle());
- }
-
- if (mProgram == null) {
- return;
- }
-
- long startTime = mProgram.getStartTimeUtcMillis();
- long endTime = mProgram.getEndTimeUtcMillis();
- long currTime = System.currentTimeMillis();
- mProgressBar.setVisibility(View.VISIBLE);
- if (currTime <= startTime) {
- mProgressBar.setProgress(0);
- } else if (currTime >= endTime) {
- mProgressBar.setProgress(100);
- } else {
- mProgressBar.setProgress((int) (100 * (currTime - startTime) / (endTime - startTime)));
+ private void setPosterArt(String posterArtUri) {
+ if (!TextUtils.equals(mPosterArtUri, posterArtUri)) {
+ mPosterArtUri = posterArtUri;
+ if (posterArtUri == null
+ || !mProgram.loadPosterArt(getContext(), mCardImageWidth, mCardImageHeight,
+ createProgramPosterArtCallback(this, mProgram))) {
+ mImageView.setImageResource(R.drawable.ic_recent_thumbnail_default);
+ mImageView.setForeground(null);
+ }
}
+ }
- if (!(getContext() instanceof MainActivity)) {
- Log.e(TAG, "Fails to check program's content rating.");
- return;
- }
- ParentalControlSettings parental = mMainActivity.getParentalControlSettings();
- if ((!parental.isParentalControlsEnabled()
- || !parental.isRatingBlocked(mProgram.getContentRatings()))
- && !TextUtils.isEmpty(mProgram.getPosterArtUri())) {
- mProgram.loadPosterArt(getContext(), mCardImageWidth, mCardImageHeight,
- createProgramPosterArtCallback(this, mProgram));
- }
+ private void updatePosterArt(Bitmap posterArt) {
+ mImageView.setImageBitmap(posterArt);
+ mImageView.setForeground(getContext().getDrawable(R.drawable.card_image_gradient));
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/menu/ChannelsPosterPrefetcher.java b/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
index f932d75d..bc5d6cfb 100644
--- a/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
+++ b/src/com/android/tv/menu/ChannelsPosterPrefetcher.java
@@ -97,12 +97,13 @@ public class ChannelsPosterPrefetcher {
// This executes on the main thread, but since the item list is expected to be about 5 items
// and ImageLoader spawns an async task so this is fast enough. 1 ms in local testing.
- List<Channel> channelList = mChannelsAdapter.getItemList();
- if (channelList != null) {
- for (Channel channel : channelList) {
+ List<ChannelsRowItem> items = mChannelsAdapter.getItemList();
+ if (items != null) {
+ for (ChannelsRowItem item : items) {
if (isCanceled) {
return;
}
+ Channel channel = item.getChannel();
if (!Channel.isValid(channel)) {
continue;
}
@@ -116,7 +117,7 @@ public class ChannelsPosterPrefetcher {
}
if (DEBUG) {
Log.d(TAG, "doPrefetchImages() finished. ImageLoader may still have async tasks for "
- + "channels " + channelList);
+ + "channels " + items);
}
}
diff --git a/src/com/android/tv/menu/ChannelsRow.java b/src/com/android/tv/menu/ChannelsRow.java
index dedf0993..490d73de 100644
--- a/src/com/android/tv/menu/ChannelsRow.java
+++ b/src/com/android/tv/menu/ChannelsRow.java
@@ -26,8 +26,14 @@ import com.android.tv.recommendation.Recommender;
public class ChannelsRow extends ItemListRow {
public static final String ID = ChannelsRow.class.getName();
- private static final int MIN_COUNT_FOR_RECENT_CHANNELS = 5;
- private static final int MAX_COUNT_FOR_RECENT_CHANNELS = 10;
+ /**
+ * Minimum count for recent channels.
+ */
+ public static final int MIN_COUNT_FOR_RECENT_CHANNELS = 5;
+ /**
+ * Maximum count for recent channels.
+ */
+ public static final int MAX_COUNT_FOR_RECENT_CHANNELS = 10;
private Recommender mTvRecommendation;
private ChannelsRowAdapter mChannelsAdapter;
diff --git a/src/com/android/tv/menu/ChannelsRowAdapter.java b/src/com/android/tv/menu/ChannelsRowAdapter.java
index c8e1bd05..7ff44ea6 100644
--- a/src/com/android/tv/menu/ChannelsRowAdapter.java
+++ b/src/com/android/tv/menu/ChannelsRowAdapter.java
@@ -31,17 +31,15 @@ import com.android.tv.dvr.DvrDataManager;
import com.android.tv.recommendation.Recommender;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
-import com.android.tv.util.Utils;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
/**
* An adapter of the Channels row.
*/
-public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel> {
- private static final String TAG = "ChannelsRowAdapter";
-
+public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<ChannelsRowItem> {
// There are four special cards: guide, setup, dvr, applink.
private static final int SIZE_OF_VIEW_TYPE = 5;
@@ -51,7 +49,6 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
private final DvrDataManager mDvrDataManager;
private final int mMaxCount;
private final int mMinCount;
- private final int[] mViewType = new int[SIZE_OF_VIEW_TYPE];
private final View.OnClickListener mGuideOnClickListener = new View.OnClickListener() {
@Override
@@ -113,14 +110,12 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
mRecommender = recommender;
mMinCount = minCount;
mMaxCount = maxCount;
+ setHasStableIds(true);
}
@Override
public int getItemViewType(int position) {
- if (position >= SIZE_OF_VIEW_TYPE) {
- return R.layout.menu_card_channel;
- }
- return mViewType[position];
+ return getItemList().get(position).getLayoutId();
}
@Override
@@ -129,9 +124,12 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
}
@Override
- public void onBindViewHolder(MyViewHolder viewHolder, int position) {
- super.onBindViewHolder(viewHolder, position);
+ public long getItemId(int position) {
+ return getItemList().get(position).getItemId();
+ }
+ @Override
+ public void onBindViewHolder(MyViewHolder viewHolder, int position) {
int viewType = getItemViewType(position);
if (viewType == R.layout.menu_card_guide) {
viewHolder.itemView.setOnClickListener(mGuideOnClickListener);
@@ -144,80 +142,158 @@ public class ChannelsRowAdapter extends ItemListRowView.ItemListAdapter<Channel>
SimpleCardView view = (SimpleCardView) viewHolder.itemView;
view.setText(R.string.channels_item_dvr);
} else {
- viewHolder.itemView.setTag(getItemList().get(position));
+ viewHolder.itemView.setTag(getItemList().get(position).getChannel());
viewHolder.itemView.setOnClickListener(mChannelOnClickListener);
}
+ super.onBindViewHolder(viewHolder, position);
}
@Override
public void update() {
- List<Channel> channelList = new ArrayList<>();
- Channel dummyChannel = new Channel.Builder().build();
- // For guide item
- channelList.add(dummyChannel);
- // For setup item
- TvInputManagerHelper inputManager = TvApplication.getSingletons(mContext)
- .getTvInputManagerHelper();
- boolean showSetupCard = SetupUtils.getInstance(mContext).hasNewInput(inputManager);
- Channel currentChannel = getMainActivity().getCurrentChannel();
- boolean showAppLinkCard = currentChannel != null
- && currentChannel.getAppLinkType(mContext) != Channel.APP_LINK_TYPE_NONE
- // Sometimes applicationInfo can be null. b/28932537
- && inputManager.getTvInputAppInfo(currentChannel.getInputId()) != null;
- boolean showDvrCard = false;
+ if (getItemCount() == 0) {
+ createItems();
+ } else {
+ updateItems();
+ }
+ }
+
+ private void createItems() {
+ List<ChannelsRowItem> items = new ArrayList<>();
+ items.add(ChannelsRowItem.GUIDE_ITEM);
+ if (needToShowSetupItem()) {
+ items.add(ChannelsRowItem.SETUP_ITEM);
+ }
+ if (needToShowDvrItem()) {
+ items.add(ChannelsRowItem.DVR_ITEM);
+ }
+ if (needToShowAppLinkItem()) {
+ ChannelsRowItem.APP_LINK_ITEM.setChannel(
+ new Channel.Builder(getMainActivity().getCurrentChannel()).build());
+ items.add(ChannelsRowItem.APP_LINK_ITEM);
+ }
+ for (Channel channel : getRecentChannels()) {
+ items.add(new ChannelsRowItem(channel, R.layout.menu_card_channel));
+ }
+ setItemList(items);
+ }
+
+ private void updateItems() {
+ List<ChannelsRowItem> items = getItemList();
+ // The current index of the item list to iterate. It starts from 1 because the first item
+ // (GUIDE) is always visible and not updated.
+ int currentIndex = 1;
+ if (updateItem(needToShowSetupItem(), ChannelsRowItem.SETUP_ITEM, currentIndex)) {
+ ++currentIndex;
+ }
+ if (updateItem(needToShowDvrItem(), ChannelsRowItem.DVR_ITEM, currentIndex)) {
+ ++currentIndex;
+ }
+ if (updateItem(needToShowAppLinkItem(), ChannelsRowItem.APP_LINK_ITEM, currentIndex)) {
+ if (!getMainActivity().getCurrentChannel()
+ .hasSameReadOnlyInfo(ChannelsRowItem.APP_LINK_ITEM.getChannel())) {
+ ChannelsRowItem.APP_LINK_ITEM.setChannel(
+ new Channel.Builder(getMainActivity().getCurrentChannel()).build());
+ notifyItemChanged(currentIndex);
+ }
+ ++currentIndex;
+ }
+ int numOldChannels = items.size() - currentIndex;
+ if (numOldChannels > 0) {
+ while (items.size() > currentIndex) {
+ items.remove(items.size() - 1);
+ }
+ notifyItemRangeRemoved(currentIndex, numOldChannels);
+ }
+ for (Channel channel : getRecentChannels()) {
+ items.add(new ChannelsRowItem(channel, R.layout.menu_card_channel));
+ }
+ int numNewChannels = items.size() - currentIndex;
+ if (numNewChannels > 0) {
+ notifyItemRangeInserted(currentIndex, numNewChannels);
+ }
+ }
+
+ /**
+ * Returns {@code true} if the item should be shown.
+ */
+ private boolean updateItem(boolean needToShow, ChannelsRowItem item, int index) {
+ List<ChannelsRowItem> items = getItemList();
+ boolean isItemInList = index < items.size() && item.equals(items.get(index));
+ if (needToShow && !isItemInList) {
+ items.add(index, item);
+ notifyItemInserted(index);
+ } else if (!needToShow && isItemInList) {
+ items.remove(index);
+ notifyItemRemoved(index);
+ }
+ return needToShow;
+ }
+
+ private boolean needToShowSetupItem() {
+ TvInputManagerHelper inputManager =
+ TvApplication.getSingletons(mContext).getTvInputManagerHelper();
+ return SetupUtils.getInstance(mContext).hasNewInput(inputManager);
+ }
+
+ private boolean needToShowDvrItem() {
+ TvInputManagerHelper inputManager =
+ TvApplication.getSingletons(mContext).getTvInputManagerHelper();
if (mDvrDataManager != null) {
for (TvInputInfo info : inputManager.getTvInputInfos(true, true)) {
if (info.canRecord()) {
- showDvrCard = true;
- break;
+ return true;
}
}
}
+ return false;
+ }
- mViewType[0] = R.layout.menu_card_guide;
- int index = 1;
- if (showSetupCard) {
- channelList.add(dummyChannel);
- mViewType[index++] = R.layout.menu_card_setup;
- }
- if (showDvrCard) {
- channelList.add(dummyChannel);
- mViewType[index++] = R.layout.menu_card_dvr;
- }
- if (showAppLinkCard) {
- channelList.add(currentChannel);
- mViewType[index++] = R.layout.menu_card_app_link;
- }
- for ( ; index < mViewType.length; ++index) {
- mViewType[index] = R.layout.menu_card_channel;
- }
- channelList.addAll(getRecentChannels());
- setItemList(channelList);
+ private boolean needToShowAppLinkItem() {
+ TvInputManagerHelper inputManager =
+ TvApplication.getSingletons(mContext).getTvInputManagerHelper();
+ Channel currentChannel = getMainActivity().getCurrentChannel();
+ return currentChannel != null
+ && currentChannel.getAppLinkType(mContext) != Channel.APP_LINK_TYPE_NONE
+ // Sometimes applicationInfo can be null. b/28932537
+ && inputManager.getTvInputAppInfo(currentChannel.getInputId()) != null;
}
private List<Channel> getRecentChannels() {
List<Channel> channelList = new ArrayList<>();
+ long currentChannelId = getMainActivity().getCurrentChannelId();
+ ArrayDeque<Long> recentChannels = getMainActivity().getRecentChannels();
+ // Add the last watched channel as the first one.
+ for (long channelId : recentChannels) {
+ if (addChannelToList(
+ channelList, mRecommender.getChannel(channelId), currentChannelId)) {
+ break;
+ }
+ }
+ // Add the recommended channels.
for (Channel channel : mRecommender.recommendChannels(mMaxCount)) {
- if (channel.isBrowsable()) {
- channelList.add(channel);
+ if (channelList.size() >= mMaxCount) {
+ break;
}
+ addChannelToList(channelList, channel, currentChannelId);
}
- int count = channelList.size();
// If the number of recommended channels is not enough, add more from the recent channel
// list.
- if (count < mMinCount) {
- for (long channelId : getMainActivity().getRecentChannels()) {
- Channel channel = mRecommender.getChannel(channelId);
- if (channel == null || channelList.contains(channel)
- || !channel.isBrowsable()) {
- continue;
- }
- channelList.add(channel);
- if (++count >= mMinCount) {
- break;
- }
+ for (long channelId : recentChannels) {
+ if (channelList.size() >= mMinCount) {
+ break;
}
+ addChannelToList(channelList, mRecommender.getChannel(channelId), currentChannelId);
}
return channelList;
}
+
+ private static boolean addChannelToList(
+ List<Channel> channelList, Channel channel, long currentChannelId) {
+ if (channel == null || channel.getId() == currentChannelId
+ || channelList.contains(channel) || !channel.isBrowsable()) {
+ return false;
+ }
+ channelList.add(channel);
+ return true;
+ }
}
diff --git a/src/com/android/tv/menu/ChannelsRowItem.java b/src/com/android/tv/menu/ChannelsRowItem.java
new file mode 100644
index 00000000..c35189ec
--- /dev/null
+++ b/src/com/android/tv/menu/ChannelsRowItem.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 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.tv.menu;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import com.android.tv.R;
+import com.android.tv.data.Channel;
+
+/**
+ * A class for the items in channels row.
+ */
+public class ChannelsRowItem {
+ /** The item ID for guide item */
+ public static final int GUIDE_ITEM_ID = -1;
+ /** The item ID for setup item */
+ public static final int SETUP_ITEM_ID = -2;
+ /** The item ID for DVR item */
+ public static final int DVR_ITEM_ID = -3;
+ /** The item ID for app link item */
+ public static final int APP_LINK_ITEM_ID = -4;
+
+ /** The item which represents the guide. */
+ public static final ChannelsRowItem GUIDE_ITEM =
+ new ChannelsRowItem(GUIDE_ITEM_ID, R.layout.menu_card_guide);
+ /** The item which represents the setup. */
+ public static final ChannelsRowItem SETUP_ITEM =
+ new ChannelsRowItem(SETUP_ITEM_ID, R.layout.menu_card_setup);
+ /** The item which represents the DVR. */
+ public static final ChannelsRowItem DVR_ITEM =
+ new ChannelsRowItem(DVR_ITEM_ID, R.layout.menu_card_dvr);
+ /** The item which represents the app link. */
+ public static final ChannelsRowItem APP_LINK_ITEM =
+ new ChannelsRowItem(APP_LINK_ITEM_ID, R.layout.menu_card_app_link);
+
+ private final long mItemId;
+ @NonNull private Channel mChannel;
+ private final int mLayoutId;
+
+ public ChannelsRowItem(@NonNull Channel channel, int layoutId) {
+ this(channel.getId(), layoutId);
+ mChannel = channel;
+ }
+
+ private ChannelsRowItem(long itemId, int layoutId) {
+ mItemId = itemId;
+ mLayoutId = layoutId;
+ }
+
+ /**
+ * Returns the channel for this item.
+ */
+ @NonNull
+ public Channel getChannel() {
+ return mChannel;
+ }
+
+ /**
+ * Sets the channel.
+ */
+ public void setChannel(@NonNull Channel channel) {
+ mChannel = channel;
+ }
+
+ /**
+ * Returns the layout resource ID to represent this item.
+ */
+ public int getLayoutId() {
+ return mLayoutId;
+ }
+
+ /**
+ * Returns the unique ID for this item.
+ */
+ public long getItemId() {
+ return mItemId;
+ }
+
+ @Override
+ public String toString() {
+ return "ChannelsRowItem{"
+ + "itemId=" + mItemId
+ + ", layoutId=" + mLayoutId
+ + ", channel=" + mChannel + "}";
+ }
+}
diff --git a/src/com/android/tv/menu/ItemListRowView.java b/src/com/android/tv/menu/ItemListRowView.java
index 4919c595..cbeee936 100644
--- a/src/com/android/tv/menu/ItemListRowView.java
+++ b/src/com/android/tv/menu/ItemListRowView.java
@@ -28,6 +28,7 @@ import android.view.ViewGroup;
import com.android.tv.MainActivity;
import com.android.tv.R;
+import com.android.tv.util.ViewCache;
import java.util.Collections;
import java.util.List;
@@ -69,6 +70,8 @@ public class ItemListRowView extends MenuRowView implements OnChildSelectedListe
protected void onFinishInflate() {
super.onFinishInflate();
mListView = (HorizontalGridView) getContentsView();
+ // Disable the position change animation of the cards.
+ mListView.setItemAnimator(null);
}
@Override
@@ -194,9 +197,24 @@ public class ItemListRowView extends MenuRowView implements OnChildSelectedListe
return mItemList.size();
}
+ /**
+ * Returns the position of the item.
+ */
+ protected int getItemPosition(T item) {
+ return mItemList.indexOf(item);
+ }
+
+ /**
+ * Returns {@code true} if the item list contains the item, otherwise {@code false}.
+ */
+ protected boolean containsItem(T item) {
+ return mItemList.contains(item);
+ }
+
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View view = mLayoutInflater.inflate(getLayoutResId(viewType), parent, false);
+ View view = ViewCache.getInstance().getOrCreateView(
+ mLayoutInflater, getLayoutResId(viewType), parent);
return new MyViewHolder(view);
}
diff --git a/src/com/android/tv/menu/Menu.java b/src/com/android/tv/menu/Menu.java
index 1160a5b5..e373de61 100644
--- a/src/com/android/tv/menu/Menu.java
+++ b/src/com/android/tv/menu/Menu.java
@@ -26,24 +26,28 @@ import android.os.Message;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
+import android.support.v17.leanback.widget.HorizontalGridView;
import android.util.Log;
import com.android.tv.ChannelTuner;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.analytics.DurationTimer;
+import com.android.tv.TvOptionsManager;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.TvCommonUtils;
import com.android.tv.common.WeakHandler;
import com.android.tv.menu.MenuRowFactory.PartnerRow;
-import com.android.tv.menu.MenuRowFactory.PipOptionsRow;
import com.android.tv.menu.MenuRowFactory.TvOptionsRow;
import com.android.tv.ui.TunableTvView;
+import com.android.tv.util.DurationTimer;
+import com.android.tv.util.ViewCache;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* A class which controls the menu.
@@ -81,10 +85,21 @@ public class Menu {
sRowIdListForReason.add(PlayControlsRow.ID); // REASON_PLAY_CONTROLS_JUMP_TO_NEXT
}
+ private static final Map<Integer, Integer> PRELOAD_VIEW_IDS = new HashMap<>();
+ static {
+ PRELOAD_VIEW_IDS.put(R.layout.menu_card_guide, 1);
+ PRELOAD_VIEW_IDS.put(R.layout.menu_card_setup, 1);
+ PRELOAD_VIEW_IDS.put(R.layout.menu_card_dvr, 1);
+ PRELOAD_VIEW_IDS.put(R.layout.menu_card_app_link, 1);
+ PRELOAD_VIEW_IDS.put(R.layout.menu_card_channel, ChannelsRow.MAX_COUNT_FOR_RECENT_CHANNELS);
+ PRELOAD_VIEW_IDS.put(R.layout.menu_card_action, 7);
+ }
+
private static final String SCREEN_NAME = "Menu";
private static final int MSG_HIDE_MENU = 1000;
+ private final Context mContext;
private final IMenuView mMenuView;
private final Tracker mTracker;
private final DurationTimer mVisibleTimer = new DurationTimer();
@@ -103,15 +118,16 @@ public class Menu {
@VisibleForTesting
Menu(Context context, IMenuView menuView, MenuRowFactory menuRowFactory,
OnMenuVisibilityChangeListener onMenuVisibilityChangeListener) {
- this(context, null, menuView, menuRowFactory, onMenuVisibilityChangeListener);
+ this(context, null, null, menuView, menuRowFactory, onMenuVisibilityChangeListener);
}
- public Menu(Context context, TunableTvView tvView, IMenuView menuView,
- MenuRowFactory menuRowFactory,
+ public Menu(Context context, TunableTvView tvView, TvOptionsManager optionsManager,
+ IMenuView menuView, MenuRowFactory menuRowFactory,
OnMenuVisibilityChangeListener onMenuVisibilityChangeListener) {
+ mContext = context;
mMenuView = menuView;
mTracker = TvApplication.getSingletons(context).getTracker();
- mMenuUpdater = new MenuUpdater(context, tvView, this);
+ mMenuUpdater = new MenuUpdater(this, tvView, optionsManager);
Resources res = context.getResources();
mShowDurationMillis = res.getInteger(R.integer.menu_show_duration);
mOnMenuVisibilityChangeListener = onMenuVisibilityChangeListener;
@@ -130,7 +146,6 @@ public class Menu {
addMenuRow(menuRowFactory.createMenuRow(this, ChannelsRow.class));
addMenuRow(menuRowFactory.createMenuRow(this, PartnerRow.class));
addMenuRow(menuRowFactory.createMenuRow(this, TvOptionsRow.class));
- addMenuRow(menuRowFactory.createMenuRow(this, PipOptionsRow.class));
mMenuView.setMenuRows(mMenuRows);
}
@@ -160,6 +175,16 @@ public class Menu {
}
/**
+ * Preloads the item view used for the menu.
+ */
+ public void preloadItemViews() {
+ HorizontalGridView fakeParent = new HorizontalGridView(mContext);
+ for (int id : PRELOAD_VIEW_IDS.keySet()) {
+ ViewCache.getInstance().putView(mContext, id, fakeParent, PRELOAD_VIEW_IDS.get(id));
+ }
+ }
+
+ /**
* Shows the main menu.
*
* @param reason A reason why this is called. See {@link MenuShowReason}
@@ -293,9 +318,7 @@ public class Menu {
*/
public void onStreamInfoChanged() {
if (DEBUG) Log.d(TAG, "update options row in main menu");
- for (MenuRow row : mMenuRows) {
- row.onStreamInfoChanged();
- }
+ mMenuUpdater.onStreamInfoChanged();
}
@VisibleForTesting
diff --git a/src/com/android/tv/menu/MenuAction.java b/src/com/android/tv/menu/MenuAction.java
index 0d59552a..b4356059 100644
--- a/src/com/android/tv/menu/MenuAction.java
+++ b/src/com/android/tv/menu/MenuAction.java
@@ -20,9 +20,9 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
-import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvOptionsManager;
+import com.android.tv.TvOptionsManager.OptionType;
/**
* A class to define possible actions from main menu.
@@ -36,12 +36,9 @@ public class MenuAction {
public static final MenuAction SELECT_DISPLAY_MODE_ACTION =
new MenuAction(R.string.options_item_display_mode, TvOptionsManager.OPTION_DISPLAY_MODE,
R.drawable.ic_tvoption_aspect);
- public static final MenuAction PIP_IN_APP_ACTION =
- new MenuAction(R.string.options_item_pip, TvOptionsManager.OPTION_IN_APP_PIP,
- R.drawable.ic_tvoption_pip);
public static final MenuAction SYSTEMWIDE_PIP_ACTION =
new MenuAction(R.string.options_item_pip, TvOptionsManager.OPTION_SYSTEMWIDE_PIP,
- R.drawable.ic_pip_option_layout2);
+ R.drawable.ic_tvoption_pip);
public static final MenuAction SELECT_AUDIO_LANGUAGE_ACTION =
new MenuAction(R.string.options_item_multi_audio, TvOptionsManager.OPTION_MULTI_AUDIO,
R.drawable.ic_tvoption_multi_track);
@@ -51,34 +48,36 @@ public class MenuAction {
public static final MenuAction DEV_ACTION =
new MenuAction(R.string.options_item_developer,
TvOptionsManager.OPTION_DEVELOPER, R.drawable.ic_developer_mode_tv_white_48dp);
- // TODO: Change the icon.
public static final MenuAction SETTINGS_ACTION =
new MenuAction(R.string.options_item_settings, TvOptionsManager.OPTION_SETTINGS,
R.drawable.ic_settings);
- // Actions in the PIP option row.
- public static final MenuAction PIP_SELECT_INPUT_ACTION =
- new MenuAction(R.string.pip_options_item_source, TvOptionsManager.OPTION_PIP_INPUT,
- R.drawable.ic_pip_option_input);
- public static final MenuAction PIP_SWAP_ACTION =
- new MenuAction(R.string.pip_options_item_swap, TvOptionsManager.OPTION_PIP_SWAP,
- R.drawable.ic_pip_option_swap);
- public static final MenuAction PIP_SOUND_ACTION =
- new MenuAction(R.string.pip_options_item_sound, TvOptionsManager.OPTION_PIP_SOUND,
- R.drawable.ic_pip_option_swap_audio);
- public static final MenuAction PIP_LAYOUT_ACTION =
- new MenuAction(R.string.pip_options_item_layout, TvOptionsManager.OPTION_PIP_LAYOUT,
- R.drawable.ic_pip_option_layout1);
- public static final MenuAction PIP_SIZE_ACTION =
- new MenuAction(R.string.pip_options_item_size, TvOptionsManager.OPTION_PIP_SIZE,
- R.drawable.ic_pip_option_size);
private final String mActionName;
private final int mActionNameResId;
- private final int mType;
+ @OptionType private final int mType;
+ private String mActionDescription;
private Drawable mDrawable;
private int mDrawableResId;
private boolean mEnabled = true;
+ /**
+ * Sets the action description. Returns {@code trye} if the description is changed.
+ */
+ public static boolean setActionDescription(MenuAction action, String actionDescription) {
+ String oldDescription = action.mActionDescription;
+ action.mActionDescription = actionDescription;
+ return !TextUtils.equals(action.mActionDescription, oldDescription);
+ }
+
+ /**
+ * Enables or disables the action. Returns {@code true} if the value is changed.
+ */
+ public static boolean setEnabled(MenuAction action, boolean enabled) {
+ boolean changed = action.mEnabled != enabled;
+ action.mEnabled = enabled;
+ return changed;
+ }
+
public MenuAction(int actionNameResId, int type, int drawableResId) {
mActionName = null;
mActionNameResId = actionNameResId;
@@ -102,11 +101,11 @@ public class MenuAction {
return context.getString(mActionNameResId);
}
- public String getActionDescription(Context context) {
- return ((MainActivity) context).getTvOptionsManager().getOptionString(mType);
+ public String getActionDescription() {
+ return mActionDescription;
}
- public int getType() {
+ @OptionType public int getType() {
return mType;
}
@@ -120,28 +119,10 @@ public class MenuAction {
return mDrawable;
}
- /**
- * Sets drawable resource id.
- *
- * @return {@code true} if drawable is changed.
- */
- public boolean setDrawableResId(int resId) {
- if (mDrawableResId == resId) {
- return false;
- }
- mDrawable = null;
- mDrawableResId = resId;
- return true;
- }
-
public boolean isEnabled() {
return mEnabled;
}
- public void setEnabled(boolean enabled) {
- mEnabled = enabled;
- }
-
public int getActionNameResId() {
return mActionNameResId;
}
diff --git a/src/com/android/tv/menu/MenuLayoutManager.java b/src/com/android/tv/menu/MenuLayoutManager.java
index 6c767247..173d4004 100644
--- a/src/com/android/tv/menu/MenuLayoutManager.java
+++ b/src/com/android/tv/menu/MenuLayoutManager.java
@@ -28,6 +28,7 @@ import android.support.annotation.UiThread;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.util.Property;
import android.view.View;
@@ -56,12 +57,14 @@ public class MenuLayoutManager {
// The visible duration of the title before it is hidden.
private static final long TITLE_SHOW_DURATION_BEFORE_HIDDEN_MS = TimeUnit.SECONDS.toMillis(2);
+ private static final int INVALID_POSITION = -1;
private final MenuView mMenuView;
private final List<MenuRow> mMenuRows = new ArrayList<>();
private final List<MenuRowView> mMenuRowViews = new ArrayList<>();
private final List<Integer> mRemovingRowViews = new ArrayList<>();
- private int mSelectedPosition = -1;
+ private int mSelectedPosition = INVALID_POSITION;
+ private int mPendingSelectedPosition = INVALID_POSITION;
private final int mRowAlignFromBottom;
private final int mRowContentsPaddingTop;
@@ -130,8 +133,8 @@ public class MenuLayoutManager {
MenuRowView currentView = mMenuRowViews.get(mSelectedPosition);
if (currentView.getVisibility() == View.GONE) {
// If the selected row is not visible, select the first visible row.
- int firstVisiblePosition = findNextVisiblePosition(-1);
- if (firstVisiblePosition != -1) {
+ int firstVisiblePosition = findNextVisiblePosition(INVALID_POSITION);
+ if (firstVisiblePosition != INVALID_POSITION) {
mSelectedPosition = firstVisiblePosition;
} else {
// No rows are visible.
@@ -157,6 +160,10 @@ public class MenuLayoutManager {
view.onDeselected();
}
}
+
+ if (mPendingSelectedPosition != INVALID_POSITION) {
+ setSelectedPositionSmooth(mPendingSelectedPosition);
+ }
}
private int findNextVisiblePosition(int start) {
@@ -166,7 +173,7 @@ public class MenuLayoutManager {
return i;
}
}
- return -1;
+ return INVALID_POSITION;
}
private void dumpChildren(String prefix) {
@@ -327,6 +334,7 @@ public class MenuLayoutManager {
mMenuRowViews.get(mSelectedPosition).onDeselected();
}
mSelectedPosition = position;
+ mPendingSelectedPosition = INVALID_POSITION;
if (Utils.isIndexValid(mMenuRowViews, mSelectedPosition)) {
mMenuRowViews.get(mSelectedPosition).onSelected(false);
}
@@ -380,14 +388,29 @@ public class MenuLayoutManager {
// again from the intermediate state.
mTitleFadeOutAnimator.cancel();
}
- final int oldPosition = mSelectedPosition;
- mSelectedPosition = position;
if (DEBUG) dumpChildren("startRowAnimation()");
- MenuRowView currentView = mMenuRowViews.get(position);
// Show the children of the next row.
- currentView.getTitleView().setVisibility(View.VISIBLE);
- currentView.getContentsView().setVisibility(View.VISIBLE);
+ final MenuRowView currentView = mMenuRowViews.get(position);
+ TextView currentTitleView = currentView.getTitleView();
+ View currentContentsView = currentView.getContentsView();
+ currentTitleView.setVisibility(View.VISIBLE);
+ currentContentsView.setVisibility(View.VISIBLE);
+ if (currentView instanceof PlayControlsRowView) {
+ ((PlayControlsRowView) currentView).onPreselected();
+ }
+ // When contents view's visibility is gone, layouting might be delayed until it's shown and
+ // thus cause onBindViewHolder() and menu action updating occurs in front of users' sight.
+ // Therefore we call requestLayout() here if there are pending adapter updates.
+ if (currentContentsView instanceof RecyclerView
+ && ((RecyclerView) currentContentsView).hasPendingAdapterUpdates()) {
+ currentContentsView.requestLayout();
+ mPendingSelectedPosition = position;
+ return;
+ }
+ final int oldPosition = mSelectedPosition;
+ mSelectedPosition = position;
+ mPendingSelectedPosition = INVALID_POSITION;
// Request focus after the new contents view shows up.
mMenuView.requestFocus();
if (mTempTitleViewForOld == null) {
@@ -407,7 +430,7 @@ public class MenuLayoutManager {
// Old row.
MenuRow oldRow = mMenuRows.get(oldPosition);
- MenuRowView oldView = mMenuRowViews.get(oldPosition);
+ final MenuRowView oldView = mMenuRowViews.get(oldPosition);
View oldContentsView = oldView.getContentsView();
// Old contents view.
animators.add(createAlphaAnimator(oldContentsView, 1.0f, 0.0f, 1.0f, mLinearOutSlowIn)
@@ -468,8 +491,6 @@ public class MenuLayoutManager {
}
// Current row.
Rect currentLayoutRect = new Rect(layouts.get(position));
- TextView currentTitleView = currentView.getTitleView();
- View currentContentsView = currentView.getContentsView();
currentContentsView.setAlpha(0.0f);
if (scrollDown) {
// Current title view.
@@ -529,7 +550,7 @@ public class MenuLayoutManager {
int nextPosition;
if (scrollDown) {
nextPosition = findNextVisiblePosition(position);
- if (nextPosition != -1) {
+ if (nextPosition != INVALID_POSITION) {
MenuRowView nextView = mMenuRowViews.get(nextPosition);
Rect nextLayoutRect = layouts.get(nextPosition);
animators.add(createTranslationYAnimator(nextView,
@@ -539,7 +560,7 @@ public class MenuLayoutManager {
}
} else {
nextPosition = findNextVisiblePosition(oldPosition);
- if (nextPosition != -1) {
+ if (nextPosition != INVALID_POSITION) {
MenuRowView nextView = mMenuRowViews.get(nextPosition);
animators.add(createTranslationYAnimator(nextView, 0, mRowScrollUpAnimationOffset));
animators.add(createAlphaAnimator(nextView,
@@ -572,9 +593,8 @@ public class MenuLayoutManager {
for (ViewPropertyValueHolder holder : propertyValuesAfterAnimation) {
holder.property.set(holder.view, holder.value);
}
- oldTitleView.setVisibility(View.VISIBLE);
- mMenuRowViews.get(oldPosition).onDeselected();
- mMenuRowViews.get(position).onSelected(true);
+ oldView.onDeselected();
+ currentView.onSelected(true);
mTempTitleViewForOld.setVisibility(View.GONE);
mTempTitleViewForCurrent.setVisibility(View.GONE);
layout(mMenuView.getLeft(), mMenuView.getTop(), mMenuView.getRight(),
diff --git a/src/com/android/tv/menu/MenuRow.java b/src/com/android/tv/menu/MenuRow.java
index 6f98e615..47804f11 100644
--- a/src/com/android/tv/menu/MenuRow.java
+++ b/src/com/android/tv/menu/MenuRow.java
@@ -123,11 +123,6 @@ public abstract class MenuRow {
public void onRecentChannelsChanged() { }
/**
- * This method is called when stream information is changed.
- */
- public void onStreamInfoChanged() { }
-
- /**
* Returns whether to hide the title when the row is selected.
*/
public boolean hideTitleWhenSelected() {
diff --git a/src/com/android/tv/menu/MenuRowFactory.java b/src/com/android/tv/menu/MenuRowFactory.java
index c67a0e04..570cfb8f 100644
--- a/src/com/android/tv/menu/MenuRowFactory.java
+++ b/src/com/android/tv/menu/MenuRowFactory.java
@@ -67,8 +67,6 @@ public class MenuRowFactory {
} else if (TvOptionsRow.class.equals(key)) {
return new TvOptionsRow(mMainActivity, menu, mTvCustomizationManager
.getCustomActions(TvCustomizationManager.ID_OPTIONS_ROW));
- } else if (PipOptionsRow.class.equals(key)) {
- return new PipOptionsRow(mMainActivity, menu);
}
return null;
}
@@ -77,36 +75,15 @@ public class MenuRowFactory {
* A menu row which represents the TV options row.
*/
public static class TvOptionsRow extends ItemListRow {
+ /**
+ * The ID of the row.
+ */
+ public static final String ID = TvOptionsRow.class.getName();
+
private TvOptionsRow(Context context, Menu menu, List<CustomAction> customActions) {
super(context, menu, R.string.menu_title_options, R.dimen.action_card_height,
new TvOptionsRowAdapter(context, customActions));
}
-
- @Override
- public void onStreamInfoChanged() {
- if (getMenu().isActive()) {
- update();
- }
- }
- }
-
- /**
- * A menu row which represents the PIP options row.
- */
- public static class PipOptionsRow extends ItemListRow {
- private final MainActivity mMainActivity;
-
- private PipOptionsRow(Context context, Menu menu) {
- super(context, menu, R.string.menu_title_pip_options, R.dimen.action_card_height,
- new PipOptionsRowAdapter(context));
- mMainActivity = (MainActivity) context;
- }
-
- @Override
- public boolean isVisible() {
- // TODO: Remove the dependency on MainActivity.
- return super.isVisible() && mMainActivity.isPipEnabled();
- }
}
/**
diff --git a/src/com/android/tv/menu/MenuUpdater.java b/src/com/android/tv/menu/MenuUpdater.java
index 075b299e..18416c85 100644
--- a/src/com/android/tv/menu/MenuUpdater.java
+++ b/src/com/android/tv/menu/MenuUpdater.java
@@ -16,11 +16,14 @@
package com.android.tv.menu;
-import android.content.Context;
import android.support.annotation.Nullable;
import com.android.tv.ChannelTuner;
+import com.android.tv.TvOptionsManager;
+import com.android.tv.TvOptionsManager.OptionChangedListener;
+import com.android.tv.TvOptionsManager.OptionType;
import com.android.tv.data.Channel;
+import com.android.tv.menu.MenuRowFactory.TvOptionsRow;
import com.android.tv.ui.TunableTvView;
import com.android.tv.ui.TunableTvView.OnScreenBlockingChangedListener;
@@ -30,10 +33,10 @@ import com.android.tv.ui.TunableTvView.OnScreenBlockingChangedListener;
* <p>As the menu is updated when it shows up, this class handles only the dynamic updates.
*/
public class MenuUpdater {
- // Can be null for testing.
- @Nullable
- private final TunableTvView mTvView;
private final Menu mMenu;
+ // Can be null for testing.
+ @Nullable private final TunableTvView mTvView;
+ @Nullable private final TvOptionsManager mOptionsManager;
private ChannelTuner mChannelTuner;
private final ChannelTuner.Listener mChannelTunerListener = new ChannelTuner.Listener() {
@@ -42,7 +45,7 @@ public class MenuUpdater {
@Override
public void onBrowsableChannelListChanged() {
- mMenu.update();
+ mMenu.update(ChannelsRow.ID);
}
@Override
@@ -53,10 +56,17 @@ public class MenuUpdater {
mMenu.update(ChannelsRow.ID);
}
};
+ private final OptionChangedListener mOptionChangeListener = new OptionChangedListener() {
+ @Override
+ public void onOptionChanged(@OptionType int optionType, String newString) {
+ mMenu.update(TvOptionsRow.ID);
+ }
+ };
- public MenuUpdater(Context context, TunableTvView tvView, Menu menu) {
- mTvView = tvView;
+ public MenuUpdater(Menu menu, TunableTvView tvView, TvOptionsManager optionsManager) {
mMenu = menu;
+ mTvView = tvView;
+ mOptionsManager = optionsManager;
if (mTvView != null) {
mTvView.setOnScreenBlockedListener(new OnScreenBlockingChangedListener() {
@Override
@@ -65,11 +75,18 @@ public class MenuUpdater {
}
});
}
+ if (mOptionsManager != null) {
+ mOptionsManager.setOptionChangedListener(TvOptionsManager.OPTION_CLOSED_CAPTIONS,
+ mOptionChangeListener);
+ mOptionsManager.setOptionChangedListener(TvOptionsManager.OPTION_DISPLAY_MODE,
+ mOptionChangeListener);
+ mOptionsManager.setOptionChangedListener(TvOptionsManager.OPTION_MULTI_AUDIO,
+ mOptionChangeListener);
+ }
}
/**
- * Sets the instance of {@link ChannelTuner}. Call this method when the channel tuner is ready
- * or not available any more.
+ * Sets the instance of {@link ChannelTuner}. Call this method when the channel tuner is ready.
*/
public void setChannelTuner(ChannelTuner channelTuner) {
if (mChannelTuner != null) {
@@ -79,7 +96,13 @@ public class MenuUpdater {
if (mChannelTuner != null) {
mChannelTuner.addListener(mChannelTunerListener);
}
- mMenu.update();
+ }
+
+ /**
+ * Called when the stream information changes.
+ */
+ public void onStreamInfoChanged() {
+ mMenu.update(TvOptionsRow.ID);
}
/**
@@ -92,5 +115,10 @@ public class MenuUpdater {
if (mTvView != null) {
mTvView.setOnScreenBlockedListener(null);
}
+ if (mOptionsManager != null) {
+ mOptionsManager.setOptionChangedListener(TvOptionsManager.OPTION_CLOSED_CAPTIONS, null);
+ mOptionsManager.setOptionChangedListener(TvOptionsManager.OPTION_DISPLAY_MODE, null);
+ mOptionsManager.setOptionChangedListener(TvOptionsManager.OPTION_MULTI_AUDIO, null);
+ }
}
}
diff --git a/src/com/android/tv/menu/OptionsRowAdapter.java b/src/com/android/tv/menu/OptionsRowAdapter.java
index 93bd0a4d..dd6194a1 100644
--- a/src/com/android/tv/menu/OptionsRowAdapter.java
+++ b/src/com/android/tv/menu/OptionsRowAdapter.java
@@ -21,8 +21,6 @@ import android.view.View;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.TvOptionsManager;
-import com.android.tv.TvOptionsManager.OptionChangedListener;
import com.android.tv.analytics.Tracker;
import java.util.List;
@@ -66,12 +64,9 @@ public abstract class OptionsRowAdapter extends ItemListRowView.ItemListAdapter<
public void update() {
if (mActionList == null) {
mActionList = createActions();
- updateActions();
setItemList(mActionList);
} else {
- if (updateActions()) {
- setItemList(mActionList);
- }
+ updateActions();
}
}
@@ -81,7 +76,7 @@ public abstract class OptionsRowAdapter extends ItemListRowView.ItemListAdapter<
}
protected abstract List<MenuAction> createActions();
- protected abstract boolean updateActions();
+ protected abstract void updateActions();
protected abstract void executeAction(int type);
/**
@@ -93,37 +88,6 @@ public abstract class OptionsRowAdapter extends ItemListRowView.ItemListAdapter<
return mActionList.get(position);
}
- /**
- * Sets the action at the given position.
- * Note that action at the position may differ from returned by {@link #createActions}.
- * See {@link CustomizableOptionsRowAdapter}
- */
- protected void setAction(int position, MenuAction action) {
- mActionList.set(position, action);
- }
-
- /**
- * Adds an action to the given position.
- * Note that action at the position may differ from returned by {@link #createActions}.
- * See {@link CustomizableOptionsRowAdapter}
- */
- protected void addAction(int position, MenuAction action) {
- mActionList.add(position, action);
- }
-
- /**
- * Removes an action at the given position.
- * Note that action at the position may differ from returned by {@link #createActions}.
- * See {@link CustomizableOptionsRowAdapter}
- */
- protected void removeAction(int position) {
- mActionList.remove(position);
- }
-
- protected int getActionSize() {
- return mActionList.size();
- }
-
@Override
public void onBindViewHolder(MyViewHolder viewHolder, int position) {
super.onBindViewHolder(viewHolder, position);
@@ -139,14 +103,4 @@ public abstract class OptionsRowAdapter extends ItemListRowView.ItemListAdapter<
// be preserved.
return mActionList.get(position).getType();
}
-
- protected void setOptionChangedListener(final MenuAction action) {
- TvOptionsManager om = getMainActivity().getTvOptionsManager();
- om.setOptionChangedListener(action.getType(), new OptionChangedListener() {
- @Override
- public void onOptionChanged(String newOption) {
- setItemList(mActionList);
- }
- });
- }
}
diff --git a/src/com/android/tv/menu/PartnerOptionsRowAdapter.java b/src/com/android/tv/menu/PartnerOptionsRowAdapter.java
index f3e09f80..c8249a4c 100644
--- a/src/com/android/tv/menu/PartnerOptionsRowAdapter.java
+++ b/src/com/android/tv/menu/PartnerOptionsRowAdapter.java
@@ -38,8 +38,7 @@ public class PartnerOptionsRowAdapter extends CustomizableOptionsRowAdapter {
}
@Override
- protected boolean updateActions() {
+ protected void updateActions() {
// TODO: Support adding description for custom actions.
- return false;
}
}
diff --git a/src/com/android/tv/menu/PipOptionsRowAdapter.java b/src/com/android/tv/menu/PipOptionsRowAdapter.java
deleted file mode 100644
index 87203e9d..00000000
--- a/src/com/android/tv/menu/PipOptionsRowAdapter.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.menu;
-
-import android.content.Context;
-import android.text.TextUtils;
-
-import com.android.tv.MainActivity;
-import com.android.tv.R;
-import com.android.tv.TvOptionsManager;
-import com.android.tv.ui.TvViewUiManager;
-import com.android.tv.ui.sidepanel.PipInputSelectorFragment;
-import com.android.tv.util.PipInputManager.PipInput;
-import com.android.tv.util.TvSettings;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/*
- * An adapter of PIP options.
- */
-public class PipOptionsRowAdapter extends OptionsRowAdapter {
- private static final int[] DRAWABLE_ID_FOR_LAYOUT = {
- R.drawable.ic_pip_option_layout1,
- R.drawable.ic_pip_option_layout2,
- R.drawable.ic_pip_option_layout3,
- R.drawable.ic_pip_option_layout4,
- R.drawable.ic_pip_option_layout5 };
-
- private final TvOptionsManager mTvOptionsManager;
- private final TvViewUiManager mTvViewUiManager;
-
- public PipOptionsRowAdapter(Context context) {
- super(context);
- mTvOptionsManager = getMainActivity().getTvOptionsManager();
- mTvViewUiManager = getMainActivity().getTvViewUiManager();
- }
-
- @Override
- protected List<MenuAction> createActions() {
- List<MenuAction> actionList = new ArrayList<>();
- actionList.add(MenuAction.PIP_SELECT_INPUT_ACTION);
- actionList.add(MenuAction.PIP_SWAP_ACTION);
- actionList.add(MenuAction.PIP_SOUND_ACTION);
- actionList.add(MenuAction.PIP_LAYOUT_ACTION);
- actionList.add(MenuAction.PIP_SIZE_ACTION);
- for (MenuAction action : actionList) {
- setOptionChangedListener(action);
- }
- return actionList;
- }
-
- @Override
- public boolean updateActions() {
- boolean changed = false;
- if (updateSelectInputAction()) {
- changed = true;
- }
- if (updateLayoutAction()) {
- changed = true;
- }
- if (updateSizeAction()) {
- changed = true;
- }
- return changed;
- }
-
- private boolean updateSelectInputAction() {
- String oldInputLabel = mTvOptionsManager.getOptionString(TvOptionsManager.OPTION_PIP_INPUT);
-
- MainActivity tvActivity = getMainActivity();
- PipInput newInput = tvActivity.getPipInputManager().getPipInput(tvActivity.getPipChannel());
- String newInputLabel = newInput == null ? null : newInput.getLabel();
-
- if (!TextUtils.equals(oldInputLabel, newInputLabel)) {
- mTvOptionsManager.onPipInputChanged(newInputLabel);
- return true;
- }
- return false;
- }
-
- private boolean updateLayoutAction() {
- return MenuAction.PIP_LAYOUT_ACTION.setDrawableResId(
- DRAWABLE_ID_FOR_LAYOUT[mTvViewUiManager.getPipLayout()]);
- }
-
- private boolean updateSizeAction() {
- boolean oldEnabled = MenuAction.PIP_SIZE_ACTION.isEnabled();
- boolean newEnabled = mTvViewUiManager.getPipLayout() != TvSettings.PIP_LAYOUT_SIDE_BY_SIDE;
- if (oldEnabled != newEnabled) {
- MenuAction.PIP_SIZE_ACTION.setEnabled(newEnabled);
- return true;
- }
- return false;
- }
-
- @Override
- protected void executeAction(int type) {
- switch (type) {
- case TvOptionsManager.OPTION_PIP_INPUT:
- getMainActivity().getOverlayManager().getSideFragmentManager().show(
- new PipInputSelectorFragment());
- break;
- case TvOptionsManager.OPTION_PIP_SWAP:
- getMainActivity().swapPip();
- break;
- case TvOptionsManager.OPTION_PIP_SOUND:
- getMainActivity().togglePipSoundMode();
- break;
- case TvOptionsManager.OPTION_PIP_LAYOUT:
- int oldLayout = mTvViewUiManager.getPipLayout();
- int newLayout = (oldLayout + 1) % (TvSettings.PIP_LAYOUT_LAST + 1);
- mTvViewUiManager.setPipLayout(newLayout, true);
- MenuAction.PIP_LAYOUT_ACTION.setDrawableResId(DRAWABLE_ID_FOR_LAYOUT[newLayout]);
- break;
- case TvOptionsManager.OPTION_PIP_SIZE:
- int oldSize = mTvViewUiManager.getPipSize();
- int newSize = (oldSize + 1) % (TvSettings.PIP_SIZE_LAST + 1);
- mTvViewUiManager.setPipSize(newSize, true);
- break;
- }
- }
-}
diff --git a/src/com/android/tv/menu/PlayControlsButton.java b/src/com/android/tv/menu/PlayControlsButton.java
index aff39db3..77715f28 100644
--- a/src/com/android/tv/menu/PlayControlsButton.java
+++ b/src/com/android/tv/menu/PlayControlsButton.java
@@ -39,6 +39,9 @@ public class PlayControlsButton extends FrameLayout {
private final int mIconColor;
private int mIconFocusedColor;
+ private int mImageResourceId;
+ private int mTintColor;
+
public PlayControlsButton(Context context) {
this(context, null);
}
@@ -67,10 +70,21 @@ public class PlayControlsButton extends FrameLayout {
* Sets the resource ID of the image to be displayed in the center of this control.
*/
public void setImageResId(int imageResId) {
- mIcon.setImageResource(imageResId);
- // Since on foucus changing, icons' color should be switched with animation,
+ int newTintColor = hasFocus() ? mIconFocusedColor : mIconColor;
+ if (mImageResourceId != imageResId) {
+ mImageResourceId = imageResId;
+ mIcon.setImageResource(imageResId);
+ updateTint(newTintColor);
+ } else if (newTintColor != mTintColor) {
+ updateTint(newTintColor);
+ }
+ }
+
+ private void updateTint(int tintColor) {
+ mTintColor = tintColor;
+ // Since on focus changing, icons' color should be switched with animation,
// as a result, selectors cannot be used to switch colors in this case.
- mIcon.getDrawable().setTint(hasFocus() ? mIconFocusedColor : mIconColor);
+ mIcon.getDrawable().setTint(tintColor);
}
/**
@@ -117,7 +131,9 @@ public class PlayControlsButton extends FrameLayout {
} else {
mIcon.setVisibility(View.GONE);
mLabel.setVisibility(View.VISIBLE);
- mLabel.setText(label);
+ if (!TextUtils.equals(mLabel.getText(), label)) {
+ mLabel.setText(label);
+ }
}
}
diff --git a/src/com/android/tv/menu/PlayControlsRowView.java b/src/com/android/tv/menu/PlayControlsRowView.java
index a620d4dd..4d766788 100644
--- a/src/com/android/tv/menu/PlayControlsRowView.java
+++ b/src/com/android/tv/menu/PlayControlsRowView.java
@@ -18,10 +18,10 @@ package com.android.tv.menu;
import android.content.Context;
import android.content.res.Resources;
+import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
@@ -34,17 +34,16 @@ import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
+import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrDataManager.OnDvrScheduleLoadFinishedListener;
import com.android.tv.dvr.DvrDataManager.ScheduledRecordingListener;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.DvrUiHelper;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.dvr.ui.DvrStopRecordingFragment;
-import com.android.tv.dvr.ui.HalfSizedDialogFragment;
+import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.menu.Menu.MenuShowReason;
import com.android.tv.ui.TunableTvView;
-import com.android.tv.util.Utils;
public class PlayControlsRowView extends MenuRowView {
private static final int NORMAL_WIDTH_MAX_BUTTON_COUNT = 5;
@@ -53,14 +52,10 @@ public class PlayControlsRowView extends MenuRowView {
private final int mTimeTextLeftMargin;
private final int mTimelineWidth;
// Views
- private View mBackgroundView;
+ private TextView mBackgroundView;
private View mTimeIndicator;
private TextView mTimeText;
- private View mProgressEmptyBefore;
- private View mProgressWatched;
- private View mProgressBuffered;
- private View mProgressEmptyAfter;
- private View mControlBar;
+ private PlaybackProgressBar mProgress;
private PlayControlsButton mJumpPreviousButton;
private PlayControlsButton mRewindButton;
private PlayControlsButton mPlayPauseButton;
@@ -69,7 +64,6 @@ public class PlayControlsRowView extends MenuRowView {
private PlayControlsButton mRecordButton;
private TextView mProgramStartTimeText;
private TextView mProgramEndTimeText;
- private View mUnavailableMessageText;
private TunableTvView mTvView;
private TimeShiftManager mTimeShiftManager;
private final DvrDataManager mDvrDataManager;
@@ -83,6 +77,8 @@ public class PlayControlsRowView extends MenuRowView {
private final int mNormalButtonMargin;
private final int mCompactButtonMargin;
+ private final String mUnavailableMessage;
+
private final ScheduledRecordingListener mScheduledRecordingListener
= new ScheduledRecordingListener() {
@Override
@@ -138,6 +134,7 @@ public class PlayControlsRowView extends MenuRowView {
mDvrManager = null;
}
mMainActivity = (MainActivity) context;
+ mUnavailableMessage = res.getString(R.string.play_controls_unavailable);
}
@Override
@@ -171,14 +168,10 @@ public class PlayControlsRowView extends MenuRowView {
super.onFinishInflate();
// Clip the ViewGroup(body) to the rounded rectangle of outline.
findViewById(R.id.body).setClipToOutline(true);
- mBackgroundView = findViewById(R.id.background);
+ mBackgroundView = (TextView) findViewById(R.id.background);
mTimeIndicator = findViewById(R.id.time_indicator);
mTimeText = (TextView) findViewById(R.id.time_text);
- mProgressEmptyBefore = findViewById(R.id.timeline_bg_start);
- mProgressWatched = findViewById(R.id.watched);
- mProgressBuffered = findViewById(R.id.buffered);
- mProgressEmptyAfter = findViewById(R.id.timeline_bg_end);
- mControlBar = findViewById(R.id.play_control_bar);
+ mProgress = (PlaybackProgressBar) findViewById(R.id.progress);
mJumpPreviousButton = (PlayControlsButton) findViewById(R.id.jump_previous);
mRewindButton = (PlayControlsButton) findViewById(R.id.rewind);
mPlayPauseButton = (PlayControlsButton) findViewById(R.id.play_pause);
@@ -187,7 +180,6 @@ public class PlayControlsRowView extends MenuRowView {
mRecordButton = (PlayControlsButton) findViewById(R.id.record);
mProgramStartTimeText = (TextView) findViewById(R.id.program_start_time);
mProgramEndTimeText = (TextView) findViewById(R.id.program_end_time);
- mUnavailableMessageText = findViewById(R.id.unavailable_text);
initializeButton(mJumpPreviousButton, R.drawable.lb_ic_skip_previous,
R.string.play_controls_description_skip_previous, null, new Runnable() {
@@ -195,7 +187,7 @@ public class PlayControlsRowView extends MenuRowView {
public void run() {
if (mTimeShiftManager.isAvailable()) {
mTimeShiftManager.jumpToPrevious();
- updateControls();
+ updateControls(true);
}
}
});
@@ -235,7 +227,7 @@ public class PlayControlsRowView extends MenuRowView {
public void run() {
if (mTimeShiftManager.isAvailable()) {
mTimeShiftManager.jumpToNext();
- updateControls();
+ updateControls(true);
}
}
});
@@ -265,18 +257,17 @@ public class PlayControlsRowView extends MenuRowView {
if (!(mDvrManager != null && mDvrManager.isChannelRecordable(currentChannel))) {
Toast.makeText(mMainActivity, R.string.dvr_msg_cannot_record_channel,
Toast.LENGTH_SHORT).show();
- } else if (DvrUiHelper.checkStorageStatusAndShowErrorMessage(mMainActivity,
- currentChannel.getInputId())) {
+ } else {
Program program = TvApplication.getSingletons(mMainActivity).getProgramDataManager()
.getCurrentProgram(currentChannel.getId());
- if (program == null) {
- DvrUiHelper.showChannelRecordDurationOptions(mMainActivity, currentChannel);
- } else if (DvrUiHelper.handleCreateSchedule(mMainActivity, program)) {
- String msg = mMainActivity.getString(R.string.dvr_msg_current_program_scheduled,
- program.getTitle(),
- Utils.toTimeString(program.getEndTimeUtcMillis(), false));
- Toast.makeText(mMainActivity, msg, Toast.LENGTH_SHORT).show();
- }
+ DvrUiHelper.checkStorageStatusAndShowErrorMessage(mMainActivity,
+ currentChannel.getInputId(), new Runnable() {
+ @Override
+ public void run() {
+ DvrUiHelper.requestRecordingCurrentProgram(mMainActivity,
+ currentChannel, program, true);
+ }
+ });
}
} else if (currentChannel != null) {
DvrUiHelper.showStopRecordingDialog(mMainActivity, currentChannel.getId(),
@@ -318,39 +309,37 @@ public class PlayControlsRowView extends MenuRowView {
@Override
public void onAvailabilityChanged() {
updateMenuVisibility();
- if (isShown()) {
- PlayControlsRowView.this.updateAll();
- }
+ PlayControlsRowView.this.updateAll(false);
}
@Override
public void onPlayStatusChanged(int status) {
updateMenuVisibility();
- if (mTimeShiftManager.isAvailable() && isShown()) {
- updateControls();
+ if (mTimeShiftManager.isAvailable()) {
+ updateControls(false);
}
}
@Override
public void onRecordTimeRangeChanged() {
- if (mTimeShiftManager.isAvailable() && isShown()) {
- updateControls();
+ if (mTimeShiftManager.isAvailable()) {
+ updateControls(false);
}
}
@Override
public void onCurrentPositionChanged() {
- if (mTimeShiftManager.isAvailable() && isShown()) {
+ if (mTimeShiftManager.isAvailable()) {
initializeTimeline();
- updateControls();
+ updateControls(false);
}
}
@Override
public void onProgramInfoChanged() {
- if (mTimeShiftManager.isAvailable() && isShown()) {
+ if (mTimeShiftManager.isAvailable()) {
initializeTimeline();
- updateControls();
+ updateControls(false);
}
}
@@ -372,7 +361,8 @@ public class PlayControlsRowView extends MenuRowView {
}
}
});
- updateAll();
+ // force update to initialize everything
+ updateAll(true);
}
private void initializeTimeline() {
@@ -380,6 +370,8 @@ public class PlayControlsRowView extends MenuRowView {
mTimeShiftManager.getCurrentPositionMs());
mProgramStartTimeMs = program.getStartTimeUtcMillis();
mProgramEndTimeMs = program.getEndTimeUtcMillis();
+ mProgress.setMax(mProgramEndTimeMs - mProgramStartTimeMs);
+ updateRecTimeText();
SoftPreconditions.checkArgument(mProgramStartTimeMs <= mProgramEndTimeMs);
}
@@ -389,10 +381,13 @@ public class PlayControlsRowView extends MenuRowView {
getMenu().setKeepVisible(keepMenuVisible);
}
+ public void onPreselected() {
+ updateControls(true);
+ }
+
@Override
public void onSelected(boolean showTitle) {
super.onSelected(showTitle);
- updateControls();
postHideRippleAnimation();
}
@@ -474,28 +469,32 @@ public class PlayControlsRowView extends MenuRowView {
* Updates the view contents. It is called from the PlayControlsRow.
*/
public void update() {
- updateAll();
+ updateAll(false);
}
- private void updateAll() {
+ private void updateAll(boolean forceUpdate) {
if (mTimeShiftManager.isAvailable() && !mTvView.isScreenBlocked()) {
setEnabled(true);
initializeTimeline();
mBackgroundView.setEnabled(true);
+ setTextIfNeeded(mBackgroundView, null);
} else {
setEnabled(false);
mBackgroundView.setEnabled(false);
+ setTextIfNeeded(mBackgroundView, mUnavailableMessage);
}
- updateControls();
+ // force the controls be updated no matter it's visible or not.
+ updateControls(forceUpdate);
}
- private void updateControls() {
- updateTime();
- updateProgress();
- updateRecTimeText();
- updateButtons();
- updateRecordButton();
- updateButtonMargin();
+ private void updateControls(boolean forceUpdate) {
+ if (forceUpdate || getContentsView().isShown()) {
+ updateTime();
+ updateProgress();
+ updateButtons();
+ updateRecordButton();
+ updateButtonMargin();
+ }
}
private void updateTime() {
@@ -504,70 +503,39 @@ public class PlayControlsRowView extends MenuRowView {
mTimeIndicator.setVisibility(View.VISIBLE);
} else {
mTimeText.setVisibility(View.INVISIBLE);
- mTimeIndicator.setVisibility(View.INVISIBLE);
+ mTimeIndicator.setVisibility(View.GONE);
return;
}
long currentPositionMs = mTimeShiftManager.getCurrentPositionMs();
- ViewGroup.MarginLayoutParams params =
- (ViewGroup.MarginLayoutParams) mTimeText.getLayoutParams();
int currentTimePositionPixel =
convertDurationToPixel(currentPositionMs - mProgramStartTimeMs);
- params.leftMargin = currentTimePositionPixel + mTimeTextLeftMargin;
- mTimeText.setLayoutParams(params);
- mTimeText.setText(getTimeString(currentPositionMs));
- params = (ViewGroup.MarginLayoutParams) mTimeIndicator.getLayoutParams();
- params.leftMargin = currentTimePositionPixel + mTimeIndicatorLeftMargin;
- mTimeIndicator.setLayoutParams(params);
+ mTimeText.setTranslationX(currentTimePositionPixel + mTimeTextLeftMargin);
+ setTextIfNeeded(mTimeText, getTimeString(currentPositionMs));
+ mTimeIndicator.setTranslationX(currentTimePositionPixel + mTimeIndicatorLeftMargin);
}
private void updateProgress() {
if (isEnabled()) {
- mProgressWatched.setVisibility(View.VISIBLE);
- mProgressBuffered.setVisibility(View.VISIBLE);
- mProgressEmptyAfter.setVisibility(View.VISIBLE);
- } else {
- mProgressWatched.setVisibility(View.INVISIBLE);
- mProgressBuffered.setVisibility(View.INVISIBLE);
- mProgressEmptyAfter.setVisibility(View.INVISIBLE);
- if (mProgramStartTimeMs < mProgramEndTimeMs) {
- layoutProgress(mProgressEmptyBefore, mProgramStartTimeMs, mProgramEndTimeMs);
- } else {
- // Not initialized yet.
- layoutProgress(mProgressEmptyBefore, mTimelineWidth);
- }
- return;
- }
-
- long progressStartTimeMs = Math.min(mProgramEndTimeMs,
+ long progressStartTimeMs = Math.min(mProgramEndTimeMs,
Math.max(mProgramStartTimeMs, mTimeShiftManager.getRecordStartTimeMs()));
- long currentPlayingTimeMs = Math.min(mProgramEndTimeMs,
+ long currentPlayingTimeMs = Math.min(mProgramEndTimeMs,
Math.max(mProgramStartTimeMs, mTimeShiftManager.getCurrentPositionMs()));
- long progressEndTimeMs = Math.min(mProgramEndTimeMs,
+ long progressEndTimeMs = Math.min(mProgramEndTimeMs,
Math.max(mProgramStartTimeMs, mTimeShiftManager.getRecordEndTimeMs()));
-
- layoutProgress(mProgressEmptyBefore, mProgramStartTimeMs, progressStartTimeMs);
- layoutProgress(mProgressWatched, progressStartTimeMs, currentPlayingTimeMs);
- layoutProgress(mProgressBuffered, currentPlayingTimeMs, progressEndTimeMs);
- }
-
- private void layoutProgress(View progress, long progressStartTimeMs, long progressEndTimeMs) {
- layoutProgress(progress, Math.max(0,
- convertDurationToPixel(progressEndTimeMs - progressStartTimeMs)) + 1);
- }
-
- private void layoutProgress(View progress, int width) {
- ViewGroup.MarginLayoutParams params =
- (ViewGroup.MarginLayoutParams) progress.getLayoutParams();
- params.width = width;
- progress.setLayoutParams(params);
+ mProgress.setProgressRange(progressStartTimeMs - mProgramStartTimeMs,
+ progressEndTimeMs - mProgramStartTimeMs);
+ mProgress.setProgress(currentPlayingTimeMs - mProgramStartTimeMs);
+ } else {
+ mProgress.setProgressRange(0, 0);
+ }
}
private void updateRecTimeText() {
if (isEnabled()) {
mProgramStartTimeText.setVisibility(View.VISIBLE);
- mProgramStartTimeText.setText(getTimeString(mProgramStartTimeMs));
+ setTextIfNeeded(mProgramStartTimeText, getTimeString(mProgramStartTimeMs));
mProgramEndTimeText.setVisibility(View.VISIBLE);
- mProgramEndTimeText.setText(getTimeString(mProgramEndTimeMs));
+ setTextIfNeeded(mProgramEndTimeText, getTimeString(mProgramEndTimeMs));
} else {
mProgramStartTimeText.setVisibility(View.GONE);
mProgramEndTimeText.setVisibility(View.GONE);
@@ -576,11 +544,17 @@ public class PlayControlsRowView extends MenuRowView {
private void updateButtons() {
if (isEnabled()) {
- mControlBar.setVisibility(View.VISIBLE);
- mUnavailableMessageText.setVisibility(View.GONE);
+ mPlayPauseButton.setVisibility(View.VISIBLE);
+ mJumpPreviousButton.setVisibility(View.VISIBLE);
+ mJumpNextButton.setVisibility(View.VISIBLE);
+ mRewindButton.setVisibility(View.VISIBLE);
+ mFastForwardButton.setVisibility(View.VISIBLE);
} else {
- mControlBar.setVisibility(View.INVISIBLE);
- mUnavailableMessageText.setVisibility(View.VISIBLE);
+ mPlayPauseButton.setVisibility(View.GONE);
+ mJumpPreviousButton.setVisibility(View.GONE);
+ mJumpNextButton.setVisibility(View.GONE);
+ mRewindButton.setVisibility(View.GONE);
+ mFastForwardButton.setVisibility(View.GONE);
return;
}
@@ -622,6 +596,12 @@ public class PlayControlsRowView extends MenuRowView {
}
private void updateRecordButton() {
+ if (isEnabled()) {
+ mRecordButton.setVisibility(VISIBLE);
+ } else {
+ mRecordButton.setVisibility(GONE);
+ return;
+ }
if (!(mDvrManager != null
&& mDvrManager.isChannelRecordable(mMainActivity.getCurrentChannel()))) {
mRecordButton.setVisibility(View.GONE);
@@ -682,4 +662,10 @@ public class PlayControlsRowView extends MenuRowView {
mDvrDataManager.removeScheduledRecordingListener(mScheduledRecordingListener);
}
}
+
+ private void setTextIfNeeded(TextView textView, String text) {
+ if (!TextUtils.equals(textView.getText(), text)) {
+ textView.setText(text);
+ }
+ }
}
diff --git a/src/com/android/tv/menu/PlaybackProgressBar.java b/src/com/android/tv/menu/PlaybackProgressBar.java
new file mode 100644
index 00000000..e8061bc6
--- /dev/null
+++ b/src/com/android/tv/menu/PlaybackProgressBar.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 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.tv.menu;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.tv.R;
+
+/**
+ * A progress bar control which has two progresses which start in the middle of the control.
+ */
+public class PlaybackProgressBar extends View {
+ private final LayerDrawable mProgressDrawable;
+ private final Drawable mPrimaryDrawable;
+ private final Drawable mSecondaryDrawable;
+ private long mMax = 100;
+ private long mProgressStart = 0;
+ private long mProgressEnd = 0;
+ private long mProgress = 0;
+
+ public PlaybackProgressBar(Context context) {
+ this(context, null);
+ }
+
+ public PlaybackProgressBar(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public PlaybackProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public PlaybackProgressBar(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.PlaybackProgressBar, defStyleAttr, defStyleRes);
+ mProgressDrawable =
+ (LayerDrawable) a.getDrawable(R.styleable.PlaybackProgressBar_progressDrawable);
+ mPrimaryDrawable = mProgressDrawable.findDrawableByLayerId(android.R.id.progress);
+ mSecondaryDrawable =
+ mProgressDrawable.findDrawableByLayerId(android.R.id.secondaryProgress);
+ a.recycle();
+ refreshProgress();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ final int saveCount = canvas.save();
+ canvas.translate(getPaddingLeft(), getPaddingTop());
+ mProgressDrawable.draw(canvas);
+ canvas.restoreToCount(saveCount);
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ refreshProgress();
+ }
+
+ public void setMax(long max) {
+ if (max < 0) {
+ max = 0;
+ }
+ if (max != mMax) {
+ mMax = max;
+ if (mProgressStart > max) {
+ mProgressStart = max;
+ }
+ if (mProgressEnd > max) {
+ mProgressEnd = max;
+ }
+ if (mProgress > max) {
+ mProgress = max;
+ }
+ refreshProgress();
+ }
+ }
+
+ /**
+ * Sets the start and end position of the progress.
+ */
+ public void setProgressRange(long start, long end) {
+ start = constrain(start, 0, mMax);
+ end = constrain(end, start, mMax);
+ mProgress = constrain(mProgress, start, end);
+ if (start != mProgressStart || end != mProgressEnd) {
+ mProgressStart = start;
+ mProgressEnd = end;
+ setProgressLevels();
+ }
+ }
+
+ /**
+ * Sets the progress position.
+ */
+ public void setProgress(long progress) {
+ progress = constrain(progress, mProgressStart, mProgressEnd);
+ if (progress != mProgress) {
+ mProgress = progress;
+ setProgressLevels();
+ }
+ }
+
+ private long constrain(long value, long min, long max) {
+ return Math.min(Math.max(value, min), max);
+ }
+
+ private void refreshProgress() {
+ int width = getWidth() - getPaddingStart() - getPaddingEnd();
+ int height = getHeight() - getPaddingTop() - getPaddingBottom();
+ mProgressDrawable.setBounds(0, 0, width, height);
+ setProgressLevels();
+ }
+
+ private void setProgressLevels() {
+ boolean progressUpdated = setProgressBound(mPrimaryDrawable, mProgressStart, mProgress);
+ progressUpdated |= setProgressBound(mSecondaryDrawable, mProgress, mProgressEnd);
+ if (progressUpdated) {
+ postInvalidate();
+ }
+ }
+
+ private boolean setProgressBound(Drawable drawable, long start, long end) {
+ Rect oldBounds = drawable.getBounds();
+ if (mMax == 0) {
+ if (!isEqualRect(oldBounds, 0, 0, 0, 0)) {
+ drawable.setBounds(0, 0, 0, 0);
+ return true;
+ }
+ return false;
+ }
+ int width = mProgressDrawable.getBounds().width();
+ int height = mProgressDrawable.getBounds().height();
+ int left = (int) (width * start / mMax);
+ int right = (int) (width * end / mMax);
+ if (!isEqualRect(oldBounds, left, 0, right, height)) {
+ drawable.setBounds(left, 0, right, height);
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isEqualRect(Rect rect, int left, int top, int right, int bottom) {
+ return rect.left == left && rect.top == top && rect.right == right && rect.bottom == bottom;
+ }
+}
diff --git a/src/com/android/tv/menu/SimpleCardView.java b/src/com/android/tv/menu/SimpleCardView.java
index c99834be..fc5192da 100644
--- a/src/com/android/tv/menu/SimpleCardView.java
+++ b/src/com/android/tv/menu/SimpleCardView.java
@@ -19,12 +19,10 @@ package com.android.tv.menu;
import android.content.Context;
import android.util.AttributeSet;
-import com.android.tv.data.Channel;
-
/**
* A view to render a guide card.
*/
-public class SimpleCardView extends BaseCardView<Channel> {
+public class SimpleCardView extends BaseCardView<ChannelsRowItem> {
public SimpleCardView(Context context) {
this(context, null, 0);
diff --git a/src/com/android/tv/menu/TvOptionsRowAdapter.java b/src/com/android/tv/menu/TvOptionsRowAdapter.java
index fb062246..6e035f22 100644
--- a/src/com/android/tv/menu/TvOptionsRowAdapter.java
+++ b/src/com/android/tv/menu/TvOptionsRowAdapter.java
@@ -21,7 +21,6 @@ import android.media.tv.TvTrackInfo;
import android.support.annotation.VisibleForTesting;
import com.android.tv.Features;
-import com.android.tv.R;
import com.android.tv.TvOptionsManager;
import com.android.tv.customization.CustomAction;
import com.android.tv.data.DisplayMode;
@@ -30,7 +29,7 @@ import com.android.tv.ui.sidepanel.ClosedCaptionFragment;
import com.android.tv.ui.sidepanel.DeveloperOptionFragment;
import com.android.tv.ui.sidepanel.DisplayModeFragment;
import com.android.tv.ui.sidepanel.MultiAudioFragment;
-import com.android.tv.util.PipInputManager;
+import com.android.tv.util.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -39,12 +38,6 @@ import java.util.List;
* An adapter of options.
*/
public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
- private static final boolean ENABLE_IN_APP_PIP = false;
-
- private int mPositionPipAction;
- // If mInAppPipAction is false, system-wide PIP is used.
- private boolean mInAppPipAction = true;
-
public TvOptionsRowAdapter(Context context, List<CustomAction> customActions) {
super(context, customActions);
}
@@ -53,123 +46,73 @@ public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
protected List<MenuAction> createBaseActions() {
List<MenuAction> actionList = new ArrayList<>();
actionList.add(MenuAction.SELECT_CLOSED_CAPTION_ACTION);
- setOptionChangedListener(MenuAction.SELECT_CLOSED_CAPTION_ACTION);
actionList.add(MenuAction.SELECT_DISPLAY_MODE_ACTION);
- setOptionChangedListener(MenuAction.SELECT_DISPLAY_MODE_ACTION);
- actionList.add(MenuAction.PIP_IN_APP_ACTION);
- setOptionChangedListener(MenuAction.PIP_IN_APP_ACTION);
- mPositionPipAction = actionList.size() - 1;
+ if (Features.PICTURE_IN_PICTURE.isEnabled(getMainActivity())) {
+ actionList.add(MenuAction.SYSTEMWIDE_PIP_ACTION);
+ }
actionList.add(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION);
- setOptionChangedListener(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION);
actionList.add(MenuAction.MORE_CHANNELS_ACTION);
- if (DeveloperOptionFragment.shouldShow()) {
+ if (Utils.isDeveloper()) {
actionList.add(MenuAction.DEV_ACTION);
}
actionList.add(MenuAction.SETTINGS_ACTION);
- if (getCustomActions() != null) {
- // Adjust Pip action position which will be changed by applying custom actions.
- for (CustomAction customAction : getCustomActions()) {
- if (customAction.isFront()) {
- mPositionPipAction++;
- }
- }
- }
-
+ updateClosedCaptionAction();
+ updatePipAction();
+ updateMultiAudioAction();
+ updateDisplayModeAction();
return actionList;
}
@Override
- protected boolean updateActions() {
- boolean changed = false;
+ protected void updateActions() {
+ if (updateClosedCaptionAction()) {
+ notifyItemChanged(getItemPosition(MenuAction.SELECT_CLOSED_CAPTION_ACTION));
+ }
if (updatePipAction()) {
- changed = true;
+ notifyItemChanged(getItemPosition(MenuAction.SYSTEMWIDE_PIP_ACTION));
}
if (updateMultiAudioAction()) {
- changed = true;
+ notifyItemChanged(getItemPosition(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION));
}
if (updateDisplayModeAction()) {
- changed = true;
+ notifyItemChanged(getItemPosition(MenuAction.SELECT_DISPLAY_MODE_ACTION));
}
- return changed;
}
- private boolean updatePipAction() {
- // There are four states.
- // Case 1. The device doesn't even have any input for PIP. (e.g. OTT box without HDMI input)
- // => Remove the icon.
- // Case 2. The device has one or more inputs for PIP but none of them are currently
- // available.
- // => Show the icon but disable it.
- // Case 3. The device has one or more available PIP inputs and now it's tuned off.
- // => Show the icon with "Off".
- // Case 4. The device has one or more available PIP inputs but it's already turned on.
- // => Show the icon with "On".
-
- boolean changed = false;
-
- // Case 1
- PipInputManager pipInputManager = getMainActivity().getPipInputManager();
- if (ENABLE_IN_APP_PIP && pipInputManager.getPipInputSize(false) > 1) {
- if (!mInAppPipAction) {
- removeAction(mPositionPipAction);
- addAction(mPositionPipAction, MenuAction.PIP_IN_APP_ACTION);
- mInAppPipAction = true;
- changed = true;
- }
- } else {
- if (mInAppPipAction) {
- removeAction(mPositionPipAction);
- mInAppPipAction = false;
- if (Features.PICTURE_IN_PICTURE.isEnabled(getMainActivity())) {
- addAction(mPositionPipAction, MenuAction.SYSTEMWIDE_PIP_ACTION);
- }
- return true;
- }
- return false;
- }
+ @VisibleForTesting
+ private boolean updateClosedCaptionAction() {
+ return updateActionDescription(MenuAction.SELECT_CLOSED_CAPTION_ACTION);
+ }
- // Case 2
- boolean isPipEnabled = getMainActivity().isPipEnabled();
- boolean oldEnabled = MenuAction.PIP_IN_APP_ACTION.isEnabled();
- boolean newEnabled = pipInputManager.getPipInputSize(true) > 0;
- if (oldEnabled != newEnabled) {
- // Should not disable the item if the PIP is already turned on so that the user can
- // force exit it.
- if (newEnabled || !isPipEnabled) {
- MenuAction.PIP_IN_APP_ACTION.setEnabled(newEnabled);
- changed = true;
- }
+ private boolean updatePipAction() {
+ if (containsItem(MenuAction.SYSTEMWIDE_PIP_ACTION)) {
+ return MenuAction.setEnabled(MenuAction.SYSTEMWIDE_PIP_ACTION,
+ !getMainActivity().isScreenBlockedByResourceConflictOrParentalControl());
}
-
- // Case 3 & 4 - we just need to update the icon.
- MenuAction.PIP_IN_APP_ACTION.setDrawableResId(
- isPipEnabled ? R.drawable.ic_tvoption_pip : R.drawable.ic_tvoption_pip_off);
- return changed;
+ return false;
}
- @VisibleForTesting
boolean updateMultiAudioAction() {
List<TvTrackInfo> audioTracks = getMainActivity().getTracks(TvTrackInfo.TYPE_AUDIO);
- boolean oldEnabled = MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled();
- boolean newEnabled = audioTracks != null && audioTracks.size() > 1;
- if (oldEnabled != newEnabled) {
- MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.setEnabled(newEnabled);
- return true;
- }
- return false;
+ boolean enabled = audioTracks != null && audioTracks.size() > 1;
+ // Use "|" operator for non-short-circuit evaluation.
+ return MenuAction.setEnabled(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION, enabled)
+ | updateActionDescription(MenuAction.SELECT_AUDIO_LANGUAGE_ACTION);
}
private boolean updateDisplayModeAction() {
TvViewUiManager uiManager = getMainActivity().getTvViewUiManager();
- boolean oldEnabled = MenuAction.SELECT_DISPLAY_MODE_ACTION.isEnabled();
- boolean newEnabled = uiManager.isDisplayModeAvailable(DisplayMode.MODE_FULL)
+ boolean enabled = uiManager.isDisplayModeAvailable(DisplayMode.MODE_FULL)
|| uiManager.isDisplayModeAvailable(DisplayMode.MODE_ZOOM);
- if (oldEnabled != newEnabled) {
- MenuAction.SELECT_DISPLAY_MODE_ACTION.setEnabled(newEnabled);
- return true;
- }
- return false;
+ // Use "|" operator for non-short-circuit evaluation.
+ return MenuAction.setEnabled(MenuAction.SELECT_DISPLAY_MODE_ACTION, enabled)
+ | updateActionDescription(MenuAction.SELECT_DISPLAY_MODE_ACTION);
+ }
+
+ private boolean updateActionDescription(MenuAction action) {
+ return MenuAction.setActionDescription(action,
+ getMainActivity().getTvOptionsManager().getOptionString(action.getType()));
}
@Override
@@ -183,9 +126,6 @@ public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
getMainActivity().getOverlayManager().getSideFragmentManager()
.show(new DisplayModeFragment());
break;
- case TvOptionsManager.OPTION_IN_APP_PIP:
- getMainActivity().togglePipView();
- break;
case TvOptionsManager.OPTION_SYSTEMWIDE_PIP:
getMainActivity().enterPictureInPictureMode();
break;
@@ -205,4 +145,4 @@ public class TvOptionsRowAdapter extends CustomizableOptionsRowAdapter {
break;
}
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/onboarding/SetupSourcesFragment.java b/src/com/android/tv/onboarding/SetupSourcesFragment.java
index 7607822c..f56daec5 100644
--- a/src/com/android/tv/onboarding/SetupSourcesFragment.java
+++ b/src/com/android/tv/onboarding/SetupSourcesFragment.java
@@ -38,6 +38,7 @@ import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.TvInputNewComparator;
+import com.android.tv.tuner.TunerInputController;
import com.android.tv.ui.GuidedActionsStylistWithDivider;
import com.android.tv.util.SetupUtils;
import com.android.tv.util.TvInputManagerHelper;
@@ -204,6 +205,7 @@ public class SetupSourcesFragment extends SetupMultiPaneFragment {
mChannelDataManager.addListener(mChannelDataManagerListener);
super.onCreate(savedInstanceState);
mParentFragment = (SetupSourcesFragment) getParentFragment();
+ TunerInputController.executeNetworkTunerDiscoveryAsyncTask(getContext());
}
@Override
diff --git a/src/com/android/tv/parental/ContentRatingSystem.java b/src/com/android/tv/parental/ContentRatingSystem.java
index 6b5d6635..5672b793 100644
--- a/src/com/android/tv/parental/ContentRatingSystem.java
+++ b/src/com/android/tv/parental/ContentRatingSystem.java
@@ -110,6 +110,15 @@ public class ContentRatingSystem {
return mRatings;
}
+ public Rating getRating(String name) {
+ for (Rating rating : mRatings) {
+ if (TextUtils.equals(rating.getName(), name)) {
+ return rating;
+ }
+ }
+ return null;
+ }
+
public List<SubRating> getSubRatings(){
return mSubRatings;
}
diff --git a/src/com/android/tv/parental/ContentRatingsManager.java b/src/com/android/tv/parental/ContentRatingsManager.java
index 57c25f48..c3bb8c0f 100644
--- a/src/com/android/tv/parental/ContentRatingsManager.java
+++ b/src/com/android/tv/parental/ContentRatingsManager.java
@@ -20,7 +20,10 @@ import android.content.Context;
import android.media.tv.TvContentRating;
import android.media.tv.TvContentRatingSystemInfo;
import android.media.tv.TvInputManager;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import com.android.tv.R;
import com.android.tv.parental.ContentRatingSystem.Rating;
import com.android.tv.parental.ContentRatingSystem.SubRating;
@@ -53,6 +56,19 @@ public class ContentRatingsManager {
}
/**
+ * Returns the content rating system with the give ID.
+ */
+ @Nullable
+ public ContentRatingSystem getContentRatingSystem(String contentRatingSystemId) {
+ for (ContentRatingSystem ratingSystem : mContentRatingSystems) {
+ if (TextUtils.equals(ratingSystem.getId(), contentRatingSystemId)) {
+ return ratingSystem;
+ }
+ }
+ return null;
+ }
+
+ /**
* Returns a new list of all content rating systems defined.
*/
public List<ContentRatingSystem> getContentRatingSystems() {
@@ -64,6 +80,9 @@ public class ContentRatingsManager {
* displayed to the user. For example, "TV-PG (L, S)".
*/
public String getDisplayNameForRating(TvContentRating canonicalRating) {
+ if (TvContentRating.UNRATED.equals(canonicalRating)) {
+ return mContext.getResources().getString(R.string.unrated_rating_name);
+ }
Rating rating = getRating(canonicalRating);
if (rating == null) {
return null;
diff --git a/src/com/android/tv/parental/ParentalControlSettings.java b/src/com/android/tv/parental/ParentalControlSettings.java
index d7e1846e..2471c565 100644
--- a/src/com/android/tv/parental/ParentalControlSettings.java
+++ b/src/com/android/tv/parental/ParentalControlSettings.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputManager;
+import com.android.tv.experiments.Experiments;
import com.android.tv.parental.ContentRatingSystem.Rating;
import com.android.tv.parental.ContentRatingSystem.SubRating;
import com.android.tv.util.TvSettings;
@@ -109,6 +110,10 @@ public class ParentalControlSettings {
@ContentRatingLevel int currentLevel = getContentRatingLevel();
if (currentLevel != TvSettings.CONTENT_RATING_LEVEL_CUSTOM) {
mRatings = ContentRatingLevelPolicy.getRatingsForLevel(this, manager, currentLevel);
+ if (currentLevel != TvSettings.CONTENT_RATING_LEVEL_NONE) {
+ // UNRATED contents should be blocked unless the rating level is none or custom
+ mRatings.add(TvContentRating.UNRATED);
+ }
storeRatings();
}
}
@@ -129,6 +134,11 @@ public class ParentalControlSettings {
}
} else {
mRatings = ContentRatingLevelPolicy.getRatingsForLevel(this, manager, level);
+ if (level != TvSettings.CONTENT_RATING_LEVEL_NONE
+ && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
+ // UNRATED contents should be blocked unless the rating level is none or custom
+ mRatings.add(TvContentRating.UNRATED);
+ }
}
storeRatings();
}
@@ -138,6 +148,23 @@ public class ParentalControlSettings {
return TvSettings.getContentRatingLevel(mContext);
}
+ /** Sets the blocked status of a unrated contents. */
+ public boolean setUnratedBlocked(boolean blocked) {
+ boolean changed;
+ if (blocked) {
+ changed = mRatings.add(TvContentRating.UNRATED);
+ mTvInputManager.addBlockedRating(TvContentRating.UNRATED);
+ } else {
+ changed = mRatings.remove(TvContentRating.UNRATED);
+ mTvInputManager.removeBlockedRating(TvContentRating.UNRATED);
+ }
+ if (changed) {
+ // change to custom level if the blocked status is changed
+ changeToCustomLevel();
+ }
+ return changed;
+ }
+
/**
* Sets the blocked status of a given content rating.
* <p>
@@ -172,8 +199,10 @@ public class ParentalControlSettings {
* @return The {@link TvContentRating} that is blocked.
*/
public TvContentRating getBlockedRating(TvContentRating[] ratings) {
- if (ratings == null) {
- return null;
+ if (ratings == null || ratings.length <= 0) {
+ return mTvInputManager.isRatingBlocked(TvContentRating.UNRATED)
+ ? TvContentRating.UNRATED
+ : null;
}
for (TvContentRating rating : ratings) {
if (mTvInputManager.isRatingBlocked(rating)) {
diff --git a/src/com/android/tv/perf/EventNames.java b/src/com/android/tv/perf/EventNames.java
new file mode 100644
index 00000000..6026897b
--- /dev/null
+++ b/src/com/android/tv/perf/EventNames.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 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.tv.perf;
+
+import android.support.annotation.StringDef;
+
+import java.lang.annotation.Retention;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Constants for performance event names.
+ *
+ * <p>Only constants are used to insure no PII is sent.
+ *
+ */
+public final class EventNames {
+
+ @Retention(SOURCE)
+ @StringDef({
+ APPLICATION_ONCREATE,
+ FETCH_EPG_TASK,
+ MAIN_ACTIVITY_ONCREATE,
+ MAIN_ACTIVITY_ONSTART,
+ MAIN_ACTIVITY_ONRESUME,
+ ON_DEVICE_SEARCH
+ })
+ public @interface EventName {}
+
+ public static final String APPLICATION_ONCREATE = "Application.onCreate";
+ public static final String FETCH_EPG_TASK = "FetchEpgTask";
+ public static final String MAIN_ACTIVITY_ONCREATE = "MainActivity.onCreate";
+ public static final String MAIN_ACTIVITY_ONSTART = "MainActivity.onStart";
+ public static final String MAIN_ACTIVITY_ONRESUME = "MainActivity.onResume";
+ /**
+ * Event name for query running time of on-device search in
+ * {@link com.android.tv.search.LocalSearchProvider}.
+ */
+ public static final String ON_DEVICE_SEARCH = "OnDeviceSearch";
+
+ private EventNames() {}
+}
diff --git a/src/com/android/tv/perf/PerformanceMonitor.java b/src/com/android/tv/perf/PerformanceMonitor.java
new file mode 100644
index 00000000..40368b41
--- /dev/null
+++ b/src/com/android/tv/perf/PerformanceMonitor.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 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.tv.perf;
+
+import android.content.Context;
+
+import static com.android.tv.perf.EventNames.EventName;
+
+/** Measures Performance. */
+public interface PerformanceMonitor {
+
+ /**
+ * Starts monitoring application's lifecylce for interesting memory events, captures and records
+ * memory usage data whenever these events are fired.
+ */
+ void startMemoryMonitor();
+
+ /**
+ * Collects and records memory usage for a specific custom event
+ *
+ * @param eventName to record
+ */
+ void recordMemory(@EventName String eventName);
+
+ /**
+ * Starts a timer for a global event to allow measuring the event's latency across activities If
+ * multiple events with the same name are started, only the last event is retained.
+ *
+ * @param eventName for which the timer starts
+ */
+ void startGlobalTimer(@EventName String eventName);
+
+ /**
+ * Stops a cross activities timer for a specific eventName and records the timer duration. If no
+ * timer found for the event specified an error will be logged, and recording will be skipped.
+ *
+ * @param eventName for which the timer stops
+ */
+ void stopGlobalTimer(@EventName String eventName);
+
+ /**
+ * Starts a timer to record latency of a specific scenario or event. Use this method to track
+ * latency in the same method/class
+ *
+ * @return TimerEvent object to be used for stopping/recording the timer for a specific event.
+ * If PerformanceMonitor is not initialized for any reason, an empty TimerEvent will be
+ * returned.
+ */
+ TimerEvent startTimer();
+
+
+ /**
+ * Stops timer for a specific event and records the timer duration. passing a null TimerEvent
+ * will cause this operation to be skipped.
+ *
+ * @param event that needs to be stopped
+ * @param eventName for which the timer stops. This must be constant with no PII.
+ */
+ void stopTimer(TimerEvent event, @EventName String eventName);
+
+ /**
+ * Starts recording jank for a specific scenario or event.
+ *
+ * <p>If jank recording was started already for an event with the current name, but was never
+ * stopped, the previously recorded event will be skipped.
+ *
+ * @param eventName of the event for which tracking is started
+ */
+ void startJankRecorder(@EventName String eventName);
+
+ /**
+ * Stops recording jank for a specific event and records the jank event.
+ *
+ * @param eventName of the event that needs to be stopped
+ */
+ void stopJankRecorder(@EventName String eventName);
+
+ /**
+ * Starts activity to display PerformanceMonitor events recorded in local database for debug
+ * purpose.
+ *
+ * @return true if the activity is available to start
+ */
+ boolean startPerformanceMonitorEventDebugActivity(Context context);
+}
diff --git a/src/com/android/tv/perf/StubPerformanceMonitor.java b/src/com/android/tv/perf/StubPerformanceMonitor.java
new file mode 100644
index 00000000..3742a2a7
--- /dev/null
+++ b/src/com/android/tv/perf/StubPerformanceMonitor.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 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.tv.perf;
+
+import android.app.Application;
+import android.content.Context;
+
+/** Do nothing implementation of {@link PerformanceMonitor}. */
+public final class StubPerformanceMonitor implements PerformanceMonitor {
+
+ private static final TimerEvent TIMER_EVENT = new TimerEvent() {};
+
+ public static PerformanceMonitor initialize(Application app) {
+ return new StubPerformanceMonitor();
+ }
+
+ @Override
+ public void startMemoryMonitor() {}
+
+ @Override
+ public void recordMemory(String customEventName) {}
+
+ @Override
+ public void startGlobalTimer(String customEventName) {}
+
+ @Override
+ public void stopGlobalTimer(String customEventName) {}
+
+ @Override
+ public TimerEvent startTimer() {
+ return TIMER_EVENT;
+ }
+
+ @Override
+ public void stopTimer(TimerEvent event, String name) {}
+
+ @Override
+ public void startJankRecorder(String eventName) {}
+
+ @Override
+ public void stopJankRecorder(String eventName) {}
+
+ @Override
+ public boolean startPerformanceMonitorEventDebugActivity(Context context) {
+ return false;
+ }
+
+ public static TimerEvent startBootstrapTimer() {
+ return new TimerEvent() {};
+ }
+}
diff --git a/src/com/android/tv/perf/TimerEvent.java b/src/com/android/tv/perf/TimerEvent.java
new file mode 100644
index 00000000..f8ac6b2d
--- /dev/null
+++ b/src/com/android/tv/perf/TimerEvent.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 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.tv.perf;
+
+/** An event to time */
+public interface TimerEvent {}
diff --git a/src/com/android/tv/receiver/BootCompletedReceiver.java b/src/com/android/tv/receiver/BootCompletedReceiver.java
index 8d6c5a14..369e7d54 100644
--- a/src/com/android/tv/receiver/BootCompletedReceiver.java
+++ b/src/com/android/tv/receiver/BootCompletedReceiver.java
@@ -21,13 +21,15 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.util.Log;
import com.android.tv.Features;
import com.android.tv.TvActivity;
import com.android.tv.TvApplication;
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.dvr.DvrRecordingService;
+import com.android.tv.dvr.recorder.DvrRecordingService;
+import com.android.tv.dvr.recorder.RecordingScheduler;
+import com.android.tv.recommendation.ChannelPreviewUpdater;
import com.android.tv.recommendation.NotificationService;
import com.android.tv.util.OnboardingUtils;
import com.android.tv.util.SetupUtils;
@@ -49,12 +51,20 @@ public class BootCompletedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
+ if (!TvApplication.getSingletons(context).getTvInputManagerHelper().hasTvInputManager()) {
+ Log.wtf(TAG, "Stopping because device does not have a TvInputManager");
+ return;
+ }
if (DEBUG) Log.d(TAG, "boot completed " + intent);
TvApplication.setCurrentRunningProcess(context, true);
- // Start {@link NotificationService}.
- Intent notificationIntent = new Intent(context, NotificationService.class);
- notificationIntent.setAction(NotificationService.ACTION_SHOW_RECOMMENDATION);
- context.startService(notificationIntent);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ ChannelPreviewUpdater.getInstance(context).updatePreviewDataForChannelsImmediately();
+ } else {
+ Intent notificationIntent = new Intent(context, NotificationService.class);
+ notificationIntent.setAction(NotificationService.ACTION_SHOW_RECOMMENDATION);
+ context.startService(notificationIntent);
+ }
// Grant permission to already set up packages after the system has finished booting.
SetupUtils.grantEpgPermissionToSetUpPackages(context);
@@ -74,8 +84,9 @@ public class BootCompletedReceiver extends BroadcastReceiver {
}
}
- if (CommonFeatures.DVR.isEnabled(context)) {
- DvrRecordingService.startService(context);
+ RecordingScheduler scheduler = TvApplication.getSingletons(context).getRecordingScheduler();
+ if (scheduler != null) {
+ scheduler.updateAndStartServiceIfNeeded();
}
}
}
diff --git a/src/com/android/tv/receiver/GlobalKeyReceiver.java b/src/com/android/tv/receiver/GlobalKeyReceiver.java
index 8cd4fdf1..cc8e76c4 100644
--- a/src/com/android/tv/receiver/GlobalKeyReceiver.java
+++ b/src/com/android/tv/receiver/GlobalKeyReceiver.java
@@ -19,7 +19,8 @@ package com.android.tv.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.media.tv.TvContract;
+import android.os.AsyncTask;
+import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
@@ -31,27 +32,64 @@ import com.android.tv.TvApplication;
public class GlobalKeyReceiver extends BroadcastReceiver {
private static final boolean DEBUG = false;
private static final String TAG = "GlobalKeyReceiver";
+
private static final String ACTION_GLOBAL_BUTTON = "android.intent.action.GLOBAL_BUTTON";
+ // Settings.Secure.USER_SETUP_COMPLETE is hidden.
+ private static final String SETTINGS_USER_SETUP_COMPLETE = "user_setup_complete";
+
+ private static long sLastEventTime;
+ private static boolean sUserSetupComplete;
@Override
public void onReceive(Context context, Intent intent) {
+ if (!TvApplication.getSingletons(context).getTvInputManagerHelper().hasTvInputManager()) {
+ Log.wtf(TAG, "Stopping because device does not have a TvInputManager");
+ return;
+ }
TvApplication.setCurrentRunningProcess(context, true);
+ Context appContext = context.getApplicationContext();
+ if (DEBUG) Log.d(TAG, "onReceive: " + intent);
+ if (sUserSetupComplete) {
+ handleIntent(appContext, intent);
+ } else {
+ new AsyncTask<Void, Void, Boolean>() {
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ return Settings.Secure.getInt(appContext.getContentResolver(),
+ SETTINGS_USER_SETUP_COMPLETE, 0) != 0;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean setupComplete) {
+ if (DEBUG) Log.d(TAG, "Is setup complete: " + setupComplete);
+ sUserSetupComplete = setupComplete;
+ if (sUserSetupComplete) {
+ handleIntent(appContext, intent);
+ }
+ }
+ }.execute();
+ }
+ }
+
+ private void handleIntent(Context appContext, Intent intent) {
if (ACTION_GLOBAL_BUTTON.equals(intent.getAction())) {
KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
- if (DEBUG) Log.d(TAG, "onReceive: " + event);
+ if (DEBUG) Log.d(TAG, "handleIntent: " + event);
int keyCode = event.getKeyCode();
int action = event.getAction();
- if (action == KeyEvent.ACTION_UP) {
+ long eventTime = event.getEventTime();
+ if (action == KeyEvent.ACTION_UP && sLastEventTime != eventTime) {
+ // Workaround for b/23947504, the same key event may be sent twice, filter it.
+ sLastEventTime = eventTime;
switch (keyCode) {
case KeyEvent.KEYCODE_GUIDE:
- context.startActivity(
- new Intent(Intent.ACTION_VIEW, TvContract.Programs.CONTENT_URI));
+ ((TvApplication) appContext).handleGuideKey();
break;
case KeyEvent.KEYCODE_TV:
- ((TvApplication) context.getApplicationContext()).handleTvKey();
+ ((TvApplication) appContext).handleTvKey();
break;
case KeyEvent.KEYCODE_TV_INPUT:
- ((TvApplication) context.getApplicationContext()).handleTvInputKey();
+ ((TvApplication) appContext).handleTvInputKey();
break;
default:
// Do nothing
diff --git a/src/com/android/tv/receiver/PackageIntentsReceiver.java b/src/com/android/tv/receiver/PackageIntentsReceiver.java
index 26d000e7..124172f0 100644
--- a/src/com/android/tv/receiver/PackageIntentsReceiver.java
+++ b/src/com/android/tv/receiver/PackageIntentsReceiver.java
@@ -19,17 +19,29 @@ package com.android.tv.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
import com.android.tv.TvApplication;
+import com.android.tv.util.Partner;
/**
* A class for handling the broadcast intents from PackageManager.
*/
public class PackageIntentsReceiver extends BroadcastReceiver {
+ private static final String TAG = "PackageIntentsReceiver";
@Override
public void onReceive(Context context, Intent intent) {
+ if (!TvApplication.getSingletons(context).getTvInputManagerHelper().hasTvInputManager()) {
+ Log.wtf(TAG, "Stopping because device does not have a TvInputManager");
+ return;
+ }
TvApplication.setCurrentRunningProcess(context, true);
((TvApplication) context.getApplicationContext()).handleInputCountChanged();
+
+ Uri uri = intent.getData();
+ final String packageName = (uri != null ? uri.getSchemeSpecificPart() : null);
+ Partner.reset(context, packageName);
}
}
diff --git a/src/com/android/tv/recommendation/ChannelPreviewUpdater.java b/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
new file mode 100644
index 00000000..2709ebe1
--- /dev/null
+++ b/src/com/android/tv/recommendation/ChannelPreviewUpdater.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2017 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.tv.recommendation;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.support.media.tv.TvContractCompat;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.TvApplication;
+import com.android.tv.data.Channel;
+import com.android.tv.data.PreviewDataManager;
+import com.android.tv.data.PreviewProgramContent;
+import com.android.tv.data.Program;
+import com.android.tv.parental.ParentalControlSettings;
+import com.android.tv.util.Utils;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/** Class for updating the preview programs for {@link Channel}. */
+@RequiresApi(Build.VERSION_CODES.O)
+public class ChannelPreviewUpdater {
+ private static final String TAG = "ChannelPreviewUpdater";
+ // STOPSHIP: set it to false.
+ private static final boolean DEBUG = true;
+
+ private static final int UPATE_PREVIEW_PROGRAMS_JOB_ID = 1000001;
+ private static final long ROUTINE_INTERVAL_MS = TimeUnit.MINUTES.toMillis(10);
+ // The left time of a program should meet the threshold so that it could be recommended.
+ private static final long RECOMMENDATION_THRESHOLD_LEFT_TIME_MS =
+ TimeUnit.MINUTES.toMillis(10);
+ private static final int RECOMMENDATION_THRESHOLD_PROGRESS = 90; // 90%
+ private static final int RECOMMENDATION_COUNT = 6;
+ private static final int MIN_COUNT_TO_ADD_ROW = 4;
+
+ private static ChannelPreviewUpdater sChannelPreviewUpdater;
+
+ /**
+ * Creates and returns the {@link ChannelPreviewUpdater}.
+ */
+ public static ChannelPreviewUpdater getInstance(Context context) {
+ if (sChannelPreviewUpdater == null) {
+ sChannelPreviewUpdater = new ChannelPreviewUpdater(context.getApplicationContext());
+ }
+ return sChannelPreviewUpdater;
+ }
+
+ private final Context mContext;
+ private final Recommender mRecommender;
+ private final PreviewDataManager mPreviewDataManager;
+ private JobService mJobService;
+ private JobParameters mJobParams;
+
+ private final ParentalControlSettings mParentalControlSettings;
+
+ private boolean mNeedUpdateAfterRecommenderReady = false;
+
+ private Recommender.Listener mRecommenderListener = new Recommender.Listener() {
+ @Override
+ public void onRecommenderReady() {
+ if (mNeedUpdateAfterRecommenderReady) {
+ if (DEBUG) Log.d(TAG, "Recommender is ready");
+ updatePreviewDataForChannelsImmediately();
+ mNeedUpdateAfterRecommenderReady = false;
+ }
+ }
+
+ @Override
+ public void onRecommendationChanged() {
+ updatePreviewDataForChannelsImmediately();
+ }
+ };
+
+ private ChannelPreviewUpdater(Context context) {
+ mContext = context;
+ mRecommender = new Recommender(context, mRecommenderListener, true);
+ mRecommender.registerEvaluator(new RandomEvaluator(), 0.1, 0.1);
+ mRecommender.registerEvaluator(new FavoriteChannelEvaluator(), 0.5, 0.5);
+ mRecommender.registerEvaluator(new RoutineWatchEvaluator(), 1.0, 1.0);
+ ApplicationSingletons appSingleton = TvApplication.getSingletons(context);
+ mPreviewDataManager = appSingleton.getPreviewDataManager();
+ mParentalControlSettings = appSingleton.getTvInputManagerHelper()
+ .getParentalControlSettings();
+ }
+
+ /**
+ * Starts the routine service for updating the preview programs.
+ */
+ public void startRoutineService() {
+ JobScheduler jobScheduler =
+ (JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+ if (jobScheduler.getPendingJob(UPATE_PREVIEW_PROGRAMS_JOB_ID) != null) {
+ if (DEBUG) Log.d(TAG, "UPDATE_PREVIEW_JOB already exists");
+ return;
+ }
+ JobInfo job = new JobInfo.Builder(UPATE_PREVIEW_PROGRAMS_JOB_ID,
+ new ComponentName(mContext, ChannelPreviewUpdateService.class))
+ .setPeriodic(ROUTINE_INTERVAL_MS)
+ .setPersisted(true)
+ .build();
+ if (jobScheduler.schedule(job) < 0) {
+ Log.i(TAG, "JobScheduler failed to schedule the job");
+ }
+ }
+
+ /** Called when {@link ChannelPreviewUpdateService} is started. */
+ void onStartJob(JobService service, JobParameters params) {
+ if (DEBUG) Log.d(TAG, "onStartJob");
+ mJobService = service;
+ mJobParams = params;
+ updatePreviewDataForChannelsImmediately();
+ }
+
+ /**
+ * Updates the preview programs table.
+ */
+ public void updatePreviewDataForChannelsImmediately() {
+ if (!mRecommender.isReady()) {
+ mNeedUpdateAfterRecommenderReady = true;
+ return;
+ }
+
+ if (!mPreviewDataManager.isLoadFinished()) {
+ mPreviewDataManager.addListener(new PreviewDataManager.PreviewDataListener() {
+ @Override
+ public void onPreviewDataLoadFinished() {
+ mPreviewDataManager.removeListener(this);
+ updatePreviewDataForChannels();
+ }
+
+ @Override
+ public void onPreviewDataUpdateFinished() { }
+ });
+ return;
+ }
+ updatePreviewDataForChannels();
+ }
+
+ /** Called when {@link ChannelPreviewUpdateService} is stopped. */
+ void onStopJob() {
+ if (DEBUG) Log.d(TAG, "onStopJob");
+ mJobService = null;
+ mJobParams = null;
+ }
+
+ private void updatePreviewDataForChannels() {
+ new AsyncTask<Void, Void, Set<Program>>() {
+ @Override
+ protected Set<Program> doInBackground(Void... params) {
+ Set<Program> programs = new HashSet<>();
+ List<Channel> channels = new ArrayList<>(mRecommender.recommendChannels());
+ for (Channel channel : channels) {
+ if (channel.isPhysicalTunerChannel()) {
+ final Program program = Utils.getCurrentProgram(mContext, channel.getId());
+ if (program != null
+ && isChannelRecommendationApplicable(channel, program)) {
+ programs.add(program);
+ if (programs.size() >= RECOMMENDATION_COUNT) {
+ break;
+ }
+ }
+ }
+ }
+ return programs;
+ }
+
+ private boolean isChannelRecommendationApplicable(Channel channel, Program program) {
+ final long programDurationMs =
+ program.getEndTimeUtcMillis() - program.getStartTimeUtcMillis();
+ if (programDurationMs <= 0) {
+ return false;
+ }
+ if (TextUtils.isEmpty(program.getPosterArtUri())) {
+ return false;
+ }
+ if (mParentalControlSettings.isParentalControlsEnabled()
+ && (channel.isLocked()
+ || mParentalControlSettings.isRatingBlocked(
+ program.getContentRatings()))) {
+ return false;
+ }
+ long programLeftTimsMs = program.getEndTimeUtcMillis() - System.currentTimeMillis();
+ final int programProgress =
+ (programDurationMs <= 0)
+ ? -1
+ : 100 - (int) (programLeftTimsMs * 100 / programDurationMs);
+
+ // We recommend those programs that meet the condition only.
+ return programProgress < RECOMMENDATION_THRESHOLD_PROGRESS
+ || programLeftTimsMs > RECOMMENDATION_THRESHOLD_LEFT_TIME_MS;
+ }
+
+ @Override
+ protected void onPostExecute(Set<Program> programs) {
+ updatePreviewDataForChannelsInternal(programs);
+ }
+ }.execute();
+ }
+
+ private void updatePreviewDataForChannelsInternal(Set<Program> programs) {
+ long defaultPreviewChannelId = mPreviewDataManager.getPreviewChannelId(
+ PreviewDataManager.TYPE_DEFAULT_PREVIEW_CHANNEL);
+ if (defaultPreviewChannelId == PreviewDataManager.INVALID_PREVIEW_CHANNEL_ID) {
+ // Only create if there is enough programs
+ if (programs.size() > MIN_COUNT_TO_ADD_ROW) {
+ mPreviewDataManager.createDefaultPreviewChannel(
+ new PreviewDataManager.OnPreviewChannelCreationResultListener() {
+ @Override
+ public void onPreviewChannelCreationResult(
+ long createdPreviewChannelId) {
+ if (createdPreviewChannelId
+ != PreviewDataManager.INVALID_PREVIEW_CHANNEL_ID) {
+ TvContractCompat.requestChannelBrowsable(
+ mContext, createdPreviewChannelId);
+ updatePreviewProgramsForPreviewChannel(
+ createdPreviewChannelId,
+ generatePreviewProgramContentsFromPrograms(
+ createdPreviewChannelId, programs));
+ }
+ }
+ });
+ }
+ } else {
+ updatePreviewProgramsForPreviewChannel(defaultPreviewChannelId,
+ generatePreviewProgramContentsFromPrograms(defaultPreviewChannelId, programs));
+ }
+ }
+
+ private Set<PreviewProgramContent> generatePreviewProgramContentsFromPrograms(
+ long previewChannelId, Set<Program> programs) {
+ Set<PreviewProgramContent> result = new HashSet<>();
+ for (Program program : programs) {
+ PreviewProgramContent previewProgramContent =
+ PreviewProgramContent.createFromProgram(mContext, previewChannelId, program);
+ if (previewProgramContent != null) {
+ result.add(previewProgramContent);
+ }
+ }
+ return result;
+ }
+
+ private void updatePreviewProgramsForPreviewChannel(long previewChannelId,
+ Set<PreviewProgramContent> previewProgramContents) {
+ PreviewDataManager.PreviewDataListener previewDataListener
+ = new PreviewDataManager.PreviewDataListener() {
+ @Override
+ public void onPreviewDataLoadFinished() { }
+
+ @Override
+ public void onPreviewDataUpdateFinished() {
+ mPreviewDataManager.removeListener(this);
+ if (mJobService != null && mJobParams != null) {
+ if (DEBUG) Log.d(TAG, "UpdateAsyncTask.onPostExecute with JobService");
+ mJobService.jobFinished(mJobParams, false);
+ mJobService = null;
+ mJobParams = null;
+ } else {
+ if (DEBUG) Log.d(TAG, "UpdateAsyncTask.onPostExecute without JobService");
+ }
+ }
+ };
+ mPreviewDataManager.updatePreviewProgramsForChannel(
+ previewChannelId, previewProgramContents, previewDataListener);
+ }
+
+ /**
+ * Job to execute the update of preview programs.
+ */
+ public static class ChannelPreviewUpdateService extends JobService {
+ private ChannelPreviewUpdater mChannelPreviewUpdater;
+
+ @Override
+ public void onCreate() {
+ TvApplication.setCurrentRunningProcess(this, true);
+ if (DEBUG) Log.d(TAG, "ChannelPreviewUpdateService.onCreate");
+ mChannelPreviewUpdater = ChannelPreviewUpdater.getInstance(this);
+ }
+
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ mChannelPreviewUpdater.onStartJob(this, params);
+ return true;
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ mChannelPreviewUpdater.onStopJob();
+ return false;
+ }
+
+ @Override
+ public void onDestroy() {
+ if (DEBUG) Log.d(TAG, "ChannelPreviewUpdateService.onDestroy");
+ }
+ }
+}
diff --git a/src/com/android/tv/recommendation/NotificationService.java b/src/com/android/tv/recommendation/NotificationService.java
index 30ec73e3..a44eca41 100644
--- a/src/com/android/tv/recommendation/NotificationService.java
+++ b/src/com/android/tv/recommendation/NotificationService.java
@@ -426,6 +426,7 @@ public class NotificationService extends Service implements Recommender.Listener
: 100 - (int) (programLeftTimsMs * 100 / programDurationMs);
Intent intent = new Intent(Intent.ACTION_VIEW, channel.getUri());
intent.putExtra(TUNE_PARAMS_RECOMMENDATION_TYPE, mRecommendationType);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
final PendingIntent notificationIntent = PendingIntent.getActivity(this, 0, intent, 0);
// This callback will run on the main thread.
@@ -455,11 +456,17 @@ public class NotificationService extends Service implements Recommender.Listener
}
private Bitmap overlayChannelLogo(Bitmap logo, Bitmap background) {
- Bitmap result = BitmapUtils.scaleBitmap(
+ Bitmap result = BitmapUtils.getScaledMutableBitmap(
background, Integer.MAX_VALUE, mCardImageHeight);
Bitmap scaledLogo = BitmapUtils.scaleBitmap(
logo, mChannelLogoMaxWidth, mChannelLogoMaxHeight);
- Canvas canvas = new Canvas(result);
+ Canvas canvas;
+ try {
+ canvas = new Canvas(result);
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to create Canvas", e);
+ return background;
+ }
canvas.drawBitmap(result, new Matrix(), null);
Rect rect = new Rect();
int startPadding;
diff --git a/src/com/android/tv/recommendation/RecommendationDataManager.java b/src/com/android/tv/recommendation/RecommendationDataManager.java
index 62ccd578..dc148ec8 100644
--- a/src/com/android/tv/recommendation/RecommendationDataManager.java
+++ b/src/com/android/tv/recommendation/RecommendationDataManager.java
@@ -41,7 +41,7 @@ import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.Program;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.util.PermissionUtils;
-import com.android.tv.util.TvProviderUriMatcher;
+import com.android.tv.util.TvUriMatcher;
import java.util.ArrayList;
import java.util.Collection;
@@ -505,8 +505,8 @@ public class RecommendationDataManager implements WatchedHistoryManager.Listener
@SuppressLint("SwitchIntDef")
@Override
public void onChange(final boolean selfChange, final Uri uri) {
- switch (TvProviderUriMatcher.match(uri)) {
- case TvProviderUriMatcher.MATCH_WATCHED_PROGRAM_ID:
+ switch (TvUriMatcher.match(uri)) {
+ case TvUriMatcher.MATCH_WATCHED_PROGRAM_ID:
if (!mHandler.hasMessages(MSG_UPDATE_WATCH_HISTORY,
TvContract.WatchedPrograms.CONTENT_URI)) {
mHandler.obtainMessage(MSG_UPDATE_WATCH_HISTORY, uri).sendToTarget();
diff --git a/src/com/android/tv/recommendation/RecordedProgramPreviewUpdater.java b/src/com/android/tv/recommendation/RecordedProgramPreviewUpdater.java
new file mode 100644
index 00000000..ad55afb7
--- /dev/null
+++ b/src/com/android/tv/recommendation/RecordedProgramPreviewUpdater.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2017 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.tv.recommendation;
+
+import android.content.Context;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.TvApplication;
+import com.android.tv.data.PreviewDataManager;
+import com.android.tv.data.PreviewProgramContent;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.data.RecordedProgram;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Class to update the preview data for {@link RecordedProgram}
+ */
+@RequiresApi(Build.VERSION_CODES.O)
+public class RecordedProgramPreviewUpdater {
+ private static final String TAG = "RecordedProgramPreviewUpdater";
+ // STOPSHIP: set it to false.
+ private static final boolean DEBUG = true;
+
+ private static final int RECOMMENDATION_COUNT = 6;
+
+ private static RecordedProgramPreviewUpdater sRecordedProgramPreviewUpdater;
+
+ /**
+ * Creates and returns the {@link RecordedProgramPreviewUpdater}.
+ */
+ public static RecordedProgramPreviewUpdater getInstance(Context context) {
+ if (sRecordedProgramPreviewUpdater == null) {
+ sRecordedProgramPreviewUpdater
+ = new RecordedProgramPreviewUpdater(context.getApplicationContext());
+ }
+ return sRecordedProgramPreviewUpdater;
+ }
+
+ private final Context mContext;
+ private final PreviewDataManager mPreviewDataManager;
+ private final DvrDataManager mDvrDataManager;
+
+ private RecordedProgramPreviewUpdater(Context context) {
+ mContext = context.getApplicationContext();
+ ApplicationSingletons applicationSingletons = TvApplication.getSingletons(mContext);
+ mPreviewDataManager = applicationSingletons.getPreviewDataManager();
+ mDvrDataManager = applicationSingletons.getDvrDataManager();
+ mDvrDataManager.addRecordedProgramListener(new DvrDataManager.RecordedProgramListener() {
+ @Override
+ public void onRecordedProgramsAdded(RecordedProgram... recordedPrograms) {
+ if (DEBUG) Log.d(TAG, "Add new preview recorded programs");
+ updatePreviewDataForRecordedPrograms();
+ }
+
+ @Override
+ public void onRecordedProgramsChanged(RecordedProgram... recordedPrograms) {
+ if (DEBUG) Log.d(TAG, "Update preview recorded programs");
+ updatePreviewDataForRecordedPrograms();
+ }
+
+ @Override
+ public void onRecordedProgramsRemoved(RecordedProgram... recordedPrograms) {
+ if (DEBUG) Log.d(TAG, "Delete preview recorded programs");
+ updatePreviewDataForRecordedPrograms();
+ }
+ });
+ }
+
+ /**
+ * Updates the preview data for recorded programs.
+ */
+ public void updatePreviewDataForRecordedPrograms() {
+ if (!mPreviewDataManager.isLoadFinished()) {
+ mPreviewDataManager.addListener(new PreviewDataManager.PreviewDataListener() {
+ @Override
+ public void onPreviewDataLoadFinished() {
+ mPreviewDataManager.removeListener(this);
+ updatePreviewDataForRecordedPrograms();
+ }
+
+ @Override
+ public void onPreviewDataUpdateFinished() { }
+ });
+ return;
+ }
+ if (!mDvrDataManager.isRecordedProgramLoadFinished()) {
+ mDvrDataManager.addRecordedProgramLoadFinishedListener(
+ new DvrDataManager.OnRecordedProgramLoadFinishedListener() {
+ @Override
+ public void onRecordedProgramLoadFinished() {
+ mDvrDataManager.removeRecordedProgramLoadFinishedListener(this);
+ updatePreviewDataForRecordedPrograms();
+ }
+ });
+ return;
+ }
+ updatePreviewDataForRecordedProgramsInternal();
+ }
+
+ private void updatePreviewDataForRecordedProgramsInternal() {
+ Set<RecordedProgram> recordedPrograms = generateRecommendationRecordedPrograms();
+ Long recordedPreviewChannelId = mPreviewDataManager.getPreviewChannelId(
+ PreviewDataManager.TYPE_RECORDED_PROGRAM_PREVIEW_CHANNEL);
+ if (recordedPreviewChannelId == PreviewDataManager.INVALID_PREVIEW_CHANNEL_ID
+ && !recordedPrograms.isEmpty()) {
+ createPreviewChannelForRecordedPrograms();
+ } else {
+ mPreviewDataManager.updatePreviewProgramsForChannel(recordedPreviewChannelId,
+ generatePreviewProgramContentsFromRecordedPrograms(
+ recordedPreviewChannelId, recordedPrograms), null);
+ }
+ }
+
+ private void createPreviewChannelForRecordedPrograms() {
+ mPreviewDataManager.createPreviewChannel(
+ PreviewDataManager.TYPE_RECORDED_PROGRAM_PREVIEW_CHANNEL,
+ new PreviewDataManager.OnPreviewChannelCreationResultListener() {
+ @Override
+ public void onPreviewChannelCreationResult(long createdPreviewChannelId) {
+ if (createdPreviewChannelId
+ != PreviewDataManager.INVALID_PREVIEW_CHANNEL_ID) {
+ updatePreviewDataForRecordedProgramsInternal();
+ }
+ }
+ });
+ }
+
+ private Set<RecordedProgram> generateRecommendationRecordedPrograms() {
+ Set<RecordedProgram> programs = new HashSet<>();
+ ArrayList<RecordedProgram> sortedRecordedPrograms =
+ new ArrayList<>(mDvrDataManager.getRecordedPrograms());
+ Collections.sort(
+ sortedRecordedPrograms, RecordedProgram.START_TIME_THEN_ID_COMPARATOR.reversed());
+ for (RecordedProgram recordedProgram : sortedRecordedPrograms) {
+ if (!TextUtils.isEmpty(recordedProgram.getPosterArtUri())) {
+ programs.add(recordedProgram);
+ if (programs.size() >= RECOMMENDATION_COUNT) {
+ break;
+ }
+ }
+ }
+ return programs;
+ }
+
+ private Set<PreviewProgramContent> generatePreviewProgramContentsFromRecordedPrograms(
+ long previewChannelId, Set<RecordedProgram> recordedPrograms) {
+ Set<PreviewProgramContent> result = new HashSet<>();
+ for (RecordedProgram recordedProgram : recordedPrograms) {
+ result.add(PreviewProgramContent.createFromRecordedProgram(mContext, previewChannelId,
+ recordedProgram));
+ }
+ return result;
+ }
+}
diff --git a/src/com/android/tv/search/DataManagerSearch.java b/src/com/android/tv/search/DataManagerSearch.java
index 5f89a21a..d90908f1 100644
--- a/src/com/android/tv/search/DataManagerSearch.java
+++ b/src/com/android/tv/search/DataManagerSearch.java
@@ -265,9 +265,7 @@ public class DataManagerSearch implements SearchInterface {
}
private String buildIntentData(long channelId) {
- return TvContract.buildChannelUri(channelId).buildUpon()
- .appendQueryParameter(Utils.PARAM_SOURCE, SOURCE_TV_SEARCH)
- .build().toString();
+ return TvContract.buildChannelUri(channelId).toString();
}
private boolean isRatingBlocked(TvContentRating[] ratings) {
diff --git a/src/com/android/tv/search/LocalSearchProvider.java b/src/com/android/tv/search/LocalSearchProvider.java
index 9255a43d..ef9336d7 100644
--- a/src/com/android/tv/search/LocalSearchProvider.java
+++ b/src/com/android/tv/search/LocalSearchProvider.java
@@ -23,10 +23,19 @@ import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.SystemClock;
+import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
+import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
+import com.android.tv.common.TvCommonUtils;
+import com.android.tv.perf.EventNames;
+import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.perf.TimerEvent;
import com.android.tv.util.PermissionUtils;
+import com.android.tv.util.TvUriMatcher;
import java.util.ArrayList;
import java.util.Arrays;
@@ -36,6 +45,9 @@ public class LocalSearchProvider extends ContentProvider {
private static final String TAG = "LocalSearchProvider";
private static final boolean DEBUG = false;
+ /** The authority for LocalSearchProvider. */
+ public static final String AUTHORITY = "com.android.tv.search";
+
public static final int PROGRESS_PERCENTAGE_HIDE = -1;
// TODO: Remove this once added to the SearchManager.
@@ -56,58 +68,93 @@ public class LocalSearchProvider extends ContentProvider {
};
private static final String EXPECTED_PATH_PREFIX = "/" + SearchManager.SUGGEST_URI_PATH_QUERY;
+ static final String SUGGEST_PARAMETER_ACTION = "action";
// The launcher passes 10 as a 'limit' parameter by default.
- private static final int DEFAULT_SEARCH_LIMIT = 10;
+ @VisibleForTesting
+ static final int DEFAULT_SEARCH_LIMIT = 10;
+ @VisibleForTesting
+ static final int DEFAULT_SEARCH_ACTION = SearchInterface.ACTION_TYPE_AMBIGUOUS;
private static final String NO_LIVE_CONTENTS = "0";
private static final String LIVE_CONTENTS = "1";
- static final String SUGGEST_PARAMETER_ACTION = "action";
- static final int DEFAULT_SEARCH_ACTION = SearchInterface.ACTION_TYPE_AMBIGUOUS;
+ private PerformanceMonitor mPerformanceMonitor;
+
+ /** Used only for testing */
+ private SearchInterface mSearchInterface;
@Override
public boolean onCreate() {
+ mPerformanceMonitor = TvApplication.getSingletons(getContext()).getPerformanceMonitor();
return true;
}
+ @VisibleForTesting
+ void setSearchInterface(SearchInterface searchInterface) {
+ SoftPreconditions.checkState(TvCommonUtils.isRunningInTest());
+ mSearchInterface = searchInterface;
+ }
+
@Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
+ public Cursor query(@NonNull Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ if (TvUriMatcher.match(uri) != TvUriMatcher.MATCH_ON_DEVICE_SEARCH) {
+ throw new IllegalArgumentException("Unknown URI: " + uri);
+ }
+ TimerEvent queryTimer = mPerformanceMonitor.startTimer();
if (DEBUG) {
Log.d(TAG, "query(" + uri + ", " + Arrays.toString(projection) + ", " + selection + ", "
+ Arrays.toString(selectionArgs) + ", " + sortOrder + ")");
}
long time = SystemClock.elapsedRealtime();
- SearchInterface search;
- if (PermissionUtils.hasAccessAllEpg(getContext())) {
- if (DEBUG) Log.d(TAG, "Performing TV Provider search.");
- search = new TvProviderSearch(getContext());
- } else {
- if (DEBUG) Log.d(TAG, "Performing Data Manager search.");
- search = new DataManagerSearch(getContext());
+ SearchInterface search = mSearchInterface;
+ if (search == null) {
+ if (PermissionUtils.hasAccessAllEpg(getContext())) {
+ if (DEBUG) Log.d(TAG, "Performing TV Provider search.");
+ search = new TvProviderSearch(getContext());
+ } else {
+ if (DEBUG) Log.d(TAG, "Performing Data Manager search.");
+ search = new DataManagerSearch(getContext());
+ }
}
String query = uri.getLastPathSegment();
- int limit = DEFAULT_SEARCH_LIMIT;
- int action = DEFAULT_SEARCH_ACTION;
- try {
- limit = Integer.parseInt(uri.getQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT));
- action = Integer.parseInt(uri.getQueryParameter(SUGGEST_PARAMETER_ACTION));
- } catch (NumberFormatException | UnsupportedOperationException e) {
- // Ignore the exceptions
+ int limit = getQueryParamater(uri, SearchManager.SUGGEST_PARAMETER_LIMIT,
+ DEFAULT_SEARCH_LIMIT);
+ if (limit <= 0) {
+ limit = DEFAULT_SEARCH_LIMIT;
+ }
+ int action = getQueryParamater(uri, SUGGEST_PARAMETER_ACTION, DEFAULT_SEARCH_ACTION);
+ if (action < SearchInterface.ACTION_TYPE_START
+ || action > SearchInterface.ACTION_TYPE_END) {
+ action = DEFAULT_SEARCH_ACTION;
}
List<SearchResult> results = new ArrayList<>();
if (!TextUtils.isEmpty(query)) {
results.addAll(search.search(query, limit, action));
}
Cursor c = createSuggestionsCursor(results);
- if (DEBUG) Log.d(TAG, "Elapsed time: " + (SystemClock.elapsedRealtime() - time) + "(msec)");
+ if (DEBUG) {
+ Log.d(TAG, "Elapsed time(count=" + c.getCount() + "): "
+ + (SystemClock.elapsedRealtime() - time) + "(msec)");
+ }
+ mPerformanceMonitor.stopTimer(queryTimer, EventNames.ON_DEVICE_SEARCH);
return c;
}
+ private int getQueryParamater(Uri uri, String key, int defaultValue) {
+ try {
+ return Integer.parseInt(uri.getQueryParameter(key));
+ } catch (NumberFormatException | UnsupportedOperationException e) {
+ // Ignore the exceptions
+ }
+ return defaultValue;
+ }
+
private Cursor createSuggestionsCursor(List<SearchResult> results) {
MatrixCursor cursor = new MatrixCursor(SEARCHABLE_COLUMNS, results.size());
List<String> row = new ArrayList<>(SEARCHABLE_COLUMNS.length);
+ int index = 0;
for (SearchResult result : results) {
row.clear();
row.add(result.title);
@@ -122,6 +169,7 @@ public class LocalSearchProvider extends ContentProvider {
row.add(result.duration == 0 ? null : String.valueOf(result.duration));
row.add(String.valueOf(result.progressPercentage));
cursor.addRow(row);
+ if (DEBUG) Log.d(TAG, "Result[" + (++index) + "]: " + result);
}
return cursor;
}
@@ -171,9 +219,20 @@ public class LocalSearchProvider extends ContentProvider {
@Override
public String toString() {
- return "channelId: " + channelId +
- ", channelNumber: " + channelNumber +
- ", title: " + title;
+ return "SearchResult{channelId=" + channelId +
+ ", channelNumber=" + channelNumber +
+ ", title=" + title +
+ ", description=" + description +
+ ", imageUri=" + imageUri +
+ ", intentAction=" + intentAction +
+ ", intentData=" + intentData +
+ ", contentType=" + contentType +
+ ", isLive=" + isLive +
+ ", videoWidth=" + videoWidth +
+ ", videoHeight=" + videoHeight +
+ ", duration=" + duration +
+ ", progressPercentage=" + progressPercentage +
+ "}";
}
}
} \ No newline at end of file
diff --git a/src/com/android/tv/search/SearchInterface.java b/src/com/android/tv/search/SearchInterface.java
index caa45812..d631972a 100644
--- a/src/com/android/tv/search/SearchInterface.java
+++ b/src/com/android/tv/search/SearchInterface.java
@@ -24,11 +24,11 @@ import java.util.List;
* Interface for channel and program search.
*/
public interface SearchInterface {
- String SOURCE_TV_SEARCH = "TvSearch";
-
+ int ACTION_TYPE_START = 1;
int ACTION_TYPE_AMBIGUOUS = 1;
int ACTION_TYPE_SWITCH_CHANNEL = 2;
int ACTION_TYPE_SWITCH_INPUT = 3;
+ int ACTION_TYPE_END = 3;
/**
* Search channels, inputs, or programs.
diff --git a/src/com/android/tv/search/TvProviderSearch.java b/src/com/android/tv/search/TvProviderSearch.java
index 2ceec19a..e7d8a02d 100644
--- a/src/com/android/tv/search/TvProviderSearch.java
+++ b/src/com/android/tv/search/TvProviderSearch.java
@@ -402,9 +402,7 @@ public class TvProviderSearch implements SearchInterface {
}
private String buildIntentData(long channelId) {
- return TvContract.buildChannelUri(channelId).buildUpon()
- .appendQueryParameter(Utils.PARAM_SOURCE, SOURCE_TV_SEARCH)
- .build().toString();
+ return TvContract.buildChannelUri(channelId).toString();
}
private boolean isRatingBlocked(String ratings) {
@@ -432,6 +430,9 @@ public class TvProviderSearch implements SearchInterface {
// Find exact matches first.
for (TvInputInfo input : inputList) {
+ if (input.getType() == TvInputInfo.TYPE_TUNER) {
+ continue;
+ }
String label = canonicalizeLabel(input.loadLabel(mContext));
String customLabel = canonicalizeLabel(input.loadCustomLabel(mContext));
if (TextUtils.equals(query, label) || TextUtils.equals(query, customLabel)) {
@@ -449,6 +450,9 @@ public class TvProviderSearch implements SearchInterface {
// Then look for partial matches.
for (TvInputInfo input : inputList) {
+ if (input.getType() == TvInputInfo.TYPE_TUNER) {
+ continue;
+ }
String label = canonicalizeLabel(input.loadLabel(mContext));
String customLabel = canonicalizeLabel(input.loadCustomLabel(mContext));
if ((label != null && label.contains(query)) ||
diff --git a/src/com/android/tv/tuner/ChannelScanFileParser.java b/src/com/android/tv/tuner/ChannelScanFileParser.java
index 2dd36074..a255de3e 100644
--- a/src/com/android/tv/tuner/ChannelScanFileParser.java
+++ b/src/com/android/tv/tuner/ChannelScanFileParser.java
@@ -90,10 +90,6 @@ public class ChannelScanFileParser {
if (tokens.length != 3 && tokens.length != 4) {
continue;
}
- if (!tokens[0].equals("A")) {
- // Only support ATSC
- continue;
- }
scanChannelList.add(ScanChannel.forTuner(Integer.parseInt(tokens[1]), tokens[2],
tokens.length == 4 ? Integer.parseInt(tokens[3]) : null));
}
diff --git a/src/com/android/tv/tuner/DvbTunerHal.java b/src/com/android/tv/tuner/DvbTunerHal.java
new file mode 100644
index 00000000..ea977230
--- /dev/null
+++ b/src/com/android/tv/tuner/DvbTunerHal.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2015 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.tv.tuner;
+
+import android.content.Context;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+import com.android.tv.tuner.DvbDeviceAccessor.DvbDeviceInfoWrapper;
+
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * A class to handle a hardware Linux DVB API supported tuner device.
+ */
+public class DvbTunerHal extends TunerHal {
+
+ private static final Object sLock = new Object();
+ // @GuardedBy("sLock")
+ private static final SortedSet<DvbDeviceInfoWrapper> sUsedDvbDevices = new TreeSet<>();
+
+ private final DvbDeviceAccessor mDvbDeviceAccessor;
+ private DvbDeviceInfoWrapper mDvbDeviceInfo;
+
+ protected DvbTunerHal(Context context) {
+ super(context);
+ mDvbDeviceAccessor = new DvbDeviceAccessor(context);
+ }
+
+ @Override
+ protected boolean openFirstAvailable() {
+ List<DvbDeviceInfoWrapper> deviceInfoList = mDvbDeviceAccessor.getDvbDeviceList();
+ if (deviceInfoList == null || deviceInfoList.isEmpty()) {
+ Log.e(TAG, "There's no dvb device attached");
+ return false;
+ }
+ synchronized (sLock) {
+ for (DvbDeviceInfoWrapper deviceInfo : deviceInfoList) {
+ if (!sUsedDvbDevices.contains(deviceInfo)) {
+ if (DEBUG) Log.d(TAG, "Available device info: " + deviceInfo);
+ mDvbDeviceInfo = deviceInfo;
+ sUsedDvbDevices.add(deviceInfo);
+ getDeliverySystemTypeFromDevice();
+ return true;
+ }
+ }
+ }
+ Log.e(TAG, "There's no available dvb devices");
+ return false;
+ }
+
+ /**
+ * Acquires the tuner device. The requested device will be locked to the current instance if
+ * it's not acquired by others.
+ *
+ * @param deviceInfo a tuner device to open
+ * @return {@code true} if the operation was successful, {@code false} otherwise
+ */
+ protected boolean open(DvbDeviceInfoWrapper deviceInfo) {
+ if (deviceInfo == null) {
+ Log.e(TAG, "Device info should not be null");
+ return false;
+ }
+ if (mDvbDeviceInfo != null) {
+ Log.e(TAG, "Already acquired");
+ return false;
+ }
+ List<DvbDeviceInfoWrapper> deviceInfoList = mDvbDeviceAccessor.getDvbDeviceList();
+ if (deviceInfoList == null || deviceInfoList.isEmpty()) {
+ Log.e(TAG, "There's no dvb device attached");
+ return false;
+ }
+ for (DvbDeviceInfoWrapper deviceInfoWrapper : deviceInfoList) {
+ if (deviceInfoWrapper.compareTo(deviceInfo) == 0) {
+ synchronized (sLock) {
+ if (sUsedDvbDevices.contains(deviceInfo)) {
+ Log.e(TAG, deviceInfo + " is already taken");
+ return false;
+ }
+ sUsedDvbDevices.add(deviceInfo);
+ }
+ if (DEBUG) Log.d(TAG, "Available device info: " + deviceInfo);
+ mDvbDeviceInfo = deviceInfo;
+ return true;
+ }
+ }
+ Log.e(TAG, "There's no such dvb device attached");
+ return false;
+ }
+
+ @Override
+ public void close() {
+ if (mDvbDeviceInfo != null) {
+ if (isStreaming()) {
+ stopTune();
+ }
+ nativeFinalize(mDvbDeviceInfo.getId());
+ synchronized (sLock) {
+ sUsedDvbDevices.remove(mDvbDeviceInfo);
+ }
+ mDvbDeviceInfo = null;
+ }
+ }
+
+ @Override
+ protected boolean isDeviceOpen() {
+ return (mDvbDeviceInfo != null);
+ }
+
+ @Override
+ protected long getDeviceId() {
+ if (mDvbDeviceInfo != null) {
+ return mDvbDeviceInfo.getId();
+ }
+ return -1;
+ }
+
+ @Override
+ protected int openDvbFrontEndFd() {
+ if (mDvbDeviceInfo != null) {
+ ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice(
+ mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_FRONTEND);
+ if (descriptor != null) {
+ return descriptor.detachFd();
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected int openDvbDemuxFd() {
+ if (mDvbDeviceInfo != null) {
+ ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice(
+ mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_DEMUX);
+ if (descriptor != null) {
+ return descriptor.detachFd();
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected int openDvbDvrFd() {
+ if (mDvbDeviceInfo != null) {
+ ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice(
+ mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_DVR);
+ if (descriptor != null) {
+ return descriptor.detachFd();
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Gets the number of USB tuner devices currently present.
+ */
+ public static int getNumberOfDevices(Context context) {
+ try {
+ return (new DvbDeviceAccessor(context)).getNumOfDvbDevices();
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+}
diff --git a/src/com/android/tv/tuner/TunerHal.java b/src/com/android/tv/tuner/TunerHal.java
index de19766e..1176cdf0 100644
--- a/src/com/android/tv/tuner/TunerHal.java
+++ b/src/com/android/tv/tuner/TunerHal.java
@@ -19,7 +19,12 @@ package com.android.tv.tuner;
import android.content.Context;
import android.support.annotation.IntDef;
import android.support.annotation.StringDef;
+import android.support.annotation.WorkerThread;
import android.util.Log;
+import android.util.Pair;
+
+import com.android.tv.Features;
+import com.android.tv.customization.TvCustomizationManager;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -46,14 +51,43 @@ public abstract class TunerHal implements AutoCloseable {
public static final String MODULATION_8VSB = "8VSB";
public static final String MODULATION_QAM256 = "QAM256";
+ @IntDef({ DELIVERY_SYSTEM_UNDEFINED, DELIVERY_SYSTEM_ATSC, DELIVERY_SYSTEM_DVBC,
+ DELIVERY_SYSTEM_DVBS, DELIVERY_SYSTEM_DVBS2, DELIVERY_SYSTEM_DVBT,
+ DELIVERY_SYSTEM_DVBT2 })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DeliverySystemType {}
+ public static final int DELIVERY_SYSTEM_UNDEFINED = 0;
+ public static final int DELIVERY_SYSTEM_ATSC = 1;
+ public static final int DELIVERY_SYSTEM_DVBC = 2;
+ public static final int DELIVERY_SYSTEM_DVBS = 3;
+ public static final int DELIVERY_SYSTEM_DVBS2 = 4;
+ public static final int DELIVERY_SYSTEM_DVBT = 5;
+ public static final int DELIVERY_SYSTEM_DVBT2 = 6;
+
+ @IntDef({ TUNER_TYPE_BUILT_IN, TUNER_TYPE_USB, TUNER_TYPE_NETWORK })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TunerType {}
public static final int TUNER_TYPE_BUILT_IN = 1;
public static final int TUNER_TYPE_USB = 2;
+ public static final int TUNER_TYPE_NETWORK = 3;
protected static final int PID_PAT = 0;
protected static final int PID_ATSC_SI_BASE = 0x1ffb;
+ protected static final int PID_DVB_SDT = 0x0011;
+ protected static final int PID_DVB_EIT = 0x0012;
protected static final int DEFAULT_VSB_TUNE_TIMEOUT_MS = 2000;
protected static final int DEFAULT_QAM_TUNE_TIMEOUT_MS = 4000; // Some device takes time for
// QAM256 tuning.
+ @IntDef({
+ BUILT_IN_TUNER_TYPE_LINUX_DVB
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface BuiltInTunerType {}
+ private static final int BUILT_IN_TUNER_TYPE_LINUX_DVB = 1;
+
+ private static Integer sBuiltInTunerType;
+
+ protected @DeliverySystemType int mDeliverySystemType;
private boolean mIsStreaming;
private int mFrequency;
private String mModulation;
@@ -67,33 +101,62 @@ public abstract class TunerHal implements AutoCloseable {
* @param context context for creating the TunerHal instance
* @return the TunerHal instance
*/
+ @WorkerThread
public synchronized static TunerHal createInstance(Context context) {
TunerHal tunerHal = null;
- if (getTunerType(context) == TUNER_TYPE_BUILT_IN) {
- }
- if (tunerHal == null) {
- tunerHal = new UsbTunerHal(context);
- }
- if (tunerHal.openFirstAvailable()) {
- return tunerHal;
+ if (DvbTunerHal.getNumberOfDevices(context) > 0) {
+ if (DEBUG) Log.d(TAG, "Use DvbTunerHal");
+ tunerHal = new DvbTunerHal(context);
}
- return null;
+ return tunerHal != null && tunerHal.openFirstAvailable() ? tunerHal : null;
}
/**
* Gets the number of tuner devices currently present.
*/
- public static int getTunerCount(Context context) {
- if (getTunerType(context) == TUNER_TYPE_BUILT_IN) {
+ @WorkerThread
+ public static Pair<Integer, Integer> getTunerTypeAndCount(Context context) {
+ if (useBuiltInTuner(context)) {
+ if (getBuiltInTunerType(context) == BUILT_IN_TUNER_TYPE_LINUX_DVB) {
+ return new Pair<>(TUNER_TYPE_BUILT_IN, DvbTunerHal.getNumberOfDevices(context));
+ }
+ } else {
+ int usbTunerCount = DvbTunerHal.getNumberOfDevices(context);
+ if (usbTunerCount > 0) {
+ return new Pair<>(TUNER_TYPE_USB, usbTunerCount);
+ }
}
- return UsbTunerHal.getNumberOfDevices(context);
+ return new Pair<>(null, 0);
+ }
+
+ /**
+ * Check a delivery system is for DVB or not.
+ */
+ public static boolean isDvbDeliverySystem(@DeliverySystemType int deliverySystemType) {
+ return deliverySystemType == DELIVERY_SYSTEM_DVBC
+ || deliverySystemType == DELIVERY_SYSTEM_DVBS
+ || deliverySystemType == DELIVERY_SYSTEM_DVBS2
+ || deliverySystemType == DELIVERY_SYSTEM_DVBT
+ || deliverySystemType == DELIVERY_SYSTEM_DVBT2;
}
/**
- * Gets the type of tuner devices currently used.
+ * Returns if tuner input service would use built-in tuners instead of USB tuners or network
+ * tuners.
*/
- public static int getTunerType(Context context) {
- return TUNER_TYPE_USB;
+ static boolean useBuiltInTuner(Context context) {
+ return getBuiltInTunerType(context) != 0;
+ }
+
+ private static @BuiltInTunerType int getBuiltInTunerType(Context context) {
+ if (sBuiltInTunerType == null) {
+ sBuiltInTunerType = 0;
+ if (TvCustomizationManager.hasLinuxDvbBuiltInTuner(context)
+ && DvbTunerHal.getNumberOfDevices(context) > 0) {
+ sBuiltInTunerType = BUILT_IN_TUNER_TYPE_LINUX_DVB;
+ }
+ }
+ return sBuiltInTunerType;
}
protected TunerHal(Context context) {
@@ -106,6 +169,20 @@ public abstract class TunerHal implements AutoCloseable {
return mIsStreaming;
}
+ protected void getDeliverySystemTypeFromDevice() {
+ if (mDeliverySystemType == DELIVERY_SYSTEM_UNDEFINED) {
+ mDeliverySystemType = nativeGetDeliverySystemType(getDeviceId());
+ }
+ }
+
+ /**
+ * Returns {@code true} if this tuner HAL can be reused to save tuning time between channels
+ * of the same frequency.
+ */
+ public boolean isReusable() {
+ return true;
+ }
+
@Override
protected void finalize() throws Throwable {
super.finalize();
@@ -131,9 +208,12 @@ public abstract class TunerHal implements AutoCloseable {
*
* @param frequency a frequency of the channel to tune to
* @param modulation a modulation method of the channel to tune to
+ * @param channelNumber channel number when channel number is already known. Some tuner HAL
+ * may use channelNumber instead of frequency for tune.
* @return {@code true} if the operation was successful, {@code false} otherwise
*/
- public synchronized boolean tune(int frequency, @ModulationType String modulation) {
+ public synchronized boolean tune(int frequency, @ModulationType String modulation,
+ String channelNumber) {
if (!isDeviceOpen()) {
Log.e(TAG, "There's no available device");
return false;
@@ -148,6 +228,10 @@ public abstract class TunerHal implements AutoCloseable {
if (mFrequency == frequency && Objects.equals(mModulation, modulation)) {
addPidFilter(PID_PAT, FILTER_TYPE_OTHER);
addPidFilter(PID_ATSC_SI_BASE, FILTER_TYPE_OTHER);
+ if (isDvbDeliverySystem(mDeliverySystemType)) {
+ addPidFilter(PID_DVB_SDT, FILTER_TYPE_OTHER);
+ addPidFilter(PID_DVB_EIT, FILTER_TYPE_OTHER);
+ }
mIsStreaming = true;
return true;
}
@@ -156,6 +240,10 @@ public abstract class TunerHal implements AutoCloseable {
if (nativeTune(getDeviceId(), frequency, modulation, timeout_ms)) {
addPidFilter(PID_PAT, FILTER_TYPE_OTHER);
addPidFilter(PID_ATSC_SI_BASE, FILTER_TYPE_OTHER);
+ if (isDvbDeliverySystem(mDeliverySystemType)) {
+ addPidFilter(PID_DVB_SDT, FILTER_TYPE_OTHER);
+ addPidFilter(PID_DVB_EIT, FILTER_TYPE_OTHER);
+ }
mFrequency = frequency;
mModulation = modulation;
mIsStreaming = true;
@@ -189,6 +277,7 @@ public abstract class TunerHal implements AutoCloseable {
protected native void nativeAddPidFilter(long deviceId, int pid, @FilterType int filterType);
protected native void nativeCloseAllPidFilters(long deviceId);
protected native void nativeSetHasPendingTune(long deviceId, boolean hasPendingTune);
+ protected native int nativeGetDeliverySystemType(long deviceId);
/**
* Stops current tuning. The tuner device and pid filters will be reset by this call and make
@@ -210,6 +299,10 @@ public abstract class TunerHal implements AutoCloseable {
nativeSetHasPendingTune(getDeviceId(), hasPendingTune);
}
+ public int getDeliverySystemType() {
+ return mDeliverySystemType;
+ }
+
protected native void nativeStopTune(long deviceId);
/**
@@ -235,7 +328,7 @@ public abstract class TunerHal implements AutoCloseable {
/**
* Opens Linux DVB frontend device. This method is called from native JNI and used only for
- * UsbTunerHal.
+ * DvbTunerHal.
*/
protected int openDvbFrontEndFd() {
return -1;
@@ -243,7 +336,7 @@ public abstract class TunerHal implements AutoCloseable {
/**
* Opens Linux DVB demux device. This method is called from native JNI and used only for
- * UsbTunerHal.
+ * DvbTunerHal.
*/
protected int openDvbDemuxFd() {
return -1;
@@ -251,7 +344,7 @@ public abstract class TunerHal implements AutoCloseable {
/**
* Opens Linux DVB dvr device. This method is called from native JNI and used only for
- * UsbTunerHal.
+ * DvbTunerHal.
*/
protected int openDvbDvrFd() {
return -1;
diff --git a/src/com/android/tv/tuner/TunerInputController.java b/src/com/android/tv/tuner/TunerInputController.java
index d89b6a0c..e06b9b4a 100644
--- a/src/com/android/tv/tuner/TunerInputController.java
+++ b/src/com/android/tv/tuner/TunerInputController.java
@@ -16,30 +16,43 @@
package com.android.tv.tuner;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
-import android.media.tv.TvInputInfo;
-import android.media.tv.TvInputManager;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.support.v4.os.BuildCompat;
+import android.os.SystemClock;
+import android.preference.PreferenceManager;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.android.tv.Features;
+import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.tuner.R;
+import com.android.tv.common.SoftPreconditions;
import com.android.tv.tuner.setup.TunerSetupActivity;
import com.android.tv.tuner.tvinput.TunerTvInputService;
+import com.android.tv.tuner.util.SystemPropertiesProxy;
import com.android.tv.tuner.util.TunerInputInfoUtils;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
/**
* Controls the package visibility of {@link TunerTvInputService}.
@@ -48,84 +61,94 @@ import java.util.Map;
* {@code UsbManager.ACTION_USB_DEVICE_ATTACHED}, and {@code UsbManager.ACTION_USB_DEVICE_ATTACHED}
* to update the connection status of the supported USB TV tuners.
*/
-public class TunerInputController extends BroadcastReceiver {
+public class TunerInputController {
private static final boolean DEBUG = true;
private static final String TAG = "TunerInputController";
+ private static final String PREFERENCE_IS_NETWORK_TUNER_ATTACHED = "network_tuner";
+ private static final String SECURITY_PATCH_LEVEL_KEY = "ro.build.version.security_patch";
+ private static final String SECURITY_PATCH_LEVEL_FORMAT = "yyyy-MM-dd";
+
+ /**
+ * Action of {@link Intent} to check network connection repeatedly when it is necessary.
+ */
+ private static final String CHECKING_NETWORK_CONNECTION =
+ "com.android.tv.action.CHECKING_NETWORK_CONNECTION";
+
+ private static final String EXTRA_CHECKING_DURATION =
+ "com.android.tv.action.extra.CHECKING_DURATION";
+
+ private static final long INITIAL_CHECKING_DURATION_MS = TimeUnit.SECONDS.toMillis(10);
+ private static final long MAXIMUM_CHECKING_DURATION_MS = TimeUnit.MINUTES.toMillis(10);
private static final TunerDevice[] TUNER_DEVICES = {
- new TunerDevice(0x2040, 0xb123), // WinTV-HVR-955Q
- new TunerDevice(0x07ca, 0x0837) // AverTV Volar Hybrid Q
+ new TunerDevice(0x2040, 0xb123, null), // WinTV-HVR-955Q
+ new TunerDevice(0x07ca, 0x0837, null), // AverTV Volar Hybrid Q
+ // WinTV-dualHD (bulk) will be supported after 2017 April security patch.
+ new TunerDevice(0x2040, 0x826d, "2017-04-01"), // WinTV-dualHD (bulk)
+ // STOPSHIP: Add WinTV-soloHD (Isoc) temporary for test. Remove this after test complete.
+ new TunerDevice(0x2040, 0x0264, null),
};
private static final int MSG_ENABLE_INPUT_SERVICE = 1000;
private static final long DVB_DRIVER_CHECK_DELAY_MS = 300;
- private DvbDeviceAccessor mDvbDeviceAccessor;
- private final Handler mHandler = new Handler(Looper.getMainLooper()) {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_ENABLE_INPUT_SERVICE:
- Context context = (Context) msg.obj;
- if (mDvbDeviceAccessor == null) {
- mDvbDeviceAccessor = new DvbDeviceAccessor(context);
- }
- enableTunerTvInputService(context, mDvbDeviceAccessor.isDvbDeviceAvailable());
- break;
- }
- }
- };
-
/**
- * Simple data holder for a USB device. Used to represent a tuner model, and compare
- * against {@link UsbDevice}.
+ * Checks status of USB devices to see if there are available USB tuners connected.
*/
- private static class TunerDevice {
- private final int vendorId;
- private final int productId;
-
- private TunerDevice(int vendorId, int productId) {
- this.vendorId = vendorId;
- this.productId = productId;
- }
-
- private boolean equals(UsbDevice device) {
- return device.getVendorId() == vendorId && device.getProductId() == productId;
- }
+ public static void onCheckingUsbTunerStatus(Context context, String action) {
+ onCheckingUsbTunerStatus(context, action, new CheckDvbDeviceHandler());
}
- @Override
- public void onReceive(Context context, Intent intent) {
- if (DEBUG) Log.d(TAG, "Broadcast intent received:" + intent);
- TvApplication.setCurrentRunningProcess(context, true);
- if (!Features.TUNER.isEnabled(context)) {
- enableTunerTvInputService(context, false);
+ private static void onCheckingUsbTunerStatus(Context context, String action,
+ @NonNull CheckDvbDeviceHandler handler) {
+ SharedPreferences sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(context);
+ if (TunerHal.useBuiltInTuner(context)) {
+ enableTunerTvInputService(context, true, false, TunerHal.TUNER_TYPE_BUILT_IN);
return;
}
+ // Falls back to the below to check USB tuner devices.
+ boolean enabled = isUsbTunerConnected(context);
+ handler.removeMessages(MSG_ENABLE_INPUT_SERVICE);
+ if (enabled) {
+ // Need to check if DVB driver is accessible. Since the driver creation
+ // could be happen after the USB event, delay the checking by
+ // DVB_DRIVER_CHECK_DELAY_MS.
+ handler.sendMessageDelayed(handler.obtainMessage(MSG_ENABLE_INPUT_SERVICE, context),
+ DVB_DRIVER_CHECK_DELAY_MS);
+ } else {
+ if (sharedPreferences.getBoolean(PREFERENCE_IS_NETWORK_TUNER_ATTACHED, false)) {
+ // Since network tuner is attached, do not disable TunerTvInput,
+ // just updates the TvInputInfo.
+ TunerInputInfoUtils.updateTunerInputInfo(context);
+ return;
+ }
+ enableTunerTvInputService(context, false, false, TextUtils
+ .equals(action, UsbManager.ACTION_USB_DEVICE_DETACHED) ?
+ TunerHal.TUNER_TYPE_USB : null);
+ }
+ }
- switch (intent.getAction()) {
- case Intent.ACTION_BOOT_COMPLETED:
- case TvApplication.ACTION_APPLICATION_FIRST_LAUNCHED:
- case UsbManager.ACTION_USB_DEVICE_ATTACHED:
- case UsbManager.ACTION_USB_DEVICE_DETACHED:
- if (TunerInputInfoUtils.isBuiltInTuner(context)) {
- enableTunerTvInputService(context, true);
- break;
- }
- // Falls back to the below to check USB tuner devices.
- boolean enabled = isUsbTunerConnected(context);
- mHandler.removeMessages(MSG_ENABLE_INPUT_SERVICE);
- if (enabled) {
- // Need to check if DVB driver is accessible. Since the driver creation
- // could be happen after the USB event, delay the checking by
- // DVB_DRIVER_CHECK_DELAY_MS.
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MSG_ENABLE_INPUT_SERVICE, context),
- DVB_DRIVER_CHECK_DELAY_MS);
- } else {
- enableTunerTvInputService(context, false);
- }
- break;
+ private static void onNetworkTunerChanged(Context context, boolean enabled) {
+ SharedPreferences sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(context);
+ if (enabled) {
+ // Network tuner detection is initiated by UI. So the app should not
+ // be killed.
+ sharedPreferences.edit().putBoolean(PREFERENCE_IS_NETWORK_TUNER_ATTACHED, true).apply();
+ enableTunerTvInputService(context, true, true, TunerHal.TUNER_TYPE_NETWORK);
+ } else {
+ sharedPreferences.edit()
+ .putBoolean(PREFERENCE_IS_NETWORK_TUNER_ATTACHED, false).apply();
+ if(!isUsbTunerConnected(context) && !TunerHal.useBuiltInTuner(context)) {
+ // Network tuner detection is initiated by UI. So the app should not
+ // be killed.
+ enableTunerTvInputService(context, false, true, TunerHal.TUNER_TYPE_NETWORK);
+ } else {
+ // Since USB tuner is attached, do not disable TunerTvInput,
+ // just updates the TvInputInfo.
+ TunerInputInfoUtils.updateTunerInputInfo(context);
+ }
}
}
@@ -135,15 +158,18 @@ public class TunerInputController extends BroadcastReceiver {
* @param context {@link Context} instance
* @return {@code true} if any tuner device we support is plugged in
*/
- private boolean isUsbTunerConnected(Context context) {
+ private static boolean isUsbTunerConnected(Context context) {
UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
Map<String, UsbDevice> deviceList = manager.getDeviceList();
+ String currentSecurityLevel =
+ SystemPropertiesProxy.getString(SECURITY_PATCH_LEVEL_KEY, null);
+
for (UsbDevice device : deviceList.values()) {
if (DEBUG) {
Log.d(TAG, "Device: " + device);
}
for (TunerDevice tuner : TUNER_DEVICES) {
- if (tuner.equals(device)) {
+ if (tuner.equals(device) && tuner.isSupported(currentSecurityLevel)) {
Log.i(TAG, "Tuner found");
return true;
}
@@ -158,7 +184,8 @@ public class TunerInputController extends BroadcastReceiver {
* @param context {@link Context} instance
* @param enabled {@code true} to enable the service; otherwise {@code false}
*/
- private void enableTunerTvInputService(Context context, boolean enabled) {
+ private static void enableTunerTvInputService(Context context, boolean enabled,
+ boolean forceDontKillApp, Integer tunerType) {
if (DEBUG) Log.d(TAG, "enableTunerTvInputService: " + enabled);
PackageManager pm = context.getPackageManager();
ComponentName componentName = new ComponentName(context, TunerTvInputService.class);
@@ -170,23 +197,182 @@ public class TunerInputController extends BroadcastReceiver {
// Since PackageManager.DONT_KILL_APP delays the operation by 10 seconds
// (PackageManagerService.BROADCAST_DELAY), we'd better avoid using it. It is used only
// when the LiveChannels app is active since we don't want to kill the running app.
- int flags = TvApplication.getSingletons(context).getMainActivityWrapper().isCreated()
+ int flags = forceDontKillApp
+ || TvApplication.getSingletons(context).getMainActivityWrapper().isCreated()
? PackageManager.DONT_KILL_APP : 0;
int newState = enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
if (newState != pm.getComponentEnabledSetting(componentName)) {
- // Send/cancel the USB tuner TV input setup recommendation card.
- TunerSetupActivity.onTvInputEnabled(context, enabled);
+ // Send/cancel the USB tuner TV input setup notification.
+ TunerSetupActivity.onTvInputEnabled(context, enabled, tunerType);
// Enable/disable the USB tuner TV input.
pm.setComponentEnabledSetting(componentName, newState, flags);
- if (!enabled) {
- Toast.makeText(
- context, R.string.msg_usb_device_detached, Toast.LENGTH_SHORT).show();
+ if (!enabled && tunerType != null) {
+ if (tunerType == TunerHal.TUNER_TYPE_USB) {
+ Toast.makeText(context, R.string.msg_usb_tuner_disconnected,
+ Toast.LENGTH_SHORT).show();
+ } else if (tunerType == TunerHal.TUNER_TYPE_NETWORK) {
+ Toast.makeText(context, R.string.msg_network_tuner_disconnected,
+ Toast.LENGTH_SHORT).show();
+ }
}
if (DEBUG) Log.d(TAG, "Status updated:" + enabled);
} else if (enabled) {
- // When # of USB tuners is changed or the device just boots.
+ // When # of tuners is changed or the tuner input service is switching from/to using
+ // network tuners or the device just boots.
TunerInputInfoUtils.updateTunerInputInfo(context);
}
}
+
+ /**
+ * Discovers a network tuner. If the network connection is down, it won't repeatedly checking.
+ */
+ public static void executeNetworkTunerDiscoveryAsyncTask(final Context context) {
+ boolean runningInMainProcess =
+ TvApplication.getSingletons(context).isRunningInMainProcess();
+ SoftPreconditions.checkState(runningInMainProcess);
+ if (!runningInMainProcess) {
+ return;
+ }
+ executeNetworkTunerDiscoveryAsyncTask(context, 0);
+ }
+
+ /**
+ * Discovers a network tuner.
+ * @param context {@link Context}
+ * @param repeatedDurationMs the time length to wait to repeatedly check network status to start
+ * finding network tuner when the network connection is not available.
+ * {@code 0} to disable repeatedly checking.
+ */
+ private static void executeNetworkTunerDiscoveryAsyncTask(final Context context,
+ final long repeatedDurationMs) {
+ if (!Features.NETWORK_TUNER.isEnabled(context)) {
+ return;
+ }
+ new AsyncTask<Void, Void, Boolean>() {
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ if (isNetworkConnected(context)) {
+ // Implement and execute network tuner discovery AsyncTask here.
+ } else if (repeatedDurationMs > 0) {
+ AlarmManager alarmManager =
+ (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ Intent networkCheckingIntent = new Intent(context, IntentReceiver.class);
+ networkCheckingIntent.setAction(CHECKING_NETWORK_CONNECTION);
+ networkCheckingIntent.putExtra(EXTRA_CHECKING_DURATION, repeatedDurationMs);
+ PendingIntent alarmIntent = PendingIntent.getBroadcast(
+ context, 0, networkCheckingIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ alarmManager.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()
+ + repeatedDurationMs, alarmIntent);
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ if (result == null) {
+ return;
+ }
+ onNetworkTunerChanged(context, result);
+ }
+ }.execute();
+ }
+
+ private static boolean isNetworkConnected(Context context) {
+ ConnectivityManager cm = (ConnectivityManager)
+ context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = cm.getActiveNetworkInfo();
+ return networkInfo != null && networkInfo.isConnected();
+ }
+
+ public static class IntentReceiver extends BroadcastReceiver {
+ private final CheckDvbDeviceHandler mHandler = new CheckDvbDeviceHandler();
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG) Log.d(TAG, "Broadcast intent received:" + intent);
+ TvApplication.setCurrentRunningProcess(context, true);
+ if (!Features.TUNER.isEnabled(context)) {
+ enableTunerTvInputService(context, false, false, null);
+ return;
+ }
+ switch (intent.getAction()) {
+ case Intent.ACTION_BOOT_COMPLETED:
+ executeNetworkTunerDiscoveryAsyncTask(context, INITIAL_CHECKING_DURATION_MS);
+ case TvApplication.ACTION_APPLICATION_FIRST_LAUNCHED:
+ case UsbManager.ACTION_USB_DEVICE_ATTACHED:
+ case UsbManager.ACTION_USB_DEVICE_DETACHED:
+ onCheckingUsbTunerStatus(context, intent.getAction(), mHandler);
+ break;
+ case CHECKING_NETWORK_CONNECTION:
+ long repeatedDurationMs = intent.getLongExtra(EXTRA_CHECKING_DURATION,
+ INITIAL_CHECKING_DURATION_MS);
+ executeNetworkTunerDiscoveryAsyncTask(context,
+ Math.min(repeatedDurationMs * 2, MAXIMUM_CHECKING_DURATION_MS));
+ break;
+ }
+ }
+ }
+
+ /**
+ * Simple data holder for a USB device. Used to represent a tuner model, and compare
+ * against {@link UsbDevice}.
+ */
+ private static class TunerDevice {
+ private final int vendorId;
+ private final int productId;
+
+ // security patch level from which the specific tuner type is supported.
+ private final String minSecurityLevel;
+
+ private TunerDevice(int vendorId, int productId, String minSecurityLevel) {
+ this.vendorId = vendorId;
+ this.productId = productId;
+ this.minSecurityLevel = minSecurityLevel;
+ }
+
+ private boolean equals(UsbDevice device) {
+ return device.getVendorId() == vendorId && device.getProductId() == productId;
+ }
+
+ private boolean isSupported(String currentSecurityLevel) {
+ if (minSecurityLevel == null) {
+ return true;
+ }
+
+ long supportSecurityLevelTimeStamp = 0;
+ long currentSecurityLevelTimestamp = 0;
+ try {
+ SimpleDateFormat format = new SimpleDateFormat(SECURITY_PATCH_LEVEL_FORMAT);
+ supportSecurityLevelTimeStamp = format.parse(minSecurityLevel).getTime();
+ currentSecurityLevelTimestamp = format.parse(currentSecurityLevel).getTime();
+ } catch (ParseException e) {
+ }
+ return supportSecurityLevelTimeStamp != 0
+ && supportSecurityLevelTimeStamp <= currentSecurityLevelTimestamp;
+ }
+ }
+
+ private static class CheckDvbDeviceHandler extends Handler {
+ private DvbDeviceAccessor mDvbDeviceAccessor;
+
+ CheckDvbDeviceHandler() {
+ super(Looper.getMainLooper());
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ENABLE_INPUT_SERVICE:
+ Context context = (Context) msg.obj;
+ if (mDvbDeviceAccessor == null) {
+ mDvbDeviceAccessor = new DvbDeviceAccessor(context);
+ }
+ boolean enabled = mDvbDeviceAccessor.isDvbDeviceAvailable();
+ enableTunerTvInputService(
+ context, enabled, false, enabled ? TunerHal.TUNER_TYPE_USB : null);
+ break;
+ }
+ }
+ }
}
diff --git a/src/com/android/tv/tuner/TunerPreferences.java b/src/com/android/tv/tuner/TunerPreferences.java
index 1547e3ae..11a6a969 100644
--- a/src/com/android/tv/tuner/TunerPreferences.java
+++ b/src/com/android/tv/tuner/TunerPreferences.java
@@ -25,11 +25,15 @@ import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
+import android.support.annotation.GuardedBy;
+import android.support.annotation.IntDef;
import android.support.annotation.MainThread;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.tuner.TunerPreferenceProvider.Preferences;
import com.android.tv.tuner.util.TisConfiguration;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* A helper class for the USB tuner preferences.
@@ -39,21 +43,53 @@ public class TunerPreferences {
private static final String PREFS_KEY_CHANNEL_DATA_VERSION = "channel_data_version";
private static final String PREFS_KEY_SCANNED_CHANNEL_COUNT = "scanned_channel_count";
+ private static final String PREFS_KEY_LAST_POSTAL_CODE = "last_postal_code";
private static final String PREFS_KEY_SCAN_DONE = "scan_done";
private static final String PREFS_KEY_LAUNCH_SETUP = "launch_setup";
private static final String PREFS_KEY_STORE_TS_STREAM = "store_ts_stream";
+ private static final String PREFS_KEY_TRICKPLAY_SETTING = "trickplay_setting";
+ private static final String PREFS_KEY_TRICKPLAY_EXPIRED_MS = "trickplay_expired_ms";
private static final String SHARED_PREFS_NAME = "com.android.tv.tuner.preferences";
public static final int CHANNEL_DATA_VERSION_NOT_SET = -1;
+ @IntDef({TRICKPLAY_SETTING_NOT_SET, TRICKPLAY_SETTING_DISABLED, TRICKPLAY_SETTING_ENABLED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TrickplaySetting {
+ }
+
+ /**
+ * Trickplay setting is not changed by a user. Trickplay will be enabled in this case.
+ */
+ public static final int TRICKPLAY_SETTING_NOT_SET = -1;
+
+ /**
+ * Trickplay setting is disabled.
+ */
+ public static final int TRICKPLAY_SETTING_DISABLED = 0;
+
+ /**
+ * Trickplay setting is enabled.
+ */
+ public static final int TRICKPLAY_SETTING_ENABLED = 1;
+
+ @GuardedBy("TunerPreferences.class")
private static final Bundle sPreferenceValues = new Bundle();
private static LoadPreferencesTask sLoadPreferencesTask;
private static ContentObserver sContentObserver;
+ private static TunerPreferencesChangedListener sPreferencesChangedListener = null;
private static boolean sInitialized;
/**
+ * Listeners for TunerPreferences change.
+ */
+ public interface TunerPreferencesChangedListener {
+ void onTunerPreferencesChanged();
+ }
+
+ /**
* Initializes the USB tuner preferences.
*/
@MainThread
@@ -86,11 +122,19 @@ public class TunerPreferences {
/**
* Releases the resources.
*/
- @MainThread
- public static void release(Context context) {
+ public static synchronized void release(Context context) {
if (useContentProvider(context) && sContentObserver != null) {
context.getContentResolver().unregisterContentObserver(sContentObserver);
}
+ setTunerPreferencesChangedListener(null);
+ }
+
+ /**
+ * Sets the listener for TunerPreferences change.
+ */
+ public static void setTunerPreferencesChangedListener(
+ TunerPreferencesChangedListener listener) {
+ sPreferencesChangedListener = listener;
}
/**
@@ -99,7 +143,8 @@ public class TunerPreferences {
* This preferences is used across processes, so the preferences should be loaded again when the
* databases changes.
*/
- public static synchronized void loadPreferences(Context context) {
+ @MainThread
+ public static void loadPreferences(Context context) {
if (sLoadPreferencesTask != null
&& sLoadPreferencesTask.getStatus() != AsyncTask.Status.FINISHED) {
sLoadPreferencesTask.cancel(true);
@@ -113,8 +158,7 @@ public class TunerPreferences {
return TisConfiguration.isPackagedWithLiveChannels(context);
}
- @MainThread
- public static int getChannelDataVersion(Context context) {
+ public static synchronized int getChannelDataVersion(Context context) {
SoftPreconditions.checkState(sInitialized);
if (useContentProvider(context)) {
return sPreferenceValues.getInt(PREFS_KEY_CHANNEL_DATA_VERSION,
@@ -126,8 +170,7 @@ public class TunerPreferences {
}
}
- @MainThread
- public static void setChannelDataVersion(Context context, int version) {
+ public static synchronized void setChannelDataVersion(Context context, int version) {
if (useContentProvider(context)) {
setPreference(context, PREFS_KEY_CHANNEL_DATA_VERSION, version);
} else {
@@ -137,8 +180,7 @@ public class TunerPreferences {
}
}
- @MainThread
- public static int getScannedChannelCount(Context context) {
+ public static synchronized int getScannedChannelCount(Context context) {
SoftPreconditions.checkState(sInitialized);
if (useContentProvider(context)) {
return sPreferenceValues.getInt(PREFS_KEY_SCANNED_CHANNEL_COUNT);
@@ -148,8 +190,7 @@ public class TunerPreferences {
}
}
- @MainThread
- public static void setScannedChannelCount(Context context, int channelCount) {
+ public static synchronized void setScannedChannelCount(Context context, int channelCount) {
if (useContentProvider(context)) {
setPreference(context, PREFS_KEY_SCANNED_CHANNEL_COUNT, channelCount);
} else {
@@ -159,8 +200,25 @@ public class TunerPreferences {
}
}
- @MainThread
- public static boolean isScanDone(Context context) {
+ public static synchronized String getLastPostalCode(Context context) {
+ SoftPreconditions.checkState(sInitialized);
+ if (useContentProvider(context)) {
+ return sPreferenceValues.getString(PREFS_KEY_LAST_POSTAL_CODE);
+ } else {
+ return getSharedPreferences(context).getString(PREFS_KEY_LAST_POSTAL_CODE, null);
+ }
+ }
+
+ public static synchronized void setLastPostalCode(Context context, String postalCode) {
+ if (useContentProvider(context)) {
+ setPreference(context, PREFS_KEY_LAST_POSTAL_CODE, postalCode);
+ } else {
+ getSharedPreferences(context).edit()
+ .putString(PREFS_KEY_LAST_POSTAL_CODE, postalCode).apply();
+ }
+ }
+
+ public static synchronized boolean isScanDone(Context context) {
SoftPreconditions.checkState(sInitialized);
if (useContentProvider(context)) {
return sPreferenceValues.getBoolean(PREFS_KEY_SCAN_DONE);
@@ -170,8 +228,7 @@ public class TunerPreferences {
}
}
- @MainThread
- public static void setScanDone(Context context) {
+ public static synchronized void setScanDone(Context context) {
if (useContentProvider(context)) {
setPreference(context, PREFS_KEY_SCAN_DONE, true);
} else {
@@ -181,8 +238,7 @@ public class TunerPreferences {
}
}
- @MainThread
- public static boolean shouldShowSetupActivity(Context context) {
+ public static synchronized boolean shouldShowSetupActivity(Context context) {
SoftPreconditions.checkState(sInitialized);
if (useContentProvider(context)) {
return sPreferenceValues.getBoolean(PREFS_KEY_LAUNCH_SETUP);
@@ -192,8 +248,7 @@ public class TunerPreferences {
}
}
- @MainThread
- public static void setShouldShowSetupActivity(Context context, boolean need) {
+ public static synchronized void setShouldShowSetupActivity(Context context, boolean need) {
if (useContentProvider(context)) {
setPreference(context, PREFS_KEY_LAUNCH_SETUP, need);
} else {
@@ -203,8 +258,50 @@ public class TunerPreferences {
}
}
- @MainThread
- public static boolean getStoreTsStream(Context context) {
+ public static synchronized long getTrickplayExpiredMs(Context context) {
+ SoftPreconditions.checkState(sInitialized);
+ if (useContentProvider(context)) {
+ return sPreferenceValues.getLong(PREFS_KEY_TRICKPLAY_EXPIRED_MS, 0);
+ } else {
+ return getSharedPreferences(context)
+ .getLong(TunerPreferences.PREFS_KEY_TRICKPLAY_EXPIRED_MS, 0);
+ }
+ }
+
+ public static synchronized void setTrickplayExpiredMs(Context context, long timeMs) {
+ if (useContentProvider(context)) {
+ setPreference(context, PREFS_KEY_TRICKPLAY_EXPIRED_MS, timeMs);
+ } else {
+ getSharedPreferences(context).edit()
+ .putLong(TunerPreferences.PREFS_KEY_TRICKPLAY_EXPIRED_MS, timeMs)
+ .apply();
+ }
+ }
+
+ public static synchronized @TrickplaySetting int getTrickplaySetting(Context context) {
+ SoftPreconditions.checkState(sInitialized);
+ if (useContentProvider(context)) {
+ return sPreferenceValues.getInt(PREFS_KEY_TRICKPLAY_SETTING, TRICKPLAY_SETTING_NOT_SET);
+ } else {
+ return getSharedPreferences(context)
+ .getInt(TunerPreferences.PREFS_KEY_TRICKPLAY_SETTING, TRICKPLAY_SETTING_NOT_SET);
+ }
+ }
+
+ public static synchronized void setTrickplaySetting(Context context,
+ @TrickplaySetting int trickplaySetting) {
+ SoftPreconditions.checkState(sInitialized);
+ SoftPreconditions.checkArgument(trickplaySetting != TRICKPLAY_SETTING_NOT_SET);
+ if (useContentProvider(context)) {
+ setPreference(context, PREFS_KEY_TRICKPLAY_SETTING, trickplaySetting);
+ } else {
+ getSharedPreferences(context).edit()
+ .putInt(TunerPreferences.PREFS_KEY_TRICKPLAY_SETTING, trickplaySetting)
+ .apply();
+ }
+ }
+
+ public static synchronized boolean getStoreTsStream(Context context) {
SoftPreconditions.checkState(sInitialized);
if (useContentProvider(context)) {
return sPreferenceValues.getBoolean(PREFS_KEY_STORE_TS_STREAM, false);
@@ -214,8 +311,7 @@ public class TunerPreferences {
}
}
- @MainThread
- public static void setStoreTsStream(Context context, boolean shouldStore) {
+ public static synchronized void setStoreTsStream(Context context, boolean shouldStore) {
if (useContentProvider(context)) {
setPreference(context, PREFS_KEY_STORE_TS_STREAM, shouldStore);
} else {
@@ -229,8 +325,28 @@ public class TunerPreferences {
return context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE);
}
- @MainThread
- private static void setPreference(final Context context, final String key, final String value) {
+ private static synchronized void setPreference(Context context, String key, String value) {
+ sPreferenceValues.putString(key, value);
+ savePreference(context, key, value);
+ }
+
+ private static synchronized void setPreference(Context context, String key, int value) {
+ sPreferenceValues.putInt(key, value);
+ savePreference(context, key, Integer.toString(value));
+ }
+
+ private static synchronized void setPreference(Context context, String key, long value) {
+ sPreferenceValues.putLong(key, value);
+ savePreference(context, key, Long.toString(value));
+ }
+
+ private static synchronized void setPreference(Context context, String key, boolean value) {
+ sPreferenceValues.putBoolean(key, value);
+ savePreference(context, key, Boolean.toString(value));
+ }
+
+ private static void savePreference(final Context context, final String key,
+ final String value) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
@@ -249,18 +365,6 @@ public class TunerPreferences {
}.execute();
}
- @MainThread
- private static void setPreference(Context context, String key, int value) {
- sPreferenceValues.putInt(key, value);
- setPreference(context, key, Integer.toString(value));
- }
-
- @MainThread
- private static void setPreference(Context context, String key, boolean value) {
- sPreferenceValues.putBoolean(key, value);
- setPreference(context, key, Boolean.toString(value));
- }
-
private static class LoadPreferencesTask extends AsyncTask<Void, Void, Bundle> {
private final Context mContext;
private LoadPreferencesTask(Context context) {
@@ -279,8 +383,12 @@ public class TunerPreferences {
String key = cursor.getString(0);
String value = cursor.getString(1);
switch (key) {
+ case PREFS_KEY_TRICKPLAY_EXPIRED_MS:
+ bundle.putLong(key, Long.parseLong(value));
+ break;
case PREFS_KEY_CHANNEL_DATA_VERSION:
case PREFS_KEY_SCANNED_CHANNEL_COUNT:
+ case PREFS_KEY_TRICKPLAY_SETTING:
try {
bundle.putInt(key, Integer.parseInt(value));
} catch (NumberFormatException e) {
@@ -292,6 +400,9 @@ public class TunerPreferences {
case PREFS_KEY_STORE_TS_STREAM:
bundle.putBoolean(key, Boolean.parseBoolean(value));
break;
+ case PREFS_KEY_LAST_POSTAL_CODE:
+ bundle.putString(key, value);
+ break;
}
}
}
@@ -304,7 +415,14 @@ public class TunerPreferences {
@Override
protected void onPostExecute(Bundle bundle) {
- sPreferenceValues.putAll(bundle);
+ synchronized (TunerPreferences.class) {
+ if (bundle != null) {
+ sPreferenceValues.putAll(bundle);
+ }
+ }
+ if (sPreferencesChangedListener != null) {
+ sPreferencesChangedListener.onTunerPreferencesChanged();
+ }
}
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/tuner/UsbTunerHal.java b/src/com/android/tv/tuner/UsbTunerHal.java
deleted file mode 100644
index 22e35ea1..00000000
--- a/src/com/android/tv/tuner/UsbTunerHal.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.tuner;
-
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-import com.android.tv.tuner.DvbDeviceAccessor.DvbDeviceInfoWrapper;
-
-import java.util.List;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * A class to handle a hardware USB tuner device.
- */
-public class UsbTunerHal extends TunerHal {
-
- private static final Object sLock = new Object();
- // @GuardedBy("sLock")
- private static final SortedSet<DvbDeviceInfoWrapper> sUsedDvbDevices = new TreeSet<>();
-
- private final DvbDeviceAccessor mDvbDeviceAccessor;
- private DvbDeviceInfoWrapper mDvbDeviceInfo;
-
- protected UsbTunerHal(Context context) {
- super(context);
- mDvbDeviceAccessor = new DvbDeviceAccessor(context);
- }
-
- @Override
- protected boolean openFirstAvailable() {
- List<DvbDeviceInfoWrapper> deviceInfoList = mDvbDeviceAccessor.getDvbDeviceList();
- if (deviceInfoList == null || deviceInfoList.isEmpty()) {
- Log.e(TAG, "There's no dvb device attached");
- return false;
- }
- synchronized (sLock) {
- for (DvbDeviceInfoWrapper deviceInfo : deviceInfoList) {
- if (!sUsedDvbDevices.contains(deviceInfo)) {
- if (DEBUG) Log.d(TAG, "Available device info: " + deviceInfo);
- mDvbDeviceInfo = deviceInfo;
- sUsedDvbDevices.add(deviceInfo);
- return true;
- }
- }
- }
- Log.e(TAG, "There's no available dvb devices");
- return false;
- }
-
- /**
- * Acquires the tuner device. The requested device will be locked to the current instance if
- * it's not acquired by others.
- *
- * @param deviceInfo a tuner device to open
- * @return {@code true} if the operation was successful, {@code false} otherwise
- */
- protected boolean open(DvbDeviceInfoWrapper deviceInfo) {
- if (deviceInfo == null) {
- Log.e(TAG, "Device info should not be null");
- return false;
- }
- if (mDvbDeviceInfo != null) {
- Log.e(TAG, "Already acquired");
- return false;
- }
- List<DvbDeviceInfoWrapper> deviceInfoList = mDvbDeviceAccessor.getDvbDeviceList();
- if (deviceInfoList == null || deviceInfoList.isEmpty()) {
- Log.e(TAG, "There's no dvb device attached");
- return false;
- }
- for (DvbDeviceInfoWrapper deviceInfoWrapper : deviceInfoList) {
- if (deviceInfoWrapper.compareTo(deviceInfo) == 0) {
- synchronized (sLock) {
- if (sUsedDvbDevices.contains(deviceInfo)) {
- Log.e(TAG, deviceInfo + " is already taken");
- return false;
- }
- sUsedDvbDevices.add(deviceInfo);
- }
- if (DEBUG) Log.d(TAG, "Available device info: " + deviceInfo);
- mDvbDeviceInfo = deviceInfo;
- return true;
- }
- }
- Log.e(TAG, "There's no such dvb device attached");
- return false;
- }
-
- @Override
- public void close() {
- if (mDvbDeviceInfo != null) {
- if (isStreaming()) {
- stopTune();
- }
- nativeFinalize(mDvbDeviceInfo.getId());
- synchronized (sLock) {
- sUsedDvbDevices.remove(mDvbDeviceInfo);
- }
- mDvbDeviceInfo = null;
- }
- }
-
- @Override
- protected boolean isDeviceOpen() {
- return (mDvbDeviceInfo != null);
- }
-
- @Override
- protected long getDeviceId() {
- if (mDvbDeviceInfo != null) {
- return mDvbDeviceInfo.getId();
- }
- return -1;
- }
-
- @Override
- protected int openDvbFrontEndFd() {
- if (mDvbDeviceInfo != null) {
- ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice(
- mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_FRONTEND);
- if (descriptor != null) {
- return descriptor.detachFd();
- }
- }
- return -1;
- }
-
- @Override
- protected int openDvbDemuxFd() {
- if (mDvbDeviceInfo != null) {
- ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice(
- mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_DEMUX);
- if (descriptor != null) {
- return descriptor.detachFd();
- }
- }
- return -1;
- }
-
- @Override
- protected int openDvbDvrFd() {
- if (mDvbDeviceInfo != null) {
- ParcelFileDescriptor descriptor = mDvbDeviceAccessor.openDvbDevice(
- mDvbDeviceInfo, DvbDeviceAccessor.DVB_DEVICE_DVR);
- if (descriptor != null) {
- return descriptor.detachFd();
- }
- }
- return -1;
- }
-
- /**
- * Gets the number of USB tuner devices currently present.
- */
- public static int getNumberOfDevices(Context context) {
- return (new DvbDeviceAccessor(context)).getNumOfDvbDevices();
- }
-}
diff --git a/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java b/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java
index 3c75caa9..24a0f354 100644
--- a/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java
+++ b/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java
@@ -245,6 +245,10 @@ public class CaptionTrackRenderer implements Handler.Callback {
}
}
+ public void clear() {
+ mHandler.sendEmptyMessage(MSG_CAPTION_CLEAR);
+ }
+
public void reset() {
mCurrentWindowLayout = null;
mIsDelayed = false;
diff --git a/src/com/android/tv/tuner/cc/Cea708Parser.java b/src/com/android/tv/tuner/cc/Cea708Parser.java
index 92ab0620..d0f6cf11 100644
--- a/src/com/android/tv/tuner/cc/Cea708Parser.java
+++ b/src/com/android/tv/tuner/cc/Cea708Parser.java
@@ -140,6 +140,7 @@ public class Cea708Parser {
private int mCommand = 0;
private int mListenServiceNumber = 0;
private boolean mDtvCcPacking = false;
+ private boolean mFirstServiceNumberDiscovered;
// Assign a dummy listener in order to avoid null checks.
private OnCea708ParserListener mListener = new OnCea708ParserListener() {
@@ -208,6 +209,15 @@ public class Cea708Parser {
}
}
+ public void clear() {
+ mDtvCcPacket.clear();
+ mCcPackets.clear();
+ mBuffer.setLength(0);
+ mDiscoveredNumBytes.clear();
+ mCommand = 0;
+ mDtvCcPacking = false;
+ }
+
public void setListenServiceNumber(int serviceNumber) {
mListenServiceNumber = serviceNumber;
}
@@ -332,12 +342,14 @@ public class Cea708Parser {
mDiscoveredNumBytes.put(
serviceNumber, blockSize + mDiscoveredNumBytes.get(serviceNumber, 0));
}
- if (mLastDiscoveryLaunchedMs + DISCOVERY_PERIOD_MS < SystemClock.elapsedRealtime()) {
+ if (mLastDiscoveryLaunchedMs + DISCOVERY_PERIOD_MS < SystemClock.elapsedRealtime()
+ || !mFirstServiceNumberDiscovered) {
for (int i = 0; i < mDiscoveredNumBytes.size(); ++i) {
int discoveredNumBytes = mDiscoveredNumBytes.valueAt(i);
if (discoveredNumBytes >= DISCOVERY_NUM_BYTES_THRESHOLD) {
int discoveredServiceNumber = mDiscoveredNumBytes.keyAt(i);
mListener.discoverServiceNumber(discoveredServiceNumber);
+ mFirstServiceNumberDiscovered = true;
}
}
mDiscoveredNumBytes.clear();
diff --git a/src/com/android/tv/tuner/data/PsipData.java b/src/com/android/tv/tuner/data/PsipData.java
index aead4be8..8f98e67c 100644
--- a/src/com/android/tv/tuner/data/PsipData.java
+++ b/src/com/android/tv/tuner/data/PsipData.java
@@ -24,9 +24,10 @@ import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.ts.SectionParser;
import com.android.tv.tuner.util.ConvertUtils;
-import com.android.tv.tuner.util.StringUtils;
+import com.android.tv.util.StringUtils;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -226,6 +227,50 @@ public class PsipData {
}
}
+ public static class SdtItem {
+ private final String mServiceName;
+ private final String mServiceProviderName;
+ private final int mServiceType;
+ private final int mServiceId;
+ private final int mOriginalNetWorkId;
+
+ public SdtItem(String serviceName, String serviceProviderName, int serviceType,
+ int serviceId, int originalNetWorkId) {
+ mServiceName = serviceName;
+ mServiceProviderName = serviceProviderName;
+ mServiceType = serviceType;
+ mServiceId = serviceId;
+ mOriginalNetWorkId = originalNetWorkId;
+ }
+
+ public String getServiceName() {
+ return mServiceName;
+ }
+
+ public String getServiceProviderName() {
+ return mServiceProviderName;
+ }
+
+ public int getServiceType() {
+ return mServiceType;
+ }
+
+ public int getServiceId() {
+ return mServiceId;
+ }
+
+ public int getOriginalNetworkId() {
+ return mOriginalNetWorkId;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ServiceName: %s ServiceProviderName:%s ServiceType:%d "
+ + "OriginalNetworkId:%d",
+ mServiceName, mServiceProviderName, mServiceType, mOriginalNetWorkId);
+ }
+ }
+
/**
* A base class for descriptors of Ts packets.
*/
@@ -462,6 +507,92 @@ public class PsipData {
}
}
+ public static class ServiceDescriptor extends TsDescriptor {
+ private final int mServiceType;
+ private final String mServiceProviderName;
+ private final String mServiceName;
+
+ public ServiceDescriptor(int serviceType, String serviceProviderName, String serviceName) {
+ mServiceType = serviceType;
+ mServiceProviderName = serviceProviderName;
+ mServiceName = serviceName;
+ }
+
+ @Override
+ public int getTag() {
+ return SectionParser.DVB_DESCRIPTOR_TAG_SERVICE;
+ }
+
+ public int getServiceType() {
+ return mServiceType;
+ }
+
+ public String getServiceProviderName() {
+ return mServiceProviderName;
+ }
+
+ public String getServiceName() {
+ return mServiceName;
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "Service descriptor, service type: %d, "
+ + "service provider name: %s, "
+ + "service name: %s", mServiceType, mServiceProviderName, mServiceName);
+ }
+ }
+
+ public static class ShortEventDescriptor extends TsDescriptor {
+ private final String mLanguage;
+ private final String mEventName;
+ private final String mText;
+
+ public ShortEventDescriptor(String language, String eventName, String text) {
+ mLanguage = language;
+ mEventName = eventName;
+ mText = text;
+ }
+
+ public String getEventName() {
+ return mEventName;
+ }
+
+ @Override
+ public int getTag() {
+ return SectionParser.DVB_DESCRIPTOR_TAG_SHORT_EVENT;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ShortEvent Descriptor, language:%s, event name: %s, "
+ + "text:%s", mLanguage, mEventName, mText);
+ }
+ }
+
+ public static class ParentalRatingDescriptor extends TsDescriptor {
+ private final HashMap<String, Integer> mRatings;
+
+ public ParentalRatingDescriptor(HashMap<String, Integer> ratings) {
+ mRatings = ratings;
+ }
+
+ @Override
+ public int getTag() {
+ return SectionParser.DVB_DESCRIPTOR_TAG_PARENTAL_RATING;
+ }
+
+ public HashMap<String, Integer> getRatings() {
+ return mRatings;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Parental rating descriptor, ratings:" + mRatings);
+ }
+ }
+
public static class RatingRegion {
private final int mName;
private final String mDescription;
diff --git a/src/com/android/tv/tuner/data/TunerChannel.java b/src/com/android/tv/tuner/data/TunerChannel.java
index 89079d77..1cf514c1 100644
--- a/src/com/android/tv/tuner/data/TunerChannel.java
+++ b/src/com/android/tv/tuner/data/TunerChannel.java
@@ -24,7 +24,7 @@ import com.android.tv.tuner.data.nano.Channel.TunerChannelProto;
import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.util.Ints;
-import com.android.tv.tuner.util.StringUtils;
+import com.android.tv.util.StringUtils;
import com.google.protobuf.nano.MessageNano;
import java.io.IOException;
@@ -40,6 +40,11 @@ import java.util.Objects;
public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracksInterface {
private static final String TAG = "TunerChannel";
+ /**
+ * Channel number separator between major number and minor number.
+ */
+ public static final char CHANNEL_NUMBER_SEPARATOR = '-';
+
// See ATSC Code Points Registry.
private static final String[] ATSC_SERVICE_TYPE_NAMES = new String[] {
"ATSC Reserved",
@@ -63,6 +68,7 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
// According to ISO13818-1, Mpeg2 StreamType has a range from 0x00 to 0xff.
public static final int INVALID_STREAMTYPE = -1;
+ // @GuardedBy(this) Writing operations and toByteArray will be guarded. b/34197766
private final TunerChannelProto mProto;
private TunerChannel(PsipData.VctItem channel, int programNumber,
@@ -88,6 +94,10 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
}
mProto.serviceType = channel.getServiceType();
}
+ initProto(pmtItems, type);
+ }
+
+ private void initProto(List<PsiData.PmtItem> pmtItems, int type) {
mProto.type = type;
mProto.channelId = -1L;
mProto.frequency = INVALID_FREQUENCY;
@@ -129,14 +139,44 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
mProto.audioTrackIndex = (audioPids.size() > 0) ? 0 : -1;
}
+ private TunerChannel(int programNumber, int type, PsipData.SdtItem channel,
+ List<PsiData.PmtItem> pmtItems) {
+ mProto = new TunerChannelProto();
+ mProto.tsid = 0;
+ mProto.virtualMajor = 0;
+ mProto.virtualMinor = 0;
+ if (channel == null) {
+ mProto.shortName = "";
+ mProto.programNumber = programNumber;
+ } else {
+ mProto.shortName = channel.getServiceName();
+ mProto.programNumber = channel.getServiceId();
+ mProto.serviceType = channel.getServiceType();
+ }
+ initProto(pmtItems, type);
+ }
+
+ /**
+ * Initialize tuner channel with VCT items and PMT items.
+ */
public TunerChannel(PsipData.VctItem channel, List<PsiData.PmtItem> pmtItems) {
this(channel, 0, pmtItems, Channel.TYPE_TUNER);
}
+ /**
+ * Initialize tuner channel with program number and PMT items.
+ */
public TunerChannel(int programNumber, List<PsiData.PmtItem> pmtItems) {
this(null, programNumber, pmtItems, Channel.TYPE_TUNER);
}
+ /**
+ * Initialize tuner channel with SDT items and PMT items.
+ */
+ public TunerChannel(PsipData.SdtItem channel, List<PsiData.PmtItem> pmtItems) {
+ this(0, Channel.TYPE_TUNER, channel, pmtItems);
+ }
+
private TunerChannel(TunerChannelProto tunerChannelProto) {
mProto = tunerChannelProto;
}
@@ -145,6 +185,50 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
return new TunerChannel(channel, 0, pmtItems, Channel.TYPE_FILE);
}
+ public static TunerChannel forDvbFile(
+ PsipData.SdtItem channel, List<PsiData.PmtItem> pmtItems) {
+ return new TunerChannel(0, Channel.TYPE_FILE, channel, pmtItems);
+ }
+
+ /**
+ * Create a TunerChannel object suitable for network tuners
+ * @param major Channel number major
+ * @param minor Channel number minor
+ * @param programNumber Program number
+ * @param shortName Short name
+ * @param recordingProhibited Recording prohibition info
+ * @param videoFormat Video format. Should be {@code null} or one of the followings:
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_240P},
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_360P},
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_480I},
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_480P},
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_576I},
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_576P},
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_720P},
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_1080I},
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_1080P},
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_2160P},
+ * {@link android.media.tv.TvContract.Channels#VIDEO_FORMAT_4320P}
+ * @return a TunerChannel object
+ */
+ public static TunerChannel forNetwork(int major, int minor, int programNumber,
+ String shortName, boolean recordingProhibited, String videoFormat) {
+ TunerChannel tunerChannel = new TunerChannel(
+ null, programNumber, Collections.EMPTY_LIST, Channel.TYPE_NETWORK);
+ tunerChannel.setVirtualMajor(major);
+ tunerChannel.setVirtualMinor(minor);
+ tunerChannel.setShortName(shortName);
+ // Set audio and video pids in order to work around the audio-only channel check.
+ tunerChannel.setAudioPids(new ArrayList<>(Arrays.asList(0)));
+ tunerChannel.selectAudioTrack(0);
+ tunerChannel.setVideoPid(0);
+ tunerChannel.setRecordingProhibited(recordingProhibited);
+ if (videoFormat != null) {
+ tunerChannel.setVideoFormat(videoFormat);
+ }
+ return tunerChannel;
+ }
+
public String getName() {
return (!mProto.shortName.isEmpty()) ? mProto.shortName : mProto.longName;
}
@@ -193,7 +277,7 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
return mProto.videoPid;
}
- public void setVideoPid(int videoPid) {
+ synchronized public void setVideoPid(int videoPid) {
mProto.videoPid = videoPid;
}
@@ -219,7 +303,7 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
return Ints.asList(mProto.audioPids);
}
- public void setAudioPids(List<Integer> audioPids) {
+ synchronized public void setAudioPids(List<Integer> audioPids) {
mProto.audioPids = Ints.toArray(audioPids);
}
@@ -227,7 +311,7 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
return Ints.asList(mProto.audioStreamTypes);
}
- public void setAudioStreamTypes(List<Integer> audioStreamTypes) {
+ synchronized public void setAudioStreamTypes(List<Integer> audioStreamTypes) {
mProto.audioStreamTypes = Ints.toArray(audioStreamTypes);
}
@@ -239,32 +323,32 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
return mProto.type;
}
- public void setFilepath(String filepath) {
- mProto.filepath = filepath;
+ synchronized public void setFilepath(String filepath) {
+ mProto.filepath = filepath == null ? "" : filepath;
}
public String getFilepath() {
return mProto.filepath;
}
- public void setVirtualMajor(int virtualMajor) {
+ synchronized public void setVirtualMajor(int virtualMajor) {
mProto.virtualMajor = virtualMajor;
}
- public void setVirtualMinor(int virtualMinor) {
+ synchronized public void setVirtualMinor(int virtualMinor) {
mProto.virtualMinor = virtualMinor;
}
- public void setShortName(String shortName) {
- mProto.shortName = shortName;
+ synchronized public void setShortName(String shortName) {
+ mProto.shortName = shortName == null ? "" : shortName;
}
- public void setFrequency(int frequency) {
+ synchronized public void setFrequency(int frequency) {
mProto.frequency = frequency;
}
- public void setModulation(String modulation) {
- mProto.modulation = modulation;
+ synchronized public void setModulation(String modulation) {
+ mProto.modulation = modulation == null ? "" : modulation;
}
public boolean hasVideo() {
@@ -279,13 +363,18 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
return mProto.channelId;
}
- public void setChannelId(long channelId) {
+ synchronized public void setChannelId(long channelId) {
mProto.channelId = channelId;
}
public String getDisplayNumber() {
- if (mProto.virtualMajor != 0 && mProto.virtualMinor != 0) {
- return String.format("%d-%d", mProto.virtualMajor, mProto.virtualMinor);
+ return getDisplayNumber(true);
+ }
+
+ public String getDisplayNumber(boolean ignoreZeroMinorNumber) {
+ if (mProto.virtualMajor != 0 && (mProto.virtualMinor != 0 || !ignoreZeroMinorNumber)) {
+ return String.format("%d%c%d", mProto.virtualMajor, CHANNEL_NUMBER_SEPARATOR,
+ mProto.virtualMinor);
} else if (mProto.virtualMajor != 0) {
return Integer.toString(mProto.virtualMajor);
} else {
@@ -298,7 +387,7 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
}
@Override
- public void setHasCaptionTrack() {
+ synchronized public void setHasCaptionTrack() {
mProto.hasCaptionTrack = true;
}
@@ -312,7 +401,7 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
return Collections.unmodifiableList(Arrays.asList(mProto.audioTracks));
}
- public void setAudioTracks(List<AtscAudioTrack> audioTracks) {
+ synchronized public void setAudioTracks(List<AtscAudioTrack> audioTracks) {
mProto.audioTracks = audioTracks.toArray(new AtscAudioTrack[audioTracks.size()]);
}
@@ -321,11 +410,11 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
return Collections.unmodifiableList(Arrays.asList(mProto.captionTracks));
}
- public void setCaptionTracks(List<AtscCaptionTrack> captionTracks) {
+ synchronized public void setCaptionTracks(List<AtscCaptionTrack> captionTracks) {
mProto.captionTracks = captionTracks.toArray(new AtscCaptionTrack[captionTracks.size()]);
}
- public void selectAudioTrack(int index) {
+ synchronized public void selectAudioTrack(int index) {
if (0 <= index && index < mProto.audioPids.length) {
mProto.audioTrackIndex = index;
} else {
@@ -333,6 +422,22 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
}
}
+ synchronized public void setRecordingProhibited(boolean recordingProhibited) {
+ mProto.recordingProhibited = recordingProhibited;
+ }
+
+ public boolean isRecordingProhibited() {
+ return mProto.recordingProhibited;
+ }
+
+ synchronized public void setVideoFormat(String videoFormat) {
+ mProto.videoFormat = videoFormat == null ? "" : videoFormat;
+ }
+
+ public String getVideoFormat() {
+ return mProto.videoFormat;
+ }
+
@Override
public String toString() {
switch (mProto.type) {
@@ -359,7 +464,10 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
if (ret != 0) {
return ret;
}
-
+ ret = StringUtils.compare(getName(), channel.getName());
+ if (ret != 0) {
+ return ret;
+ }
// For FileTsStreamer, file paths should be compared.
return StringUtils.compare(getFilepath(), channel.getFilepath());
}
@@ -374,12 +482,19 @@ public class TunerChannel implements Comparable<TunerChannel>, PsipData.TvTracks
@Override
public int hashCode() {
- return Objects.hash(getFrequency(), getProgramNumber(), getFilepath());
+ return Objects.hash(getFrequency(), getProgramNumber(), getName(), getFilepath());
}
// Serialization
- public byte[] toByteArray() {
- return MessageNano.toByteArray(mProto);
+ synchronized public byte[] toByteArray() {
+ try {
+ return MessageNano.toByteArray(mProto);
+ } catch (Exception e) {
+ // Retry toByteArray. b/34197766
+ Log.w(TAG, "TunerChannel or its variables are modified in multiple thread without lock",
+ e);
+ return MessageNano.toByteArray(mProto);
+ }
}
public static TunerChannel parseFrom(byte[] data) {
diff --git a/src/com/android/tv/tuner/exoplayer/Cea708TextTrackRenderer.java b/src/com/android/tv/tuner/exoplayer/Cea708TextTrackRenderer.java
index 5e839223..5f536708 100644
--- a/src/com/android/tv/tuner/exoplayer/Cea708TextTrackRenderer.java
+++ b/src/com/android/tv/tuner/exoplayer/Cea708TextTrackRenderer.java
@@ -40,6 +40,7 @@ public class Cea708TextTrackRenderer extends TrackRenderer implements
private static final boolean DEBUG = false;
public static final int MSG_SERVICE_NUMBER = 1;
+ public static final int MSG_ENABLE_CLOSED_CAPTION = 2;
// According to CEA-708B, the maximum value of closed caption bandwidth is 9600bps.
private static final int DEFAULT_INPUT_BUFFER_SIZE = 9600 / 8;
@@ -52,11 +53,13 @@ public class Cea708TextTrackRenderer extends TrackRenderer implements
private long mCurrentPositionUs;
private long mPresentationTimeUs;
private int mTrackIndex;
+ private boolean mRenderingDisabled;
private Cea708Parser mCea708Parser;
private CcListener mCcListener;
public interface CcListener {
void emitEvent(CaptionEvent captionEvent);
+ void clearCaption();
void discoverServiceNumber(int serviceNumber);
}
@@ -204,7 +207,7 @@ public class Cea708TextTrackRenderer extends TrackRenderer implements
}
case SampleSource.SAMPLE_READ: {
mSampleHolder.data.flip();
- if (mCea708Parser != null) {
+ if (mCea708Parser != null && !mRenderingDisabled) {
mCea708Parser.parseClosedCaption(mSampleHolder.data, mSampleHolder.timeUs);
}
return true;
@@ -274,10 +277,26 @@ public class Cea708TextTrackRenderer extends TrackRenderer implements
@Override
public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
- if (messageType == MSG_SERVICE_NUMBER) {
- setServiceNumber((int) message);
- } else {
- super.handleMessage(messageType, message);
+ switch (messageType) {
+ case MSG_SERVICE_NUMBER:
+ setServiceNumber((int) message);
+ break;
+ case MSG_ENABLE_CLOSED_CAPTION:
+ boolean renderingDisabled = (Boolean) message == false;
+ if (mRenderingDisabled != renderingDisabled) {
+ mRenderingDisabled = renderingDisabled;
+ if (mRenderingDisabled) {
+ if (mCea708Parser != null) {
+ mCea708Parser.clear();
+ }
+ if (mCcListener != null) {
+ mCcListener.clearCaption();
+ }
+ }
+ }
+ break;
+ default:
+ super.handleMessage(messageType, message);
}
}
}
diff --git a/src/com/android/tv/tuner/exoplayer/ExoPlayerExtractorsFactory.java b/src/com/android/tv/tuner/exoplayer/ExoPlayerExtractorsFactory.java
new file mode 100644
index 00000000..0ab6d8c4
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/ExoPlayerExtractorsFactory.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 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.tv.tuner.exoplayer;
+
+import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
+import com.google.android.exoplayer2.extractor.Extractor;
+import com.google.android.exoplayer2.extractor.ExtractorsFactory;
+import com.google.android.exoplayer2.extractor.TimestampAdjuster;
+import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory;
+import com.google.android.exoplayer2.extractor.ts.TsExtractor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Extractor factory, mainly aim at create TsExtractor with FLAG_ALLOW_NON_IDR_KEYFRAMES flags for
+ * H.264 stream
+ */
+public final class ExoPlayerExtractorsFactory implements ExtractorsFactory {
+ @Override
+ public Extractor[] createExtractors() {
+ // Only create TsExtractor since we only target MPEG2TS stream.
+ Extractor[] extractors = {
+ new TsExtractor(new TimestampAdjuster(0), new DefaultTsPayloadReaderFactory(
+ DefaultTsPayloadReaderFactory.FLAG_ALLOW_NON_IDR_KEYFRAMES), false) };
+ return extractors;
+ }
+}
diff --git a/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java b/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java
index c105e222..0b648400 100644
--- a/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java
+++ b/src/com/android/tv/tuner/exoplayer/ExoPlayerSampleExtractor.java
@@ -23,17 +23,28 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
+import android.util.Pair;
-import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.MediaFormatHolder;
import com.google.android.exoplayer.SampleHolder;
-import com.google.android.exoplayer.SampleSource;
-import com.google.android.exoplayer.extractor.ExtractorSampleSource;
-import com.google.android.exoplayer.extractor.ExtractorSampleSource.EventListener;
-import com.google.android.exoplayer.upstream.Allocator;
import com.google.android.exoplayer.upstream.DataSource;
-import com.google.android.exoplayer.upstream.DefaultAllocator;
+import com.google.android.exoplayer2.C;
+import com.google.android.exoplayer2.Format;
+import com.google.android.exoplayer2.FormatHolder;
+import com.google.android.exoplayer2.Timeline;
+import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
+import com.google.android.exoplayer2.source.ExtractorMediaSource;
+import com.google.android.exoplayer2.source.ExtractorMediaSource.EventListener;
+import com.google.android.exoplayer2.source.MediaPeriod;
+import com.google.android.exoplayer2.source.MediaSource;
+import com.google.android.exoplayer2.source.SampleStream;
+import com.google.android.exoplayer2.source.TrackGroupArray;
+import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
+import com.google.android.exoplayer2.trackselection.TrackSelection;
+import com.google.android.exoplayer2.upstream.DataSpec;
+import com.google.android.exoplayer2.upstream.DefaultAllocator;
+import com.android.tv.tuner.exoplayer.audio.MpegTsDefaultAudioTrackRenderer;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
import com.android.tv.tuner.exoplayer.buffer.RecordingSampleBuffer;
import com.android.tv.tuner.exoplayer.buffer.SimpleSampleBuffer;
@@ -42,10 +53,11 @@ import com.android.tv.tuner.tvinput.PlaybackBufferListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
/**
* A class that extracts samples from a live broadcast stream while storing the sample on the disk.
@@ -54,11 +66,7 @@ import java.util.concurrent.atomic.AtomicLong;
public class ExoPlayerSampleExtractor implements SampleExtractor {
private static final String TAG = "ExoPlayerSampleExtracto";
- // Buffer segment size for memory allocator. Copied from demo implementation of ExoPlayer.
- private static final int BUFFER_SEGMENT_SIZE_IN_BYTES = 64 * 1024;
- // Buffer segment count for sample source. Copied from demo implementation of ExoPlayer.
- private static final int BUFFER_SEGMENT_COUNT = 256;
-
+ private static final int INVALID_TRACK_INDEX = -1;
private final HandlerThread mSourceReaderThread;
private final long mId;
@@ -70,36 +78,69 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
private AtomicBoolean mOnCompletionCalled = new AtomicBoolean();
private IOException mExceptionOnPrepare;
private List<MediaFormat> mTrackFormats;
+ private int mVideoTrackIndex = INVALID_TRACK_INDEX;
+ private boolean mVideoTrackMet;
+ private long mBaseSamplePts = Long.MIN_VALUE;
private HashMap<Integer, Long> mLastExtractedPositionUsMap = new HashMap<>();
+ private final List<Pair<Integer, SampleHolder>> mPendingSamples = new LinkedList<>();
private OnCompletionListener mOnCompletionListener;
private Handler mOnCompletionListenerHandler;
private IOException mError;
- public ExoPlayerSampleExtractor(Uri uri, DataSource source, BufferManager bufferManager,
+ public ExoPlayerSampleExtractor(Uri uri, final DataSource source, BufferManager bufferManager,
PlaybackBufferListener bufferListener, boolean isRecording) {
// It'll be used as a timeshift file chunk name's prefix.
mId = System.currentTimeMillis();
- Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE_IN_BYTES);
EventListener eventListener = new EventListener() {
-
@Override
- public void onLoadError(int sourceId, IOException e) {
- mError = e;
+ public void onLoadError(IOException error) {
+ mError = error;
}
};
mSourceReaderThread = new HandlerThread("SourceReaderThread");
- mSourceReaderWorker = new SourceReaderWorker(new ExtractorSampleSource(uri, source,
- allocator, BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE_IN_BYTES,
+ mSourceReaderWorker = new SourceReaderWorker(new ExtractorMediaSource(uri,
+ new com.google.android.exoplayer2.upstream.DataSource.Factory() {
+ @Override
+ public com.google.android.exoplayer2.upstream.DataSource createDataSource() {
+ // Returns an adapter implementation for ExoPlayer V2 DataSource interface.
+ return new com.google.android.exoplayer2.upstream.DataSource() {
+ @Override
+ public long open(DataSpec dataSpec) throws IOException {
+ return source.open(
+ new com.google.android.exoplayer.upstream.DataSpec(
+ dataSpec.uri, dataSpec.postBody,
+ dataSpec.absoluteStreamPosition, dataSpec.position,
+ dataSpec.length, dataSpec.key, dataSpec.flags));
+ }
+
+ @Override
+ public int read(byte[] buffer, int offset, int readLength)
+ throws IOException {
+ return source.read(buffer, offset, readLength);
+ }
+
+ @Override
+ public Uri getUri() {
+ return null;
+ }
+
+ @Override
+ public void close() throws IOException {
+ source.close();
+ }
+ };
+ }
+ },
+ new ExoPlayerExtractorsFactory(),
// Do not create a handler if we not on a looper. e.g. test.
- Looper.myLooper() != null ? new Handler() : null,
- eventListener, 0));
+ Looper.myLooper() != null ? new Handler() : null, eventListener));
if (isRecording) {
mSampleBuffer = new RecordingSampleBuffer(bufferManager, bufferListener, false,
RecordingSampleBuffer.BUFFER_REASON_RECORDING);
} else {
- if (bufferManager == null || bufferManager.isDisabled()) {
+ if (bufferManager == null) {
mSampleBuffer = new SimpleSampleBuffer(bufferListener);
} else {
mSampleBuffer = new RecordingSampleBuffer(bufferManager, bufferListener, true,
@@ -114,43 +155,141 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
mOnCompletionListenerHandler = handler;
}
- private class SourceReaderWorker implements Handler.Callback {
+ private class SourceReaderWorker implements Handler.Callback, MediaPeriod.Callback {
public static final int MSG_PREPARE = 1;
public static final int MSG_FETCH_SAMPLES = 2;
public static final int MSG_RELEASE = 3;
private static final int RETRY_INTERVAL_MS = 50;
- private final SampleSource mSampleSource;
- private SampleSource.SampleSourceReader mSampleSourceReader;
+ private final MediaSource mSampleSource;
+ private MediaPeriod mMediaPeriod;
+ private SampleStream[] mStreams;
private boolean[] mTrackMetEos;
private boolean mMetEos = false;
private long mCurrentPosition;
+ private DecoderInputBuffer mDecoderInputBuffer;
+ private SampleHolder mSampleHolder;
+ private boolean mPrepareRequested;
- public SourceReaderWorker(SampleSource sampleSource) {
+ public SourceReaderWorker(MediaSource sampleSource) {
mSampleSource = sampleSource;
+ mSampleSource.prepareSource(null, false, new MediaSource.Listener() {
+ @Override
+ public void onSourceInfoRefreshed(Timeline timeline, Object manifest) {
+ // Dynamic stream change is not supported yet. b/28169263
+ // For now, this will cause EOS and playback reset.
+ }
+ });
+ mDecoderInputBuffer = new DecoderInputBuffer(
+ DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
+ mSampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL);
+ }
+
+ MediaFormat convertFormat(Format format) {
+ if (format.sampleMimeType.startsWith("audio/")) {
+ return MediaFormat.createAudioFormat(format.id, format.sampleMimeType,
+ format.bitrate, format.maxInputSize,
+ com.google.android.exoplayer.C.UNKNOWN_TIME_US, format.channelCount,
+ format.sampleRate, format.initializationData, format.language,
+ format.pcmEncoding);
+ } else if (format.sampleMimeType.startsWith("video/")) {
+ return MediaFormat.createVideoFormat(
+ format.id, format.sampleMimeType, format.bitrate, format.maxInputSize,
+ com.google.android.exoplayer.C.UNKNOWN_TIME_US, format.width, format.height,
+ format.initializationData, format.rotationDegrees,
+ format.pixelWidthHeightRatio, format.projectionData, format.stereoMode);
+ } else if (format.sampleMimeType.endsWith("/cea-608")
+ || format.sampleMimeType.startsWith("text/")) {
+ return MediaFormat.createTextFormat(
+ format.id, format.sampleMimeType, format.bitrate,
+ com.google.android.exoplayer.C.UNKNOWN_TIME_US, format.language);
+ } else {
+ return MediaFormat.createFormatForMimeType(
+ format.id, format.sampleMimeType, format.bitrate,
+ com.google.android.exoplayer.C.UNKNOWN_TIME_US);
+ }
+ }
+
+ @Override
+ public void onPrepared(MediaPeriod mediaPeriod) {
+ if (mMediaPeriod == null) {
+ // This instance is already released while the extractor is preparing.
+ return;
+ }
+ TrackSelection.Factory selectionFactory = new FixedTrackSelection.Factory();
+ TrackGroupArray trackGroupArray = mMediaPeriod.getTrackGroups();
+ TrackSelection[] selections = new TrackSelection[trackGroupArray.length];
+ for (int i = 0; i < selections.length; ++i) {
+ selections[i] = selectionFactory.createTrackSelection(trackGroupArray.get(i), 0);
+ }
+ boolean retain[] = new boolean[trackGroupArray.length];
+ boolean reset[] = new boolean[trackGroupArray.length];
+ mStreams = new SampleStream[trackGroupArray.length];
+ mMediaPeriod.selectTracks(selections, retain, mStreams, reset, 0);
+ if (mTrackFormats == null) {
+ int trackCount = trackGroupArray.length;
+ mTrackMetEos = new boolean[trackCount];
+ List<MediaFormat> trackFormats = new ArrayList<>();
+ int videoTrackCount = 0;
+ for (int i = 0; i < trackCount; i++) {
+ Format format = trackGroupArray.get(i).getFormat(0);
+ if (format.sampleMimeType.startsWith("video/")) {
+ videoTrackCount++;
+ mVideoTrackIndex = i;
+ }
+ trackFormats.add(convertFormat(format));
+ }
+ if (videoTrackCount > 1) {
+ // Disable dropping samples when there are multiple video tracks.
+ mVideoTrackIndex = INVALID_TRACK_INDEX;
+ }
+ mTrackFormats = trackFormats;
+ List<String> ids = new ArrayList<>();
+ for (int i = 0; i < mTrackFormats.size(); i++) {
+ ids.add(String.format(Locale.ENGLISH, "%s_%x", Long.toHexString(mId), i));
+ }
+ try {
+ mSampleBuffer.init(ids, mTrackFormats);
+ } catch (IOException e) {
+ // In this case, we will not schedule any further operation.
+ // mExceptionOnPrepare will be notified to ExoPlayer, and ExoPlayer will
+ // call release() eventually.
+ mExceptionOnPrepare = e;
+ return;
+ }
+ mSourceReaderHandler.sendEmptyMessage(MSG_FETCH_SAMPLES);
+ mPrepared = true;
+ }
+ }
+
+ @Override
+ public void onContinueLoadingRequested(MediaPeriod source) {
+ source.continueLoading(mCurrentPosition);
}
@Override
public boolean handleMessage(Message message) {
switch (message.what) {
case MSG_PREPARE:
- mPrepared = prepare();
- if (!mPrepared && mExceptionOnPrepare == null) {
- mSourceReaderHandler
- .sendEmptyMessageDelayed(MSG_PREPARE, RETRY_INTERVAL_MS);
- } else{
- mSourceReaderHandler.sendEmptyMessage(MSG_FETCH_SAMPLES);
+ if (!mPrepareRequested) {
+ mPrepareRequested = true;
+ mMediaPeriod = mSampleSource.createPeriod(0,
+ new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE), 0);
+ mMediaPeriod.prepare(this);
+ try {
+ mMediaPeriod.maybeThrowPrepareError();
+ } catch (IOException e) {
+ mError = e;
+ }
}
return true;
case MSG_FETCH_SAMPLES:
boolean didSomething = false;
- SampleHolder sample = new SampleHolder(
- SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL);
ConditionVariable conditionVariable = new ConditionVariable();
- int trackCount = mSampleSourceReader.getTrackCount();
+ int trackCount = mStreams.length;
for (int i = 0; i < trackCount; ++i) {
- if (!mTrackMetEos[i] && SampleSource.NOTHING_READ
- != fetchSample(i, sample, conditionVariable)) {
+ if (!mTrackMetEos[i] && C.RESULT_NOTHING_READ
+ != fetchSample(i, mSampleHolder, conditionVariable)) {
if (mMetEos) {
// If mMetEos was on during fetchSample() due to an error,
// fetching from other tracks is not necessary.
@@ -159,6 +298,7 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
didSomething = true;
}
}
+ mMediaPeriod.continueLoading(mCurrentPosition);
if (!mMetEos) {
if (didSomething) {
mSourceReaderHandler.sendEmptyMessage(MSG_FETCH_SAMPLES);
@@ -171,17 +311,10 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
}
return true;
case MSG_RELEASE:
- if (mSampleSourceReader != null) {
- if (mPrepared) {
- // ExtractorSampleSource expects all the tracks should be disabled
- // before releasing.
- int count = mSampleSourceReader.getTrackCount();
- for (int i = 0; i < count; ++i) {
- mSampleSourceReader.disable(i);
- }
- }
- mSampleSourceReader.release();
- mSampleSourceReader = null;
+ if (mMediaPeriod != null) {
+ mSampleSource.releasePeriod(mMediaPeriod);
+ mSampleSource.releaseSource();
+ mMediaPeriod = null;
}
cleanUp();
mSourceReaderHandler.removeCallbacksAndMessages(null);
@@ -190,91 +323,110 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
return false;
}
- private boolean prepare() {
- if (mSampleSourceReader == null) {
- mSampleSourceReader = mSampleSource.register();
- }
- if(!mSampleSourceReader.prepare(0)) {
- return false;
- }
- if (mTrackFormats == null) {
- int trackCount = mSampleSourceReader.getTrackCount();
- mTrackMetEos = new boolean[trackCount];
- List<MediaFormat> trackFormats = new ArrayList<>();
- for (int i = 0; i < trackCount; i++) {
- trackFormats.add(mSampleSourceReader.getFormat(i));
- mSampleSourceReader.enable(i, 0);
-
- }
- mTrackFormats = trackFormats;
- List<String> ids = new ArrayList<>();
- for (int i = 0; i < mTrackFormats.size(); i++) {
- ids.add(String.format(Locale.ENGLISH, "%s_%x", Long.toHexString(mId), i));
- }
- try {
- mSampleBuffer.init(ids, mTrackFormats);
- } catch (IOException e) {
- // In this case, we will not schedule any further operation.
- // mExceptionOnPrepare will be notified to ExoPlayer, and ExoPlayer will
- // call release() eventually.
- mExceptionOnPrepare = e;
- return false;
- }
- }
- return true;
- }
-
private int fetchSample(int track, SampleHolder sample,
ConditionVariable conditionVariable) {
- mSampleSourceReader.continueBuffering(track, mCurrentPosition);
-
- MediaFormatHolder formatHolder = new MediaFormatHolder();
- sample.clearData();
- int ret = mSampleSourceReader.readData(track, mCurrentPosition, formatHolder, sample);
- if (ret == SampleSource.SAMPLE_READ) {
- if (mCurrentPosition < sample.timeUs) {
- mCurrentPosition = sample.timeUs;
+ FormatHolder dummyFormatHolder = new FormatHolder();
+ mDecoderInputBuffer.clear();
+ int ret = mStreams[track].readData(dummyFormatHolder, mDecoderInputBuffer);
+ if (ret == C.RESULT_BUFFER_READ
+ // Double-check if the extractor provided the data to prevent NPE. b/33758354
+ && mDecoderInputBuffer.data != null) {
+ if (mCurrentPosition < mDecoderInputBuffer.timeUs) {
+ mCurrentPosition = mDecoderInputBuffer.timeUs;
}
try {
Long lastExtractedPositionUs = mLastExtractedPositionUsMap.get(track);
if (lastExtractedPositionUs == null) {
- mLastExtractedPositionUsMap.put(track, sample.timeUs);
+ mLastExtractedPositionUsMap.put(track, mDecoderInputBuffer.timeUs);
} else {
mLastExtractedPositionUsMap.put(track,
- Math.max(lastExtractedPositionUs, sample.timeUs));
+ Math.max(lastExtractedPositionUs, mDecoderInputBuffer.timeUs));
}
- queueSample(track, sample, conditionVariable);
+ queueSample(track, conditionVariable);
} catch (IOException e) {
mLastExtractedPositionUsMap.clear();
mMetEos = true;
mSampleBuffer.setEos();
}
- } else if (ret == SampleSource.END_OF_STREAM) {
+ } else if (ret == C.RESULT_END_OF_INPUT) {
mTrackMetEos[track] = true;
for (int i = 0; i < mTrackMetEos.length; ++i) {
if (!mTrackMetEos[i]) {
break;
}
- if (i == mTrackMetEos.length -1) {
+ if (i == mTrackMetEos.length - 1) {
mMetEos = true;
mSampleBuffer.setEos();
}
}
}
- // TODO: Handle SampleSource.FORMAT_READ for dynamic resolution change. b/28169263
+ // TODO: Handle C.RESULT_FORMAT_READ for dynamic resolution change. b/28169263
return ret;
}
- }
-
- private void queueSample(int index, SampleHolder sample, ConditionVariable conditionVariable)
- throws IOException {
- long writeStartTimeNs = SystemClock.elapsedRealtimeNanos();
- mSampleBuffer.writeSample(index, sample, conditionVariable);
- // Checks whether the storage has enough bandwidth for recording samples.
- if (mSampleBuffer.isWriteSpeedSlow(sample.size,
- SystemClock.elapsedRealtimeNanos() - writeStartTimeNs)) {
- mSampleBuffer.handleWriteSpeedSlow();
+ private void queueSample(int index, ConditionVariable conditionVariable)
+ throws IOException {
+ if (mVideoTrackIndex != INVALID_TRACK_INDEX) {
+ if (!mVideoTrackMet) {
+ if (index != mVideoTrackIndex) {
+ SampleHolder sample =
+ new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL);
+ mSampleHolder.flags =
+ (mDecoderInputBuffer.isKeyFrame()
+ ? com.google.android.exoplayer.C.SAMPLE_FLAG_SYNC : 0)
+ | (mDecoderInputBuffer.isDecodeOnly()
+ ? com.google.android.exoplayer.C.SAMPLE_FLAG_DECODE_ONLY
+ : 0);
+ sample.timeUs = mDecoderInputBuffer.timeUs;
+ sample.size = mDecoderInputBuffer.data.position();
+ sample.ensureSpaceForWrite(sample.size);
+ mDecoderInputBuffer.flip();
+ sample.data.position(0);
+ sample.data.put(mDecoderInputBuffer.data);
+ sample.data.flip();
+ mPendingSamples.add(new Pair<>(index, sample));
+ return;
+ }
+ mVideoTrackMet = true;
+ mBaseSamplePts =
+ mDecoderInputBuffer.timeUs
+ - MpegTsDefaultAudioTrackRenderer
+ .INITIAL_AUDIO_BUFFERING_TIME_US;
+ for (Pair<Integer, SampleHolder> pair : mPendingSamples) {
+ if (pair.second.timeUs >= mBaseSamplePts) {
+ mSampleBuffer.writeSample(pair.first, pair.second, conditionVariable);
+ }
+ }
+ mPendingSamples.clear();
+ } else {
+ if (mDecoderInputBuffer.timeUs < mBaseSamplePts
+ && mVideoTrackIndex != index) {
+ return;
+ }
+ }
+ }
+ // Copy the decoder input to the sample holder.
+ mSampleHolder.clearData();
+ mSampleHolder.flags =
+ (mDecoderInputBuffer.isKeyFrame()
+ ? com.google.android.exoplayer.C.SAMPLE_FLAG_SYNC : 0)
+ | (mDecoderInputBuffer.isDecodeOnly()
+ ? com.google.android.exoplayer.C.SAMPLE_FLAG_DECODE_ONLY : 0);
+ mSampleHolder.timeUs = mDecoderInputBuffer.timeUs;
+ mSampleHolder.size = mDecoderInputBuffer.data.position();
+ mSampleHolder.ensureSpaceForWrite(mSampleHolder.size);
+ mDecoderInputBuffer.flip();
+ mSampleHolder.data.position(0);
+ mSampleHolder.data.put(mDecoderInputBuffer.data);
+ mSampleHolder.data.flip();
+ long writeStartTimeNs = SystemClock.elapsedRealtimeNanos();
+ mSampleBuffer.writeSample(index, mSampleHolder, conditionVariable);
+
+ // Checks whether the storage has enough bandwidth for recording samples.
+ if (mSampleBuffer.isWriteSpeedSlow(mSampleHolder.size,
+ SystemClock.elapsedRealtimeNanos() - writeStartTimeNs)) {
+ mSampleBuffer.handleWriteSpeedSlow();
+ }
}
}
@@ -328,7 +480,7 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
}
@Override
- public boolean continueBuffering(long positionUs) {
+ public boolean continueBuffering(long positionUs) {
return mSampleBuffer.continueBuffering(positionUs);
}
@@ -386,12 +538,14 @@ public class ExoPlayerSampleExtractor implements SampleExtractor {
}
private long getLastExtractedPositionUs() {
- long lastExtractedPositionUs = Long.MAX_VALUE;
- for (long value : mLastExtractedPositionUsMap.values()) {
- lastExtractedPositionUs = Math.min(lastExtractedPositionUs, value);
+ long lastExtractedPositionUs = Long.MIN_VALUE;
+ for (Map.Entry<Integer, Long> entry : mLastExtractedPositionUsMap.entrySet()) {
+ if (mVideoTrackIndex != entry.getKey()) {
+ lastExtractedPositionUs = Math.max(lastExtractedPositionUs, entry.getValue());
+ }
}
- if (lastExtractedPositionUs == Long.MAX_VALUE) {
- lastExtractedPositionUs = C.UNKNOWN_TIME_US;
+ if (lastExtractedPositionUs == Long.MIN_VALUE) {
+ lastExtractedPositionUs = com.google.android.exoplayer.C.UNKNOWN_TIME_US;
}
return lastExtractedPositionUs;
}
diff --git a/src/com/android/tv/tuner/exoplayer/FileSampleExtractor.java b/src/com/android/tv/tuner/exoplayer/FileSampleExtractor.java
index ec7b4b16..b7e42a7c 100644
--- a/src/com/android/tv/tuner/exoplayer/FileSampleExtractor.java
+++ b/src/com/android/tv/tuner/exoplayer/FileSampleExtractor.java
@@ -25,7 +25,6 @@ import com.android.tv.tuner.exoplayer.buffer.RecordingSampleBuffer;
import com.android.tv.tuner.tvinput.PlaybackBufferListener;
import android.os.Handler;
-import android.util.Pair;
import java.io.IOException;
import java.util.ArrayList;
@@ -61,18 +60,17 @@ public class FileSampleExtractor implements SampleExtractor{
@Override
public boolean prepare() throws IOException {
- ArrayList<Pair<String, android.media.MediaFormat>> trackInfos =
- mBufferManager.readTrackInfoFiles();
- if (trackInfos == null || trackInfos.isEmpty()) {
+ List<BufferManager.TrackFormat> trackFormatList = mBufferManager.readTrackInfoFiles();
+ if (trackFormatList == null || trackFormatList.isEmpty()) {
throw new IOException("Cannot find meta files for the recording.");
}
- mTrackCount = trackInfos.size();
+ mTrackCount = trackFormatList.size();
List<String> ids = new ArrayList<>();
mTrackFormats.clear();
for (int i = 0; i < mTrackCount; ++i) {
- Pair<String, android.media.MediaFormat> pair = trackInfos.get(i);
- ids.add(pair.first);
- mTrackFormats.add(MediaFormatUtil.createMediaFormat(pair.second));
+ BufferManager.TrackFormat trackFormat = trackFormatList.get(i);
+ ids.add(trackFormat.trackId);
+ mTrackFormats.add(MediaFormatUtil.createMediaFormat(trackFormat.format));
}
mSampleBuffer = new RecordingSampleBuffer(mBufferManager, mBufferListener, true,
RecordingSampleBuffer.BUFFER_REASON_RECORDED_PLAYBACK);
diff --git a/src/com/android/tv/tuner/exoplayer/MpegTsPlayer.java b/src/com/android/tv/tuner/exoplayer/MpegTsPlayer.java
index 381b22e9..2694298a 100644
--- a/src/com/android/tv/tuner/exoplayer/MpegTsPlayer.java
+++ b/src/com/android/tv/tuner/exoplayer/MpegTsPlayer.java
@@ -39,20 +39,22 @@ import com.android.tv.common.SoftPreconditions;
import com.android.tv.tuner.data.Cea708Data;
import com.android.tv.tuner.data.Cea708Data.CaptionEvent;
import com.android.tv.tuner.data.TunerChannel;
-import com.android.tv.tuner.exoplayer.ac3.Ac3PassthroughTrackRenderer;
-import com.android.tv.tuner.exoplayer.ac3.Ac3TrackRenderer;
+import com.android.tv.tuner.exoplayer.audio.MpegTsDefaultAudioTrackRenderer;
+import com.android.tv.tuner.exoplayer.audio.MpegTsMediaCodecAudioTrackRenderer;
import com.android.tv.tuner.source.TsDataSource;
import com.android.tv.tuner.source.TsDataSourceManager;
import com.android.tv.tuner.tvinput.EventDetector;
+import com.android.tv.tuner.tvinput.TunerDebug;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-/**
- * MPEG-2 TS stream player implementation using ExoPlayer.
- */
-public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRenderer.EventListener,
- Ac3PassthroughTrackRenderer.EventListener, Ac3TrackRenderer.Ac3EventListener {
+/** MPEG-2 TS stream player implementation using ExoPlayer. */
+public class MpegTsPlayer
+ implements ExoPlayer.Listener,
+ MediaCodecVideoTrackRenderer.EventListener,
+ MpegTsDefaultAudioTrackRenderer.EventListener,
+ MpegTsMediaCodecAudioTrackRenderer.Ac3EventListener {
private int mCaptionServiceNumber = Cea708Data.EMPTY_SERVICE_NUMBER;
/**
@@ -60,7 +62,7 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
*/
public interface RendererBuilder {
void buildRenderers(MpegTsPlayer mpegTsPlayer, DataSource dataSource,
- RendererBuilderCallback callback);
+ boolean hasSoftwareAudioDecoder, RendererBuilderCallback callback);
}
/**
@@ -94,6 +96,11 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
void onEmitCaptionEvent(CaptionEvent event);
/**
+ * Notifies clearing up whole closed caption event.
+ */
+ void onClearCaptionEvent();
+
+ /**
* Notifies the discovered caption service number.
*/
void onDiscoverCaptionServiceNumber(int serviceNumber);
@@ -215,10 +222,11 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
* Creates renderers and {@link DataSource} and initializes player.
* @param context a {@link Context} instance
* @param channel to play
+ * @param hasSoftwareAudioDecoder {@code true} if there is connected software decoder
* @param eventListener for program information which will be scanned from MPEG2-TS stream
* @return true when everything is created and initialized well, false otherwise
*/
- public boolean prepare(Context context, TunerChannel channel,
+ public boolean prepare(Context context, TunerChannel channel, boolean hasSoftwareAudioDecoder,
EventDetector.EventListener eventListener) {
TsDataSource source = null;
if (channel != null) {
@@ -236,7 +244,7 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
}
mRendererBuildingState = RENDERER_BUILDING_STATE_BUILDING;
mBuilderCallback = new InternalRendererBuilderCallback();
- mRendererBuilder.buildRenderers(this, source, mBuilderCallback);
+ mRendererBuilder.buildRenderers(this, source, hasSoftwareAudioDecoder, mBuilderCallback);
return true;
}
@@ -304,8 +312,10 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
SoftPreconditions.checkState(supportSmoothTrickPlay(playbackParams.getSpeed()));
mPlayer.setPlayWhenReady(true);
mTrickplayRunning = true;
- if (mAudioRenderer instanceof Ac3PassthroughTrackRenderer) {
- mPlayer.sendMessage(mAudioRenderer, Ac3PassthroughTrackRenderer.MSG_SET_PLAYBACK_SPEED,
+ if (mAudioRenderer instanceof MpegTsDefaultAudioTrackRenderer) {
+ mPlayer.sendMessage(
+ mAudioRenderer,
+ MpegTsDefaultAudioTrackRenderer.MSG_SET_PLAYBACK_SPEED,
playbackParams.getSpeed());
} else {
mPlayer.sendMessage(mAudioRenderer,
@@ -317,9 +327,9 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
private void stopSmoothTrickplay(boolean calledBySeek) {
if (mTrickplayRunning) {
mTrickplayRunning = false;
- if (mAudioRenderer instanceof Ac3PassthroughTrackRenderer) {
- mPlayer.sendMessage(mAudioRenderer,
- Ac3PassthroughTrackRenderer.MSG_SET_PLAYBACK_SPEED,
+ if (mAudioRenderer instanceof MpegTsDefaultAudioTrackRenderer) {
+ mPlayer.sendMessage(
+ mAudioRenderer, MpegTsDefaultAudioTrackRenderer.MSG_SET_PLAYBACK_SPEED,
1.0f);
} else {
mPlayer.sendMessage(mAudioRenderer,
@@ -423,8 +433,9 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
*/
public void setVolume(float volume) {
mVolume = volume;
- if (mAudioRenderer instanceof Ac3PassthroughTrackRenderer) {
- mPlayer.sendMessage(mAudioRenderer, Ac3PassthroughTrackRenderer.MSG_SET_VOLUME, volume);
+ if (mAudioRenderer instanceof MpegTsDefaultAudioTrackRenderer) {
+ mPlayer.sendMessage(mAudioRenderer, MpegTsDefaultAudioTrackRenderer.MSG_SET_VOLUME,
+ volume);
} else {
mPlayer.sendMessage(mAudioRenderer, MediaCodecAudioTrackRenderer.MSG_SET_VOLUME,
volume);
@@ -432,18 +443,20 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
}
/**
- * Enables or disables audio.
+ * Enables or disables audio and closed caption.
*
- * @param enable enables the audio when {@code true}, disables otherwise.
+ * @param enable enables the audio and closed caption when {@code true}, disables otherwise.
*/
- public void setAudioTrack(boolean enable) {
- if (mAudioRenderer instanceof Ac3PassthroughTrackRenderer) {
- mPlayer.sendMessage(mAudioRenderer, Ac3PassthroughTrackRenderer.MSG_SET_AUDIO_TRACK,
+ public void setAudioTrackAndClosedCaption(boolean enable) {
+ if (mAudioRenderer instanceof MpegTsDefaultAudioTrackRenderer) {
+ mPlayer.sendMessage(mAudioRenderer, MpegTsDefaultAudioTrackRenderer.MSG_SET_AUDIO_TRACK,
enable ? 1 : 0);
} else {
mPlayer.sendMessage(mAudioRenderer, MediaCodecAudioTrackRenderer.MSG_SET_VOLUME,
enable ? mVolume : 0.0f);
}
+ mPlayer.sendMessage(mTextRenderer, Cea708TextTrackRenderer.MSG_ENABLE_CLOSED_CAPTION,
+ enable);
}
/**
@@ -495,6 +508,28 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
}
/**
+ * Returns the index of the currently selected track for the specified renderer.
+ *
+ * @param rendererIndex The index of the renderer.
+ * @return The selected track. A negative value or a value greater than or equal to the renderer's
+ * track count indicates that the renderer is disabled.
+ */
+ public int getSelectedTrack(int rendererIndex) {
+ return mPlayer.getSelectedTrack(rendererIndex);
+ }
+
+ /**
+ * Returns the format of a track.
+ *
+ * @param rendererIndex The index of the renderer.
+ * @param trackIndex The index of the track.
+ * @return The format of the track.
+ */
+ public MediaFormat getTrackFormat(int rendererIndex, int trackIndex) {
+ return mPlayer.getTrackFormat(rendererIndex, trackIndex);
+ }
+
+ /**
* Gets the main handler of the player.
*/
/* package */ Handler getMainHandler() {
@@ -579,6 +614,7 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
@Override
public void onDroppedFrames(int count, long elapsed) {
+ TunerDebug.notifyVideoFrameDrop(count, elapsed);
if (mTrickplayRunning && mListener != null) {
mListener.onSmoothTrickplayForceStopped();
}
@@ -622,6 +658,13 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
}
@Override
+ public void clearCaption() {
+ if (mVideoEventListener != null) {
+ mVideoEventListener.onClearCaptionEvent();
+ }
+ }
+
+ @Override
public void discoverServiceNumber(int serviceNumber) {
if (mVideoEventListener != null) {
mVideoEventListener.onDiscoverCaptionServiceNumber(serviceNumber);
@@ -650,4 +693,4 @@ public class MpegTsPlayer implements ExoPlayer.Listener, MediaCodecVideoTrackRen
}
}
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/tuner/exoplayer/MpegTsRendererBuilder.java b/src/com/android/tv/tuner/exoplayer/MpegTsRendererBuilder.java
index 0e46c9cf..006ccac2 100644
--- a/src/com/android/tv/tuner/exoplayer/MpegTsRendererBuilder.java
+++ b/src/com/android/tv/tuner/exoplayer/MpegTsRendererBuilder.java
@@ -18,12 +18,14 @@ package com.android.tv.tuner.exoplayer;
import android.content.Context;
+import com.google.android.exoplayer.MediaCodecSelector;
import com.google.android.exoplayer.SampleSource;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.upstream.DataSource;
+import com.android.tv.Features;
import com.android.tv.tuner.exoplayer.MpegTsPlayer.RendererBuilder;
import com.android.tv.tuner.exoplayer.MpegTsPlayer.RendererBuilderCallback;
-import com.android.tv.tuner.exoplayer.ac3.Ac3PassthroughTrackRenderer;
+import com.android.tv.tuner.exoplayer.audio.MpegTsDefaultAudioTrackRenderer;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
import com.android.tv.tuner.tvinput.PlaybackBufferListener;
@@ -44,7 +46,7 @@ public class MpegTsRendererBuilder implements RendererBuilder {
@Override
public void buildRenderers(MpegTsPlayer mpegTsPlayer, DataSource dataSource,
- RendererBuilderCallback callback) {
+ boolean mHasSoftwareAudioDecoder, RendererBuilderCallback callback) {
// Build the video and audio renderers.
SampleExtractor extractor = dataSource == null ?
new MpegTsSampleExtractor(mBufferManager, mBufferListener) :
@@ -52,10 +54,16 @@ public class MpegTsRendererBuilder implements RendererBuilder {
SampleSource sampleSource = new MpegTsSampleSource(extractor);
MpegTsVideoTrackRenderer videoRenderer = new MpegTsVideoTrackRenderer(mContext,
sampleSource, mpegTsPlayer.getMainHandler(), mpegTsPlayer);
- // TODO: Only using Ac3PassthroughTrackRenderer for A/V sync issue. We will use
- // {@link Ac3TrackRenderer} when we use ExoPlayer's extractor.
- TrackRenderer audioRenderer = new Ac3PassthroughTrackRenderer(sampleSource,
- mpegTsPlayer.getMainHandler(), mpegTsPlayer);
+ // TODO: Only using MpegTsDefaultAudioTrackRenderer for A/V sync issue. We will use
+ // {@link MpegTsMediaCodecAudioTrackRenderer} when we use ExoPlayer's extractor.
+ TrackRenderer audioRenderer =
+ new MpegTsDefaultAudioTrackRenderer(
+ sampleSource,
+ MediaCodecSelector.DEFAULT,
+ mpegTsPlayer.getMainHandler(),
+ mpegTsPlayer,
+ mHasSoftwareAudioDecoder,
+ !Features.AC3_SOFTWARE_DECODE.isEnabled(mContext));
Cea708TextTrackRenderer textRenderer = new Cea708TextTrackRenderer(sampleSource);
TrackRenderer[] renderers = new TrackRenderer[MpegTsPlayer.RENDERER_COUNT];
diff --git a/src/com/android/tv/tuner/exoplayer/ac3/Ac3PassthroughTrackRenderer.java b/src/com/android/tv/tuner/exoplayer/ac3/Ac3PassthroughTrackRenderer.java
deleted file mode 100644
index 9dae2e34..00000000
--- a/src/com/android/tv/tuner/exoplayer/ac3/Ac3PassthroughTrackRenderer.java
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.tuner.exoplayer.ac3;
-
-import android.os.Handler;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.google.android.exoplayer.CodecCounters;
-import com.google.android.exoplayer.ExoPlaybackException;
-import com.google.android.exoplayer.MediaClock;
-import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
-import com.google.android.exoplayer.MediaFormat;
-import com.google.android.exoplayer.MediaFormatHolder;
-import com.google.android.exoplayer.MediaFormatUtil;
-import com.google.android.exoplayer.SampleHolder;
-import com.google.android.exoplayer.SampleSource;
-import com.google.android.exoplayer.TrackRenderer;
-import com.google.android.exoplayer.audio.AudioTrack;
-import com.google.android.exoplayer.util.Assertions;
-import com.google.android.exoplayer.util.MimeTypes;
-import com.android.tv.tuner.tvinput.TunerDebug;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-
-/**
- * Decodes and renders AC3 audio.
- */
-public class Ac3PassthroughTrackRenderer extends TrackRenderer implements MediaClock {
- public static final int MSG_SET_VOLUME = 10000;
- public static final int MSG_SET_AUDIO_TRACK = MSG_SET_VOLUME + 1;
- public static final int MSG_SET_PLAYBACK_SPEED = MSG_SET_VOLUME + 2;
-
- // ATSC/53 allows sample rate to be only 48Khz.
- // One AC3 sample has 1536 frames, and its duration is 32ms.
- public static final long AC3_SAMPLE_DURATION_US = 32000;
-
- private static final String TAG = "Ac3PassthroughTrackRenderer";
- private static final boolean DEBUG = false;
-
- /**
- * Interface definition for a callback to be notified of
- * {@link com.google.android.exoplayer.audio.AudioTrack} error.
- */
- public interface EventListener {
- void onAudioTrackInitializationError(AudioTrack.InitializationException e);
- void onAudioTrackWriteError(AudioTrack.WriteException e);
- }
-
- private static final int DEFAULT_INPUT_BUFFER_SIZE = 16384 * 2;
- private static final int DEFAULT_OUTPUT_BUFFER_SIZE = 1024*1024;
- private static final int MONITOR_DURATION_MS = 1000;
- private static final int AC3_HEADER_BITRATE_OFFSET = 4;
-
- // Keep this as static in order to prevent new framework AudioTrack creation
- // while old AudioTrack is being released.
- private static final AudioTrackWrapper AUDIO_TRACK = new AudioTrackWrapper();
- private static final long KEEP_ALIVE_AFTER_EOS_DURATION_MS = 3000;
-
- // Ignore AudioTrack backward movement if duration of movement is below the threshold.
- private static final long BACKWARD_AUDIO_TRACK_MOVE_THRESHOLD_US = 3000;
-
- // AudioTrack position cannot go ahead beyond this limit.
- private static final long CURRENT_POSITION_FROM_PTS_LIMIT_US = 1000000;
-
- // Since MediaCodec processing and AudioTrack playing add delay,
- // PTS interpolated time should be delayed reasonably when AudioTrack is not used.
- private static final long ESTIMATED_TRACK_RENDERING_DELAY_US = 500000;
-
- private final CodecCounters mCodecCounters;
- private final SampleSource.SampleSourceReader mSource;
- private final SampleHolder mSampleHolder;
- private final MediaFormatHolder mFormatHolder;
- private final EventListener mEventListener;
- private final Handler mEventHandler;
- private final AudioTrackMonitor mMonitor;
- private final AudioClock mAudioClock;
-
- private MediaFormat mFormat;
- private final ByteBuffer mOutputBuffer;
- private boolean mOutputReady;
- private int mTrackIndex;
- private boolean mSourceStateReady;
- private boolean mInputStreamEnded;
- private boolean mOutputStreamEnded;
- private long mEndOfStreamMs;
- private long mCurrentPositionUs;
- private int mPresentationCount;
- private long mPresentationTimeUs;
- private long mInterpolatedTimeUs;
- private long mPreviousPositionUs;
- private boolean mIsStopped;
- private ArrayList<Integer> mTracksIndex;
-
- public Ac3PassthroughTrackRenderer(SampleSource source, Handler eventHandler,
- EventListener listener) {
- mSource = source.register();
- mEventHandler = eventHandler;
- mEventListener = listener;
- mTrackIndex = -1;
- mSampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_DIRECT);
- mSampleHolder.ensureSpaceForWrite(DEFAULT_INPUT_BUFFER_SIZE);
- mOutputBuffer = ByteBuffer.allocate(DEFAULT_OUTPUT_BUFFER_SIZE);
- mFormatHolder = new MediaFormatHolder();
- AUDIO_TRACK.restart();
- mCodecCounters = new CodecCounters();
- mMonitor = new AudioTrackMonitor();
- mAudioClock = new AudioClock();
- mTracksIndex = new ArrayList<>();
- }
-
- @Override
- protected MediaClock getMediaClock() {
- return this;
- }
-
- private static boolean handlesMimeType(String mimeType) {
- return mimeType.equals(MimeTypes.AUDIO_AC3) || mimeType.equals(MimeTypes.AUDIO_E_AC3);
- }
-
- @Override
- protected boolean doPrepare(long positionUs) throws ExoPlaybackException {
- boolean sourcePrepared = mSource.prepare(positionUs);
- if (!sourcePrepared) {
- return false;
- }
- for (int i = 0; i < mSource.getTrackCount(); i++) {
- if (handlesMimeType(mSource.getFormat(i).mimeType)) {
- if (mTrackIndex < 0) {
- mTrackIndex = i;
- }
- mTracksIndex.add(i);
- }
- }
-
- // TODO: Check this case. Source does not have the proper mime type.
- return true;
- }
-
- @Override
- protected int getTrackCount() {
- return mTracksIndex.size();
- }
-
- @Override
- protected MediaFormat getFormat(int track) {
- Assertions.checkArgument(track >= 0 && track < mTracksIndex.size());
- return mSource.getFormat(mTracksIndex.get(track));
- }
-
- @Override
- protected void onEnabled(int track, long positionUs, boolean joining) {
- Assertions.checkArgument(track >= 0 && track < mTracksIndex.size());
- mTrackIndex = mTracksIndex.get(track);
- mSource.enable(mTrackIndex, positionUs);
- seekToInternal(positionUs);
- }
-
- @Override
- protected void onDisabled() {
- AUDIO_TRACK.resetSessionId();
- clearDecodeState();
- mFormat = null;
- mSource.disable(mTrackIndex);
- }
-
- @Override
- protected void onReleased() {
- AUDIO_TRACK.release();
- mSource.release();
- }
-
- @Override
- protected boolean isEnded() {
- return mOutputStreamEnded && AUDIO_TRACK.isEnded();
- }
-
- @Override
- protected boolean isReady() {
- return AUDIO_TRACK.isReady() || (mFormat != null && (mSourceStateReady || mOutputReady));
- }
-
- private void seekToInternal(long positionUs) {
- mMonitor.reset(MONITOR_DURATION_MS);
- mSourceStateReady = false;
- mInputStreamEnded = false;
- mOutputStreamEnded = false;
- mPresentationTimeUs = positionUs;
- mPresentationCount = 0;
- mPreviousPositionUs = 0;
- mCurrentPositionUs = Long.MIN_VALUE;
- mInterpolatedTimeUs = Long.MIN_VALUE;
- mAudioClock.setPositionUs(positionUs);
- }
-
- @Override
- protected void seekTo(long positionUs) {
- mSource.seekToUs(positionUs);
- AUDIO_TRACK.reset();
- // resetSessionId() will create a new framework AudioTrack instead of reusing old one.
- AUDIO_TRACK.resetSessionId();
- seekToInternal(positionUs);
- }
-
- @Override
- protected void onStarted() {
- AUDIO_TRACK.play();
- mAudioClock.start();
- mIsStopped = false;
- }
-
- @Override
- protected void onStopped() {
- AUDIO_TRACK.pause();
- mAudioClock.stop();
- mIsStopped = true;
- }
-
- @Override
- protected void maybeThrowError() throws ExoPlaybackException {
- try {
- mSource.maybeThrowError();
- } catch (IOException e) {
- throw new ExoPlaybackException(e);
- }
- }
-
- @Override
- protected void doSomeWork(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
- mMonitor.maybeLog();
- try {
- if (mEndOfStreamMs != 0) {
- // Ensure playback stops, after EoS was notified.
- // Sometimes MediaCodecTrackRenderer does not fetch EoS timely
- // after EoS was notified here long before.
- long diff = SystemClock.elapsedRealtime() - mEndOfStreamMs;
- if (diff >= KEEP_ALIVE_AFTER_EOS_DURATION_MS && !mIsStopped) {
- throw new ExoPlaybackException("Much time has elapsed after EoS");
- }
- }
- boolean continueBuffering = mSource.continueBuffering(mTrackIndex, positionUs);
- if (mSourceStateReady != continueBuffering) {
- mSourceStateReady = continueBuffering;
- if (DEBUG) {
- Log.d(TAG, "mSourceStateReady: " + String.valueOf(mSourceStateReady));
- }
- }
- long discontinuity = mSource.readDiscontinuity(mTrackIndex);
- if (discontinuity != SampleSource.NO_DISCONTINUITY) {
- AUDIO_TRACK.handleDiscontinuity();
- mPresentationTimeUs = discontinuity;
- mPresentationCount = 0;
- clearDecodeState();
- return;
- }
- if (mFormat == null) {
- readFormat();
- return;
- }
-
- // Process only one sample at a time for doSomeWork()
- if (processOutput()) {
- if (!mOutputReady) {
- while (feedInputBuffer()) {
- if (mOutputReady) break;
- }
- }
- }
- mCodecCounters.ensureUpdated();
- } catch (IOException e) {
- throw new ExoPlaybackException(e);
- }
- }
-
- private void ensureAudioTrackInitialized() {
- if (!AUDIO_TRACK.isInitialized()) {
- try {
- if (DEBUG) {
- Log.d(TAG, "AudioTrack initialized");
- }
- AUDIO_TRACK.initialize();
- } catch (AudioTrack.InitializationException e) {
- Log.e(TAG, "Error on AudioTrack initialization", e);
- notifyAudioTrackInitializationError(e);
-
- // Do not throw exception here but just disabling audioTrack to keep playing
- // video without audio.
- AUDIO_TRACK.setStatus(false);
- }
- if (getState() == TrackRenderer.STATE_STARTED) {
- if (DEBUG) {
- Log.d(TAG, "AudioTrack played");
- }
- AUDIO_TRACK.play();
- }
- }
- }
-
- private void clearDecodeState() {
- mOutputReady = false;
- AUDIO_TRACK.reset();
- }
-
- private void readFormat() throws IOException, ExoPlaybackException {
- int result = mSource.readData(mTrackIndex, mCurrentPositionUs,
- mFormatHolder, mSampleHolder);
- if (result == SampleSource.FORMAT_READ) {
- onInputFormatChanged(mFormatHolder);
- }
- }
-
- private void onInputFormatChanged(MediaFormatHolder formatHolder)
- throws ExoPlaybackException {
- mFormat = formatHolder.format;
- if (DEBUG) {
- Log.d(TAG, "AudioTrack was configured to FORMAT: " + mFormat.toString());
- }
- clearDecodeState();
- AUDIO_TRACK.reconfigure(mFormat.getFrameworkMediaFormatV16());
- }
-
- private boolean feedInputBuffer() throws IOException, ExoPlaybackException {
- if (mInputStreamEnded) {
- return false;
- }
-
- mSampleHolder.data.clear();
- mSampleHolder.size = 0;
- int result = mSource.readData(mTrackIndex, mPresentationTimeUs, mFormatHolder,
- mSampleHolder);
- switch (result) {
- case SampleSource.NOTHING_READ: {
- return false;
- }
- case SampleSource.FORMAT_READ: {
- Log.i(TAG, "Format was read again");
- onInputFormatChanged(mFormatHolder);
- return true;
- }
- case SampleSource.END_OF_STREAM: {
- Log.i(TAG, "End of stream from SampleSource");
- mInputStreamEnded = true;
- return false;
- }
- default: {
- mSampleHolder.data.flip();
- decodeDone(mSampleHolder.data, mSampleHolder.timeUs);
- return true;
- }
- }
- }
-
- private boolean processOutput() throws ExoPlaybackException {
- if (mOutputStreamEnded) {
- return false;
- }
- if (!mOutputReady) {
- if (mInputStreamEnded) {
- mOutputStreamEnded = true;
- mEndOfStreamMs = SystemClock.elapsedRealtime();
- return false;
- }
- return true;
- }
-
- ensureAudioTrackInitialized();
- int handleBufferResult;
- try {
- // To reduce discontinuity, interpolate presentation time.
- mInterpolatedTimeUs = mPresentationTimeUs
- + mPresentationCount * AC3_SAMPLE_DURATION_US;
- handleBufferResult = AUDIO_TRACK.handleBuffer(mOutputBuffer,
- 0, mOutputBuffer.limit(), mInterpolatedTimeUs);
- } catch (AudioTrack.WriteException e) {
- notifyAudioTrackWriteError(e);
- throw new ExoPlaybackException(e);
- }
-
- if ((handleBufferResult & AudioTrack.RESULT_POSITION_DISCONTINUITY) != 0) {
- Log.i(TAG, "Play discontinuity happened");
- mCurrentPositionUs = Long.MIN_VALUE;
- }
- if ((handleBufferResult & AudioTrack.RESULT_BUFFER_CONSUMED) != 0) {
- mCodecCounters.renderedOutputBufferCount++;
- mOutputReady = false;
- return true;
- }
- return false;
- }
-
- @Override
- protected long getDurationUs() {
- return mSource.getFormat(mTrackIndex).durationUs;
- }
-
- @Override
- protected long getBufferedPositionUs() {
- long pos = mSource.getBufferedPositionUs();
- return pos == UNKNOWN_TIME_US || pos == END_OF_TRACK_US
- ? pos : Math.max(pos, getPositionUs());
- }
-
- @Override
- public long getPositionUs() {
- if (!AUDIO_TRACK.isInitialized()) {
- return mAudioClock.getPositionUs();
- } else if (!AUDIO_TRACK.isEnabled()) {
- if (mInterpolatedTimeUs > 0) {
- return mInterpolatedTimeUs - ESTIMATED_TRACK_RENDERING_DELAY_US;
- }
- return mPresentationTimeUs;
- }
- long audioTrackCurrentPositionUs = AUDIO_TRACK.getCurrentPositionUs(isEnded());
- if (audioTrackCurrentPositionUs == AudioTrack.CURRENT_POSITION_NOT_SET) {
- mPreviousPositionUs = 0L;
- if (DEBUG) {
- long oldPositionUs = Math.max(mCurrentPositionUs, 0);
- long currentPositionUs = Math.max(mPresentationTimeUs, mCurrentPositionUs);
- Log.d(TAG, "Audio position is not set, diff in us: "
- + String.valueOf(currentPositionUs - oldPositionUs));
- }
- mCurrentPositionUs = Math.max(mPresentationTimeUs, mCurrentPositionUs);
- } else {
- if (mPreviousPositionUs
- > audioTrackCurrentPositionUs + BACKWARD_AUDIO_TRACK_MOVE_THRESHOLD_US) {
- Log.e(TAG, "audio_position BACK JUMP: "
- + (mPreviousPositionUs - audioTrackCurrentPositionUs));
- mCurrentPositionUs = audioTrackCurrentPositionUs;
- } else {
- mCurrentPositionUs = Math.max(mCurrentPositionUs, audioTrackCurrentPositionUs);
- }
- mPreviousPositionUs = audioTrackCurrentPositionUs;
- }
- long upperBound = mPresentationTimeUs + CURRENT_POSITION_FROM_PTS_LIMIT_US;
- if (mCurrentPositionUs > upperBound) {
- mCurrentPositionUs = upperBound;
- }
- return mCurrentPositionUs;
- }
-
- private void decodeDone(ByteBuffer outputBuffer, long presentationTimeUs) {
- if (outputBuffer == null || mOutputBuffer == null) {
- return;
- }
- if (presentationTimeUs < 0) {
- Log.e(TAG, "decodeDone - invalid presentationTimeUs");
- return;
- }
-
- if (TunerDebug.ENABLED) {
- TunerDebug.setAudioPtsUs(presentationTimeUs);
- }
-
- mOutputBuffer.clear();
- Assertions.checkState(mOutputBuffer.remaining() >= outputBuffer.limit());
-
- mOutputBuffer.put(outputBuffer);
- mMonitor.addPts(presentationTimeUs, mOutputBuffer.position(),
- mOutputBuffer.get(AC3_HEADER_BITRATE_OFFSET));
- if (presentationTimeUs == mPresentationTimeUs) {
- mPresentationCount++;
- } else {
- mPresentationCount = 0;
- mPresentationTimeUs = presentationTimeUs;
- }
- mOutputBuffer.flip();
- mOutputReady = true;
- }
-
- private void notifyAudioTrackInitializationError(final AudioTrack.InitializationException e) {
- if (mEventHandler == null || mEventListener == null) {
- return;
- }
- mEventHandler.post(new Runnable() {
- @Override
- public void run() {
- mEventListener.onAudioTrackInitializationError(e);
- }
- });
- }
-
- private void notifyAudioTrackWriteError(final AudioTrack.WriteException e) {
- if (mEventHandler == null || mEventListener == null) {
- return;
- }
- mEventHandler.post(new Runnable() {
- @Override
- public void run() {
- mEventListener.onAudioTrackWriteError(e);
- }
- });
- }
-
- @Override
- public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
- switch (messageType) {
- case MSG_SET_VOLUME:
- AUDIO_TRACK.setVolume((Float) message);
- break;
- case MSG_SET_AUDIO_TRACK:
- boolean enabled = (Integer) message == 1;
- if (enabled == AUDIO_TRACK.isEnabled()) {
- return;
- }
- if (!enabled) {
- // mAudioClock can be different from getPositionUs. In order to sync them,
- // we set mAudioClock.
- mAudioClock.setPositionUs(getPositionUs());
- }
- AUDIO_TRACK.setStatus(enabled);
- if (enabled) {
- // When AUDIO_TRACK is enabled, we need to clear AUDIO_TRACK and seek to
- // the current position. If not, AUDIO_TRACK has the obsolete data.
- seekTo(mAudioClock.getPositionUs());
- }
- break;
- case MSG_SET_PLAYBACK_SPEED:
- mAudioClock.setPlaybackSpeed((Float) message);
- break;
- default:
- super.handleMessage(messageType, message);
- }
- }
-}
diff --git a/src/com/android/tv/tuner/exoplayer/ac3/Ac3TrackRenderer.java b/src/com/android/tv/tuner/exoplayer/ac3/Ac3TrackRenderer.java
deleted file mode 100644
index 2bf86b5a..00000000
--- a/src/com/android/tv/tuner/exoplayer/ac3/Ac3TrackRenderer.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.tuner.exoplayer.ac3;
-
-import android.os.Handler;
-
-import com.google.android.exoplayer.ExoPlaybackException;
-import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
-import com.google.android.exoplayer.MediaCodecSelector;
-import com.google.android.exoplayer.SampleSource;
-
-/**
- * MPEG-2 TS audio track renderer.
- * <p>Since the audio output from {@link android.media.MediaExtractor} contains extra samples at
- * the beginning, using original {@link MediaCodecAudioTrackRenderer} as audio renderer causes
- * asynchronous Audio/Video outputs.
- * This class calculates the offset of audio data and adjust the presentation times to avoid the
- * asynchronous Audio/Video problem.
- */
-public class Ac3TrackRenderer extends MediaCodecAudioTrackRenderer {
- private final String TAG = "Ac3TrackRenderer";
- private final boolean DEBUG = false;
-
- private final Ac3EventListener mListener;
-
- public interface Ac3EventListener extends EventListener {
- /**
- * Invoked when a {@link android.media.PlaybackParams} set to an
- * {@link android.media.AudioTrack} is not valid.
- *
- * @param e The corresponding exception.
- */
- void onAudioTrackSetPlaybackParamsError(IllegalArgumentException e);
- }
-
- public Ac3TrackRenderer(SampleSource source, MediaCodecSelector mediaCodecSelector,
- Handler eventHandler, EventListener eventListener) {
- super(source, mediaCodecSelector, eventHandler, eventListener);
- mListener = (Ac3EventListener) eventListener;
- }
-
- @Override
- public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
- if (messageType == MSG_SET_PLAYBACK_PARAMS) {
- try {
- super.handleMessage(messageType, message);
- } catch (IllegalArgumentException e) {
- if (isAudioTrackSetPlaybackParamsError(e)) {
- notifyAudioTrackSetPlaybackParamsError(e);
- }
- }
- return;
- }
- super.handleMessage(messageType, message);
- }
-
- private void notifyAudioTrackSetPlaybackParamsError(final IllegalArgumentException e) {
- if (eventHandler != null && mListener != null) {
- eventHandler.post(new Runnable() {
- @Override
- public void run() {
- mListener.onAudioTrackSetPlaybackParamsError(e);
- }
- });
- }
- }
-
- static private boolean isAudioTrackSetPlaybackParamsError(IllegalArgumentException e) {
- if (e.getStackTrace() == null || e.getStackTrace().length < 1) {
- return false;
- }
- for (StackTraceElement element : e.getStackTrace()) {
- String elementString = element.toString();
- if (elementString.startsWith("android.media.AudioTrack.setPlaybackParams")) {
- return true;
- }
- }
- return false;
- }
-} \ No newline at end of file
diff --git a/src/com/android/tv/tuner/exoplayer/ac3/AudioClock.java b/src/com/android/tv/tuner/exoplayer/ac3/AudioClock.java
deleted file mode 100644
index 600c2c88..00000000
--- a/src/com/android/tv/tuner/exoplayer/ac3/AudioClock.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.tuner.exoplayer.ac3;
-
-import com.android.tv.common.SoftPreconditions;
-
-import android.os.SystemClock;
-
-/**
- * Copy of {@link com.google.android.exoplayer.MediaClock}.
- * <p>
- * A simple clock for tracking the progression of media time. The clock can be started, stopped and
- * its time can be set and retrieved. When started, this clock is based on
- * {@link SystemClock#elapsedRealtime()}.
- */
-/* package */ class AudioClock {
- private boolean mStarted;
-
- /**
- * The media time when the clock was last set or stopped.
- */
- private long mPositionUs;
-
- /**
- * The difference between {@link SystemClock#elapsedRealtime()} and {@link #mPositionUs}
- * when the clock was last set or mStarted.
- */
- private long mDeltaUs;
-
- private float mPlaybackSpeed = 1.0f;
- private long mDeltaUpdatedTimeUs;
-
- /**
- * Starts the clock. Does nothing if the clock is already started.
- */
- public void start() {
- if (!mStarted) {
- mStarted = true;
- mDeltaUs = elapsedRealtimeMinus(mPositionUs);
- mDeltaUpdatedTimeUs = SystemClock.elapsedRealtime() * 1000;
- }
- }
-
- /**
- * Stops the clock. Does nothing if the clock is already stopped.
- */
- public void stop() {
- if (mStarted) {
- mPositionUs = elapsedRealtimeMinus(mDeltaUs);
- mStarted = false;
- }
- }
-
- /**
- * @param timeUs The position to set in microseconds.
- */
- public void setPositionUs(long timeUs) {
- this.mPositionUs = timeUs;
- mDeltaUs = elapsedRealtimeMinus(timeUs);
- mDeltaUpdatedTimeUs = SystemClock.elapsedRealtime() * 1000;
- }
-
- /**
- * @return The current position in microseconds.
- */
- public long getPositionUs() {
- if (!mStarted) {
- return mPositionUs;
- }
- if (mPlaybackSpeed != 1.0f) {
- long elapsedTimeFromPlaybackSpeedChanged = SystemClock.elapsedRealtime() * 1000
- - mDeltaUpdatedTimeUs;
- return elapsedRealtimeMinus(mDeltaUs)
- + (long) ((mPlaybackSpeed - 1.0f) * elapsedTimeFromPlaybackSpeedChanged);
- } else {
- return elapsedRealtimeMinus(mDeltaUs);
- }
- }
-
- /**
- * Sets playback speed. {@code speed} should be positive.
- */
- public void setPlaybackSpeed(float speed) {
- SoftPreconditions.checkState(speed > 0);
- mDeltaUs = elapsedRealtimeMinus(getPositionUs());
- mDeltaUpdatedTimeUs = SystemClock.elapsedRealtime() * 1000;
- mPlaybackSpeed = speed;
- }
-
- private long elapsedRealtimeMinus(long toSubtractUs) {
- return SystemClock.elapsedRealtime() * 1000 - toSubtractUs;
- }
-}
diff --git a/src/com/android/tv/tuner/exoplayer/ac3/AudioTrackMonitor.java b/src/com/android/tv/tuner/exoplayer/ac3/AudioTrackMonitor.java
deleted file mode 100644
index bfdf08ac..00000000
--- a/src/com/android/tv/tuner/exoplayer/ac3/AudioTrackMonitor.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.tuner.exoplayer.ac3;
-
-import android.os.SystemClock;
-import android.util.Log;
-import android.util.Pair;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Monitors the rendering position of {@link AudioTrack}.
- */
-public class AudioTrackMonitor {
- private static final String TAG = "AudioTrackMonitor";
- private static final boolean DEBUG = false;
-
- // For fetched audio samples
- private final ArrayList<Pair<Long, Integer>> mPtsList = new ArrayList<>();
- private final Set<Integer> mSampleSize = new HashSet<>();
- private final Set<Integer> mCurSampleSize = new HashSet<>();
- private final Set<Integer> mAc3Header = new HashSet<>();
-
- private long mExpireMs;
- private long mDuration;
- private long mSampleCount;
- private long mTotalCount;
- private long mStartMs;
-
- private void flush() {
- mExpireMs += mDuration;
- mSampleCount = 0;
- mCurSampleSize.clear();
- mPtsList.clear();
- }
-
- /**
- * Resets and initializes {@link AudioTrackMonitor}.
- *
- * @param duration the frequency of monitoring in milliseconds
- */
- public void reset(long duration) {
- mExpireMs = SystemClock.elapsedRealtime();
- mDuration = duration;
- mTotalCount = 0;
- mStartMs = 0;
- mSampleSize.clear();
- mAc3Header.clear();
- flush();
- }
-
- /**
- * Adds an audio sample information for monitoring.
- *
- * @param pts the presentation timestamp of the sample
- * @param sampleSize the size in bytes of the sample
- * @param header the bitrate &amp; sampling information header of the sample
- */
- public void addPts(long pts, int sampleSize, int header) {
- mTotalCount++;
- mSampleCount++;
- mSampleSize.add(sampleSize);
- mAc3Header.add(header);
- mCurSampleSize.add(sampleSize);
- if (mTotalCount == 1) {
- mStartMs = SystemClock.elapsedRealtime();
- }
- if (mPtsList.isEmpty() || mPtsList.get(mPtsList.size() - 1).first != pts) {
- mPtsList.add(Pair.create(pts, 1));
- return;
- }
- Pair<Long, Integer> pair = mPtsList.get(mPtsList.size() - 1);
- mPtsList.set(mPtsList.size() - 1, Pair.create(pair.first, pair.second + 1));
- }
-
- /**
- * Logs if interested events are present.
- * <p>
- * Periodic logging is not enabled in release mode in order to avoid verbose logging.
- */
- public void maybeLog() {
- long now = SystemClock.elapsedRealtime();
- if (mExpireMs != 0 && now >= mExpireMs) {
- if (DEBUG) {
- long sampleDuration = (mTotalCount - 1) *
- Ac3PassthroughTrackRenderer.AC3_SAMPLE_DURATION_US / 1000;
- long totalDuration = now - mStartMs;
- StringBuilder ptsBuilder = new StringBuilder();
- ptsBuilder.append("PTS received ").append(mSampleCount).append(", ")
- .append(totalDuration - sampleDuration).append(' ');
-
- for (Pair<Long, Integer> pair : mPtsList) {
- ptsBuilder.append('[').append(pair.first).append(':').append(pair.second)
- .append("], ");
- }
- Log.d(TAG, ptsBuilder.toString());
- }
- if (DEBUG || mCurSampleSize.size() > 1) {
- Log.d(TAG, "PTS received sample size: "
- + String.valueOf(mSampleSize) + mCurSampleSize + mAc3Header);
- }
- flush();
- }
- }
-}
diff --git a/src/com/android/tv/tuner/exoplayer/ac3/AudioTrackWrapper.java b/src/com/android/tv/tuner/exoplayer/ac3/AudioTrackWrapper.java
deleted file mode 100644
index bc3c5d00..00000000
--- a/src/com/android/tv/tuner/exoplayer/ac3/AudioTrackWrapper.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.tuner.exoplayer.ac3;
-
-import android.media.MediaFormat;
-
-import com.google.android.exoplayer.audio.AudioTrack;
-
-import java.nio.ByteBuffer;
-
-/**
- * {@link AudioTrack} wrapper class for trickplay operations including FF/RW.
- * FF/RW trickplay operations do not need framework {@link AudioTrack}.
- * This wrapper class will do nothing in disabled status for those operations.
- */
-public class AudioTrackWrapper {
- private final AudioTrack mAudioTrack = new AudioTrack();
- private int mAudioSessionID;
- private boolean mIsEnabled;
-
- AudioTrackWrapper() {
- mIsEnabled = true;
- }
-
- public void resetSessionId() {
- mAudioSessionID = AudioTrack.SESSION_ID_NOT_SET;
- }
-
- public boolean isInitialized() {
- return mIsEnabled && mAudioTrack.isInitialized();
- }
-
- public void restart() {
- if (mAudioTrack.isInitialized()) {
- mAudioTrack.release();
- }
- mIsEnabled = true;
- resetSessionId();
- }
-
- public void release() {
- if (mAudioSessionID != AudioTrack.SESSION_ID_NOT_SET) {
- mAudioTrack.release();
- }
- }
-
- public void initialize() throws AudioTrack.InitializationException {
- if (!mIsEnabled) {
- return;
- }
- if (mAudioSessionID != AudioTrack.SESSION_ID_NOT_SET) {
- mAudioTrack.initialize(mAudioSessionID);
- } else {
- mAudioSessionID = mAudioTrack.initialize();
- }
- }
-
- public void reset() {
- if (!mIsEnabled) {
- return;
- }
- mAudioTrack.reset();
- }
-
- public boolean isEnded() {
- return !mIsEnabled || !mAudioTrack.hasPendingData();
- }
-
- public boolean isReady() {
- // In the case of not playing actual audio data, Audio track is always ready.
- return !mIsEnabled || mAudioTrack.hasPendingData();
- }
-
- public void play() {
- if (!mIsEnabled) {
- return;
- }
- mAudioTrack.play();
- }
-
- public void pause() {
- if (!mIsEnabled) {
- return;
- }
- mAudioTrack.pause();
- }
-
- public void setVolume(float volume) {
- if (!mIsEnabled) {
- return;
- }
- mAudioTrack.setVolume(volume);
- }
-
- public void reconfigure(MediaFormat format) {
- if (!mIsEnabled || format == null) {
- return;
- }
- String mimeType = format.getString(MediaFormat.KEY_MIME);
- int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
- int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
- int pcmEncoding;
- try {
- pcmEncoding = format.getInteger(MediaFormat.KEY_PCM_ENCODING);
- } catch (Exception e) {
- pcmEncoding = com.google.android.exoplayer.MediaFormat.NO_VALUE;
- }
- // TODO: Handle non-AC3 or non-passthrough audio.
- if (MediaFormat.MIMETYPE_AUDIO_AC3.equalsIgnoreCase(mimeType) && channelCount != 2) {
- // Workarounds b/25955476.
- // Since all devices and platforms does not support passthrough for non-stereo AC3,
- // It is safe to fake non-stereo AC3 as AC3 stereo which is default passthrough mode.
- // In other words, the channel count should be always 2.
- channelCount = 2;
- }
- mAudioTrack.configure(mimeType, channelCount, sampleRate, pcmEncoding);
- }
-
- public void handleDiscontinuity() {
- if (!mIsEnabled) {
- return;
- }
- mAudioTrack.handleDiscontinuity();
- }
-
- public int handleBuffer(ByteBuffer buffer, int offset, int size, long presentationTimeUs)
- throws AudioTrack.WriteException {
- if (!mIsEnabled) {
- return AudioTrack.RESULT_BUFFER_CONSUMED;
- }
- return mAudioTrack.handleBuffer(buffer, offset, size, presentationTimeUs);
- }
-
- public void setStatus(boolean enable) {
- if (enable == mIsEnabled) {
- return;
- }
- mAudioTrack.reset();
- mIsEnabled = enable;
- }
-
- public boolean isEnabled() {
- return mIsEnabled;
- }
-
- // This should be used only in case of being enabled.
- public long getCurrentPositionUs(boolean isEnded) {
- return mAudioTrack.getCurrentPositionUs(isEnded);
- }
-}
diff --git a/src/com/android/tv/tuner/exoplayer/audio/AudioClock.java b/src/com/android/tv/tuner/exoplayer/audio/AudioClock.java
new file mode 100644
index 00000000..5666c5b9
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/audio/AudioClock.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2015 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.tv.tuner.exoplayer.audio;
+
+import com.android.tv.common.SoftPreconditions;
+
+import android.os.SystemClock;
+
+/**
+ * Copy of {@link com.google.android.exoplayer.MediaClock}.
+ * <p>
+ * A simple clock for tracking the progression of media time. The clock can be started, stopped and
+ * its time can be set and retrieved. When started, this clock is based on
+ * {@link SystemClock#elapsedRealtime()}.
+ */
+/* package */ class AudioClock {
+ private boolean mStarted;
+
+ /**
+ * The media time when the clock was last set or stopped.
+ */
+ private long mPositionUs;
+
+ /**
+ * The difference between {@link SystemClock#elapsedRealtime()} and {@link #mPositionUs}
+ * when the clock was last set or mStarted.
+ */
+ private long mDeltaUs;
+
+ private float mPlaybackSpeed = 1.0f;
+ private long mDeltaUpdatedTimeUs;
+
+ /**
+ * Starts the clock. Does nothing if the clock is already started.
+ */
+ public void start() {
+ if (!mStarted) {
+ mStarted = true;
+ mDeltaUs = elapsedRealtimeMinus(mPositionUs);
+ mDeltaUpdatedTimeUs = SystemClock.elapsedRealtime() * 1000;
+ }
+ }
+
+ /**
+ * Stops the clock. Does nothing if the clock is already stopped.
+ */
+ public void stop() {
+ if (mStarted) {
+ mPositionUs = elapsedRealtimeMinus(mDeltaUs);
+ mStarted = false;
+ }
+ }
+
+ /**
+ * @param timeUs The position to set in microseconds.
+ */
+ public void setPositionUs(long timeUs) {
+ this.mPositionUs = timeUs;
+ mDeltaUs = elapsedRealtimeMinus(timeUs);
+ mDeltaUpdatedTimeUs = SystemClock.elapsedRealtime() * 1000;
+ }
+
+ /**
+ * @return The current position in microseconds.
+ */
+ public long getPositionUs() {
+ if (!mStarted) {
+ return mPositionUs;
+ }
+ if (mPlaybackSpeed != 1.0f) {
+ long elapsedTimeFromPlaybackSpeedChanged = SystemClock.elapsedRealtime() * 1000
+ - mDeltaUpdatedTimeUs;
+ return elapsedRealtimeMinus(mDeltaUs)
+ + (long) ((mPlaybackSpeed - 1.0f) * elapsedTimeFromPlaybackSpeedChanged);
+ } else {
+ return elapsedRealtimeMinus(mDeltaUs);
+ }
+ }
+
+ /**
+ * Sets playback speed. {@code speed} should be positive.
+ */
+ public void setPlaybackSpeed(float speed) {
+ SoftPreconditions.checkState(speed > 0);
+ mDeltaUs = elapsedRealtimeMinus(getPositionUs());
+ mDeltaUpdatedTimeUs = SystemClock.elapsedRealtime() * 1000;
+ mPlaybackSpeed = speed;
+ }
+
+ private long elapsedRealtimeMinus(long toSubtractUs) {
+ return SystemClock.elapsedRealtime() * 1000 - toSubtractUs;
+ }
+}
diff --git a/src/com/android/tv/tuner/exoplayer/audio/AudioDecoder.java b/src/com/android/tv/tuner/exoplayer/audio/AudioDecoder.java
new file mode 100644
index 00000000..e581092a
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/audio/AudioDecoder.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 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.tv.tuner.exoplayer.audio;
+
+import com.google.android.exoplayer.ExoPlaybackException;
+import com.google.android.exoplayer.MediaFormat;
+import com.google.android.exoplayer.SampleHolder;
+
+import java.nio.ByteBuffer;
+
+/** A base class for audio decoders. */
+public abstract class AudioDecoder {
+
+ /**
+ * Decodes an audio sample.
+ *
+ * @param sampleHolder a holder that contains the sample data and corresponding metadata
+ */
+ public abstract void decode(SampleHolder sampleHolder);
+
+ /** Returns a decoded sample from decoder. */
+ public abstract ByteBuffer getDecodedSample();
+
+ /** Returns the presentation time for the decoded sample. */
+ public abstract long getDecodedTimeUs();
+
+ /**
+ * Clear previous decode state if any. Prepares to decode samples of the specified encoding.
+ * This method should be called before using decode.
+ *
+ * @param mime audio encoding
+ */
+ public abstract void resetDecoderState(String mimeType);
+
+ /** Releases all the resource. */
+ public abstract void release();
+
+ /**
+ * Init decoder if needed.
+ *
+ * @param format the format used to initialize decoder
+ */
+ public void maybeInitDecoder(MediaFormat format) throws ExoPlaybackException {
+ // Do nothing.
+ }
+
+ /** Returns input buffer that will be used in decoder. */
+ public ByteBuffer getInputBuffer() {
+ return null;
+ }
+
+ /** Returns the output format. */
+ public android.media.MediaFormat getOutputFormat() {
+ return null;
+ }
+}
diff --git a/src/com/android/tv/tuner/exoplayer/audio/AudioTrackMonitor.java b/src/com/android/tv/tuner/exoplayer/audio/AudioTrackMonitor.java
new file mode 100644
index 00000000..ec616b13
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/audio/AudioTrackMonitor.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 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.tv.tuner.exoplayer.audio;
+
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.Pair;
+
+import com.google.android.exoplayer.util.MimeTypes;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Monitors the rendering position of {@link AudioTrack}.
+ */
+public class AudioTrackMonitor {
+ private static final String TAG = "AudioTrackMonitor";
+ private static final boolean DEBUG = false;
+
+ // For fetched audio samples
+ private final ArrayList<Pair<Long, Integer>> mPtsList = new ArrayList<>();
+ private final Set<Integer> mSampleSize = new HashSet<>();
+ private final Set<Integer> mCurSampleSize = new HashSet<>();
+ private final Set<Integer> mHeader = new HashSet<>();
+
+ private long mExpireMs;
+ private long mDuration;
+ private long mSampleCount;
+ private long mTotalCount;
+ private long mStartMs;
+
+ private boolean mIsMp2;
+
+ private void flush() {
+ mExpireMs += mDuration;
+ mSampleCount = 0;
+ mCurSampleSize.clear();
+ mPtsList.clear();
+ }
+
+ /**
+ * Resets and initializes {@link AudioTrackMonitor}.
+ *
+ * @param duration the frequency of monitoring in milliseconds
+ */
+ public void reset(long duration) {
+ mExpireMs = SystemClock.elapsedRealtime();
+ mDuration = duration;
+ mTotalCount = 0;
+ mStartMs = 0;
+ mSampleSize.clear();
+ mHeader.clear();
+ flush();
+ }
+
+ public void setEncoding(String mime) {
+ mIsMp2 = MimeTypes.AUDIO_MPEG_L2.equalsIgnoreCase(mime);
+ }
+
+ /**
+ * Adds an audio sample information for monitoring.
+ *
+ * @param pts the presentation timestamp of the sample
+ * @param sampleSize the size in bytes of the sample
+ * @param header the bitrate &amp; sampling information header of the sample
+ */
+ public void addPts(long pts, int sampleSize, int header) {
+ mTotalCount++;
+ mSampleCount++;
+ mSampleSize.add(sampleSize);
+ mHeader.add(header);
+ mCurSampleSize.add(sampleSize);
+ if (mTotalCount == 1) {
+ mStartMs = SystemClock.elapsedRealtime();
+ }
+ if (mPtsList.isEmpty() || mPtsList.get(mPtsList.size() - 1).first != pts) {
+ mPtsList.add(Pair.create(pts, 1));
+ return;
+ }
+ Pair<Long, Integer> pair = mPtsList.get(mPtsList.size() - 1);
+ mPtsList.set(mPtsList.size() - 1, Pair.create(pair.first, pair.second + 1));
+ }
+
+ /**
+ * Logs if interested events are present.
+ * <p>
+ * Periodic logging is not enabled in release mode in order to avoid verbose logging.
+ */
+ public void maybeLog() {
+ long now = SystemClock.elapsedRealtime();
+ if (mExpireMs != 0 && now >= mExpireMs) {
+ if (DEBUG) {
+ long unitDuration = mIsMp2 ? MpegTsDefaultAudioTrackRenderer.MP2_SAMPLE_DURATION_US
+ : MpegTsDefaultAudioTrackRenderer.AC3_SAMPLE_DURATION_US;
+ long sampleDuration = (mTotalCount - 1) * unitDuration / 1000;
+ long totalDuration = now - mStartMs;
+ StringBuilder ptsBuilder = new StringBuilder();
+ ptsBuilder.append("PTS received ").append(mSampleCount).append(", ")
+ .append(totalDuration - sampleDuration).append(' ');
+
+ for (Pair<Long, Integer> pair : mPtsList) {
+ ptsBuilder.append('[').append(pair.first).append(':').append(pair.second)
+ .append("], ");
+ }
+ Log.d(TAG, ptsBuilder.toString());
+ }
+ if (DEBUG || mCurSampleSize.size() > 1) {
+ Log.d(TAG, "PTS received sample size: "
+ + String.valueOf(mSampleSize) + mCurSampleSize + mHeader);
+ }
+ flush();
+ }
+ }
+}
diff --git a/src/com/android/tv/tuner/exoplayer/audio/AudioTrackWrapper.java b/src/com/android/tv/tuner/exoplayer/audio/AudioTrackWrapper.java
new file mode 100644
index 00000000..953c9fc4
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/audio/AudioTrackWrapper.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2015 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.tv.tuner.exoplayer.audio;
+
+import android.media.MediaFormat;
+
+import com.google.android.exoplayer.C;
+import com.google.android.exoplayer.audio.AudioTrack;
+
+import java.nio.ByteBuffer;
+
+/**
+ * {@link AudioTrack} wrapper class for trickplay operations including FF/RW.
+ * FF/RW trickplay operations do not need framework {@link AudioTrack}.
+ * This wrapper class will do nothing in disabled status for those operations.
+ */
+public class AudioTrackWrapper {
+ private static final int PCM16_FRAME_BYTES = 2;
+ private static final int AC3_FRAMES_IN_ONE_SAMPLE = 1536;
+ private static final int BUFFERED_SAMPLES_IN_AUDIOTRACK =
+ MpegTsDefaultAudioTrackRenderer.BUFFERED_SAMPLES_IN_AUDIOTRACK;
+ private final AudioTrack mAudioTrack = new AudioTrack();
+ private int mAudioSessionID;
+ private boolean mIsEnabled;
+
+ AudioTrackWrapper() {
+ mIsEnabled = true;
+ }
+
+ public void resetSessionId() {
+ mAudioSessionID = AudioTrack.SESSION_ID_NOT_SET;
+ }
+
+ public boolean isInitialized() {
+ return mIsEnabled && mAudioTrack.isInitialized();
+ }
+
+ public void restart() {
+ if (mAudioTrack.isInitialized()) {
+ mAudioTrack.release();
+ }
+ mIsEnabled = true;
+ resetSessionId();
+ }
+
+ public void release() {
+ if (mAudioSessionID != AudioTrack.SESSION_ID_NOT_SET) {
+ mAudioTrack.release();
+ }
+ }
+
+ public void initialize() throws AudioTrack.InitializationException {
+ if (!mIsEnabled) {
+ return;
+ }
+ if (mAudioSessionID != AudioTrack.SESSION_ID_NOT_SET) {
+ mAudioTrack.initialize(mAudioSessionID);
+ } else {
+ mAudioSessionID = mAudioTrack.initialize();
+ }
+ }
+
+ public void reset() {
+ if (!mIsEnabled) {
+ return;
+ }
+ mAudioTrack.reset();
+ }
+
+ public boolean isEnded() {
+ return !mIsEnabled || !mAudioTrack.hasPendingData();
+ }
+
+ public boolean isReady() {
+ // In the case of not playing actual audio data, Audio track is always ready.
+ return !mIsEnabled || mAudioTrack.hasPendingData();
+ }
+
+ public void play() {
+ if (!mIsEnabled) {
+ return;
+ }
+ mAudioTrack.play();
+ }
+
+ public void pause() {
+ if (!mIsEnabled) {
+ return;
+ }
+ mAudioTrack.pause();
+ }
+
+ public void setVolume(float volume) {
+ if (!mIsEnabled) {
+ return;
+ }
+ mAudioTrack.setVolume(volume);
+ }
+
+ public void reconfigure(MediaFormat format, int audioBufferSize) {
+ if (!mIsEnabled || format == null) {
+ return;
+ }
+ String mimeType = format.getString(MediaFormat.KEY_MIME);
+ int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+ int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+ int pcmEncoding;
+ try {
+ pcmEncoding = format.getInteger(MediaFormat.KEY_PCM_ENCODING);
+ } catch (Exception e) {
+ pcmEncoding = C.ENCODING_PCM_16BIT;
+ }
+ // TODO: Handle non-AC3.
+ if (MediaFormat.MIMETYPE_AUDIO_AC3.equalsIgnoreCase(mimeType) && channelCount != 2) {
+ // Workarounds b/25955476.
+ // Since all devices and platforms does not support passthrough for non-stereo AC3,
+ // It is safe to fake non-stereo AC3 as AC3 stereo which is default passthrough mode.
+ // In other words, the channel count should be always 2.
+ channelCount = 2;
+ }
+ if (MediaFormat.MIMETYPE_AUDIO_RAW.equalsIgnoreCase(mimeType)) {
+ audioBufferSize =
+ channelCount
+ * PCM16_FRAME_BYTES
+ * AC3_FRAMES_IN_ONE_SAMPLE
+ * BUFFERED_SAMPLES_IN_AUDIOTRACK;
+ }
+ mAudioTrack.configure(mimeType, channelCount, sampleRate, pcmEncoding, audioBufferSize);
+ }
+
+ public void handleDiscontinuity() {
+ if (!mIsEnabled) {
+ return;
+ }
+ mAudioTrack.handleDiscontinuity();
+ }
+
+ public int handleBuffer(ByteBuffer buffer, int offset, int size, long presentationTimeUs)
+ throws AudioTrack.WriteException {
+ if (!mIsEnabled) {
+ return AudioTrack.RESULT_BUFFER_CONSUMED;
+ }
+ return mAudioTrack.handleBuffer(buffer, offset, size, presentationTimeUs);
+ }
+
+ public void setStatus(boolean enable) {
+ if (enable == mIsEnabled) {
+ return;
+ }
+ mAudioTrack.reset();
+ mIsEnabled = enable;
+ }
+
+ public boolean isEnabled() {
+ return mIsEnabled;
+ }
+
+ // This should be used only in case of being enabled.
+ public long getCurrentPositionUs(boolean isEnded) {
+ return mAudioTrack.getCurrentPositionUs(isEnded);
+ }
+}
diff --git a/src/com/android/tv/tuner/exoplayer/audio/MediaCodecAudioDecoder.java b/src/com/android/tv/tuner/exoplayer/audio/MediaCodecAudioDecoder.java
new file mode 100644
index 00000000..72bc68b6
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/audio/MediaCodecAudioDecoder.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2017 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.tv.tuner.exoplayer.audio;
+
+import android.media.MediaCodec;
+import android.util.Log;
+
+import com.google.android.exoplayer.CodecCounters;
+import com.google.android.exoplayer.DecoderInfo;
+import com.google.android.exoplayer.ExoPlaybackException;
+import com.google.android.exoplayer.MediaCodecSelector;
+import com.google.android.exoplayer.MediaCodecUtil;
+import com.google.android.exoplayer.MediaFormat;
+import com.google.android.exoplayer.SampleHolder;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+
+/** A decoder to use MediaCodec for decoding audio stream. */
+public class MediaCodecAudioDecoder extends AudioDecoder {
+ private static final String TAG = "MediaCodecAudioDecoder";
+
+ public static final int INDEX_INVALID = -1;
+
+ private final CodecCounters mCodecCounters;
+ private final MediaCodecSelector mSelector;
+
+ private MediaCodec mCodec;
+ private MediaCodec.BufferInfo mOutputBufferInfo;
+ private ByteBuffer mMediaCodecOutputBuffer;
+ private ArrayList<Long> mDecodeOnlyPresentationTimestamps;
+ private boolean mWaitingForFirstSyncFrame;
+ private boolean mIsNewIndex;
+ private int mInputIndex;
+ private int mOutputIndex;
+
+ /** Creates a MediaCodec based audio decoder. */
+ public MediaCodecAudioDecoder(MediaCodecSelector selector) {
+ mSelector = selector;
+ mOutputBufferInfo = new MediaCodec.BufferInfo();
+ mCodecCounters = new CodecCounters();
+ mDecodeOnlyPresentationTimestamps = new ArrayList<>();
+ }
+
+ /** Returns {@code true} if there is decoder for {@code mimeType}. */
+ public static boolean supportMimeType(MediaCodecSelector selector, String mimeType) {
+ if (selector == null) {
+ return false;
+ }
+ return getDecoderInfo(selector, mimeType) != null;
+ }
+
+ private static DecoderInfo getDecoderInfo(MediaCodecSelector selector, String mimeType) {
+ try {
+ return selector.getDecoderInfo(mimeType, false);
+ } catch (MediaCodecUtil.DecoderQueryException e) {
+ Log.e(TAG, "Select decoder error:" + e);
+ return null;
+ }
+ }
+
+ private boolean shouldInitCodec(MediaFormat format) {
+ return format != null && mCodec == null;
+ }
+
+ @Override
+ public void maybeInitDecoder(MediaFormat format) throws ExoPlaybackException {
+ if (!shouldInitCodec(format)) {
+ return;
+ }
+
+ String mimeType = format.mimeType;
+ DecoderInfo decoderInfo = getDecoderInfo(mSelector, mimeType);
+ if (decoderInfo == null) {
+ Log.i(TAG, "There is not decoder found for " + mimeType);
+ return;
+ }
+
+ String codecName = decoderInfo.name;
+ try {
+ mCodec = MediaCodec.createByCodecName(codecName);
+ mCodec.configure(format.getFrameworkMediaFormatV16(), null, null, 0);
+ mCodec.start();
+ } catch (Exception e) {
+ Log.e(TAG, "Failed when configure or start codec:" + e);
+ throw new ExoPlaybackException(e);
+ }
+ mInputIndex = INDEX_INVALID;
+ mOutputIndex = INDEX_INVALID;
+ mWaitingForFirstSyncFrame = true;
+ mCodecCounters.codecInitCount++;
+ }
+
+ @Override
+ public void resetDecoderState(String mimeType) {
+ if (mCodec == null) {
+ return;
+ }
+ mInputIndex = INDEX_INVALID;
+ mOutputIndex = INDEX_INVALID;
+ mDecodeOnlyPresentationTimestamps.clear();
+ mCodec.flush();
+ mWaitingForFirstSyncFrame = true;
+ }
+
+ @Override
+ public void release() {
+ if (mCodec != null) {
+ mDecodeOnlyPresentationTimestamps.clear();
+ mInputIndex = INDEX_INVALID;
+ mOutputIndex = INDEX_INVALID;
+ mCodecCounters.codecReleaseCount++;
+ try {
+ mCodec.stop();
+ } finally {
+ try {
+ mCodec.release();
+ } finally {
+ mCodec = null;
+ }
+ }
+ }
+ }
+
+ /** Returns the index of input buffer which is ready for using. */
+ public int getInputIndex() {
+ return mInputIndex;
+ }
+
+ @Override
+ public ByteBuffer getInputBuffer() {
+ if (mInputIndex < 0) {
+ mInputIndex = mCodec.dequeueInputBuffer(0);
+ if (mInputIndex < 0) {
+ return null;
+ }
+ return mCodec.getInputBuffer(mInputIndex);
+ }
+ return mCodec.getInputBuffer(mInputIndex);
+ }
+
+ @Override
+ public void decode(SampleHolder sampleHolder) {
+ if (mWaitingForFirstSyncFrame) {
+ if (!sampleHolder.isSyncFrame()) {
+ sampleHolder.clearData();
+ return;
+ }
+ mWaitingForFirstSyncFrame = false;
+ }
+ long presentationTimeUs = sampleHolder.timeUs;
+ if (sampleHolder.isDecodeOnly()) {
+ mDecodeOnlyPresentationTimestamps.add(presentationTimeUs);
+ }
+ mCodec.queueInputBuffer(mInputIndex, 0, sampleHolder.data.limit(), presentationTimeUs, 0);
+ mInputIndex = INDEX_INVALID;
+ mCodecCounters.inputBufferCount++;
+ }
+
+ private int getDecodeOnlyIndex(long presentationTimeUs) {
+ final int size = mDecodeOnlyPresentationTimestamps.size();
+ for (int i = 0; i < size; i++) {
+ if (mDecodeOnlyPresentationTimestamps.get(i).longValue() == presentationTimeUs) {
+ return i;
+ }
+ }
+ return INDEX_INVALID;
+ }
+
+ /** Returns the index of output buffer which is ready for using. */
+ public int getOutputIndex() {
+ if (mOutputIndex < 0) {
+ mOutputIndex = mCodec.dequeueOutputBuffer(mOutputBufferInfo, 0);
+ mIsNewIndex = true;
+ } else {
+ mIsNewIndex = false;
+ }
+ return mOutputIndex;
+ }
+
+ @Override
+ public android.media.MediaFormat getOutputFormat() {
+ return mCodec.getOutputFormat();
+ }
+
+ /** Returns {@code true} if the output is only for decoding but not for rendering. */
+ public boolean maybeDecodeOnlyIndex() {
+ int decodeOnlyIndex = getDecodeOnlyIndex(mOutputBufferInfo.presentationTimeUs);
+ if (decodeOnlyIndex != INDEX_INVALID) {
+ mCodec.releaseOutputBuffer(mOutputIndex, false);
+ mCodecCounters.skippedOutputBufferCount++;
+ mDecodeOnlyPresentationTimestamps.remove(decodeOnlyIndex);
+ mOutputIndex = INDEX_INVALID;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public ByteBuffer getDecodedSample() {
+ if (maybeDecodeOnlyIndex() || mOutputIndex < 0) {
+ return null;
+ }
+ if (mIsNewIndex) {
+ mMediaCodecOutputBuffer = mCodec.getOutputBuffer(mOutputIndex);
+ }
+ return mMediaCodecOutputBuffer;
+ }
+
+ @Override
+ public long getDecodedTimeUs() {
+ return mOutputBufferInfo.presentationTimeUs;
+ }
+
+ /** Releases the output buffer after rendering. */
+ public void releaseOutputBuffer() {
+ mCodecCounters.renderedOutputBufferCount++;
+ mCodec.releaseOutputBuffer(mOutputIndex, false);
+ mOutputIndex = INDEX_INVALID;
+ }
+}
diff --git a/src/com/android/tv/tuner/exoplayer/audio/MpegTsDefaultAudioTrackRenderer.java b/src/com/android/tv/tuner/exoplayer/audio/MpegTsDefaultAudioTrackRenderer.java
new file mode 100644
index 00000000..77170419
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/audio/MpegTsDefaultAudioTrackRenderer.java
@@ -0,0 +1,735 @@
+/*
+ * Copyright (C) 2015 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.tv.tuner.exoplayer.audio;
+
+import android.media.MediaCodec;
+import android.os.Build;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.google.android.exoplayer.CodecCounters;
+import com.google.android.exoplayer.ExoPlaybackException;
+import com.google.android.exoplayer.MediaClock;
+import com.google.android.exoplayer.MediaCodecSelector;
+import com.google.android.exoplayer.MediaFormat;
+import com.google.android.exoplayer.MediaFormatHolder;
+import com.google.android.exoplayer.SampleHolder;
+import com.google.android.exoplayer.SampleSource;
+import com.google.android.exoplayer.TrackRenderer;
+import com.google.android.exoplayer.audio.AudioTrack;
+import com.google.android.exoplayer.util.Assertions;
+import com.google.android.exoplayer.util.MimeTypes;
+import com.android.tv.tuner.exoplayer.ffmpeg.FfmpegDecoderClient;
+import com.android.tv.tuner.tvinput.TunerDebug;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+
+/**
+ * Decodes and renders DTV audio. Supports MediaCodec based decoding, passthrough playback and
+ * ffmpeg based software decoding (AC3, MP2).
+ */
+public class MpegTsDefaultAudioTrackRenderer extends TrackRenderer implements MediaClock {
+ public static final int MSG_SET_VOLUME = 10000;
+ public static final int MSG_SET_AUDIO_TRACK = MSG_SET_VOLUME + 1;
+ public static final int MSG_SET_PLAYBACK_SPEED = MSG_SET_VOLUME + 2;
+
+ // ATSC/53 allows sample rate to be only 48Khz.
+ // One AC3 sample has 1536 frames, and its duration is 32ms.
+ public static final long AC3_SAMPLE_DURATION_US = 32000;
+
+ // TODO: Check whether DVB broadcasting uses sample rate other than 48Khz.
+ // MPEG-1 audio Layer II and III has 1152 frames per sample.
+ // 1152 frames duration is 24ms when sample rate is 48Khz.
+ static final long MP2_SAMPLE_DURATION_US = 24000;
+
+ // This is around 150ms, 150ms is big enough not to under-run AudioTrack,
+ // and 150ms is also small enough to fill the buffer rapidly.
+ static int BUFFERED_SAMPLES_IN_AUDIOTRACK = 5;
+ public static final long INITIAL_AUDIO_BUFFERING_TIME_US =
+ BUFFERED_SAMPLES_IN_AUDIOTRACK * AC3_SAMPLE_DURATION_US;
+
+
+ private static final String TAG = "MpegTsDefaultAudioTrac";
+ private static final boolean DEBUG = false;
+
+ /**
+ * Interface definition for a callback to be notified of
+ * {@link com.google.android.exoplayer.audio.AudioTrack} error.
+ */
+ public interface EventListener {
+ void onAudioTrackInitializationError(AudioTrack.InitializationException e);
+ void onAudioTrackWriteError(AudioTrack.WriteException e);
+ }
+
+ private static final int DEFAULT_INPUT_BUFFER_SIZE = 16384 * 2;
+ private static final int DEFAULT_OUTPUT_BUFFER_SIZE = 1024*1024;
+ private static final int MONITOR_DURATION_MS = 1000;
+ private static final int AC3_HEADER_BITRATE_OFFSET = 4;
+ private static final int MP2_HEADER_BITRATE_OFFSET = 2;
+ private static final int MP2_HEADER_BITRATE_MASK = 0xfc;
+
+ // Keep this as static in order to prevent new framework AudioTrack creation
+ // while old AudioTrack is being released.
+ private static final AudioTrackWrapper AUDIO_TRACK = new AudioTrackWrapper();
+ private static final long KEEP_ALIVE_AFTER_EOS_DURATION_MS = 3000;
+
+ // Ignore AudioTrack backward movement if duration of movement is below the threshold.
+ private static final long BACKWARD_AUDIO_TRACK_MOVE_THRESHOLD_US = 3000;
+
+ // AudioTrack position cannot go ahead beyond this limit.
+ private static final long CURRENT_POSITION_FROM_PTS_LIMIT_US = 1000000;
+
+ // Since MediaCodec processing and AudioTrack playing add delay,
+ // PTS interpolated time should be delayed reasonably when AudioTrack is not used.
+ private static final long ESTIMATED_TRACK_RENDERING_DELAY_US = 500000;
+
+ private final MediaCodecSelector mSelector;
+
+ private final CodecCounters mCodecCounters;
+ private final SampleSource.SampleSourceReader mSource;
+ private final MediaFormatHolder mFormatHolder;
+ private final EventListener mEventListener;
+ private final Handler mEventHandler;
+ private final AudioTrackMonitor mMonitor;
+ private final AudioClock mAudioClock;
+ private final boolean mAc3Passthrough;
+ private final boolean mSoftwareDecoderAvailable;
+
+ private MediaFormat mFormat;
+ private SampleHolder mSampleHolder;
+ private String mDecodingMime;
+ private boolean mFormatConfigured;
+ private int mSampleSize;
+ private final ByteBuffer mOutputBuffer;
+ private AudioDecoder mAudioDecoder;
+ private boolean mOutputReady;
+ private int mTrackIndex;
+ private boolean mSourceStateReady;
+ private boolean mInputStreamEnded;
+ private boolean mOutputStreamEnded;
+ private long mEndOfStreamMs;
+ private long mCurrentPositionUs;
+ private int mPresentationCount;
+ private long mPresentationTimeUs;
+ private long mInterpolatedTimeUs;
+ private long mPreviousPositionUs;
+ private boolean mIsStopped;
+ private boolean mEnabled = true;
+ private boolean mIsMuted;
+ private ArrayList<Integer> mTracksIndex;
+ private boolean mUseFrameworkDecoder;
+
+ public MpegTsDefaultAudioTrackRenderer(
+ SampleSource source,
+ MediaCodecSelector selector,
+ Handler eventHandler,
+ EventListener listener,
+ boolean hasSoftwareAudioDecoder,
+ boolean usePassthrough) {
+ mSource = source.register();
+ mSelector = selector;
+ mEventHandler = eventHandler;
+ mEventListener = listener;
+ mTrackIndex = -1;
+ mOutputBuffer = ByteBuffer.allocate(DEFAULT_OUTPUT_BUFFER_SIZE);
+ mFormatHolder = new MediaFormatHolder();
+ AUDIO_TRACK.restart();
+ mCodecCounters = new CodecCounters();
+ mMonitor = new AudioTrackMonitor();
+ mAudioClock = new AudioClock();
+ mTracksIndex = new ArrayList<>();
+ mAc3Passthrough = usePassthrough;
+ mSoftwareDecoderAvailable = hasSoftwareAudioDecoder && FfmpegDecoderClient.isAvailable();
+ }
+
+ @Override
+ protected MediaClock getMediaClock() {
+ return this;
+ }
+
+ private boolean handlesMimeType(String mimeType) {
+ return mimeType.equals(MimeTypes.AUDIO_AC3)
+ || mimeType.equals(MimeTypes.AUDIO_E_AC3)
+ || mimeType.equals(MimeTypes.AUDIO_MPEG_L2)
+ || MediaCodecAudioDecoder.supportMimeType(mSelector, mimeType);
+ }
+
+ @Override
+ protected boolean doPrepare(long positionUs) throws ExoPlaybackException {
+ boolean sourcePrepared = mSource.prepare(positionUs);
+ if (!sourcePrepared) {
+ return false;
+ }
+ for (int i = 0; i < mSource.getTrackCount(); i++) {
+ String mimeType = mSource.getFormat(i).mimeType;
+ if (MimeTypes.isAudio(mimeType) && handlesMimeType(mimeType)) {
+ if (mTrackIndex < 0) {
+ mTrackIndex = i;
+ }
+ mTracksIndex.add(i);
+ }
+ }
+
+ // TODO: Check this case. Source does not have the proper mime type.
+ return true;
+ }
+
+ @Override
+ protected int getTrackCount() {
+ return mTracksIndex.size();
+ }
+
+ @Override
+ protected MediaFormat getFormat(int track) {
+ Assertions.checkArgument(track >= 0 && track < mTracksIndex.size());
+ return mSource.getFormat(mTracksIndex.get(track));
+ }
+
+ @Override
+ protected void onEnabled(int track, long positionUs, boolean joining) {
+ Assertions.checkArgument(track >= 0 && track < mTracksIndex.size());
+ mTrackIndex = mTracksIndex.get(track);
+ mSource.enable(mTrackIndex, positionUs);
+ seekToInternal(positionUs);
+ }
+
+ @Override
+ protected void onDisabled() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+ AUDIO_TRACK.resetSessionId();
+ }
+ clearDecodeState();
+ mFormat = null;
+ mSource.disable(mTrackIndex);
+ }
+
+ @Override
+ protected void onReleased() {
+ releaseDecoder();
+ AUDIO_TRACK.release();
+ mSource.release();
+ }
+
+ @Override
+ protected boolean isEnded() {
+ return mOutputStreamEnded && AUDIO_TRACK.isEnded();
+ }
+
+ @Override
+ protected boolean isReady() {
+ return AUDIO_TRACK.isReady() || (mFormat != null && (mSourceStateReady || mOutputReady));
+ }
+
+ private void seekToInternal(long positionUs) {
+ mMonitor.reset(MONITOR_DURATION_MS);
+ mSourceStateReady = false;
+ mInputStreamEnded = false;
+ mOutputStreamEnded = false;
+ mPresentationTimeUs = positionUs;
+ mPresentationCount = 0;
+ mPreviousPositionUs = 0;
+ mCurrentPositionUs = Long.MIN_VALUE;
+ mInterpolatedTimeUs = Long.MIN_VALUE;
+ mAudioClock.setPositionUs(positionUs);
+ }
+
+ @Override
+ protected void seekTo(long positionUs) {
+ mSource.seekToUs(positionUs);
+ AUDIO_TRACK.reset();
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+ // resetSessionId() will create a new framework AudioTrack instead of reusing old one.
+ AUDIO_TRACK.resetSessionId();
+ }
+ seekToInternal(positionUs);
+ clearDecodeState();
+ }
+
+ @Override
+ protected void onStarted() {
+ AUDIO_TRACK.play();
+ mAudioClock.start();
+ mIsStopped = false;
+ }
+
+ @Override
+ protected void onStopped() {
+ AUDIO_TRACK.pause();
+ mAudioClock.stop();
+ mIsStopped = true;
+ }
+
+ @Override
+ protected void maybeThrowError() throws ExoPlaybackException {
+ try {
+ mSource.maybeThrowError();
+ } catch (IOException e) {
+ throw new ExoPlaybackException(e);
+ }
+ }
+
+ @Override
+ protected void doSomeWork(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
+ mMonitor.maybeLog();
+ try {
+ if (mEndOfStreamMs != 0) {
+ // Ensure playback stops, after EoS was notified.
+ // Sometimes MediaCodecTrackRenderer does not fetch EoS timely
+ // after EoS was notified here long before.
+ long diff = SystemClock.elapsedRealtime() - mEndOfStreamMs;
+ if (diff >= KEEP_ALIVE_AFTER_EOS_DURATION_MS && !mIsStopped) {
+ throw new ExoPlaybackException("Much time has elapsed after EoS");
+ }
+ }
+ boolean continueBuffering = mSource.continueBuffering(mTrackIndex, positionUs);
+ if (mSourceStateReady != continueBuffering) {
+ mSourceStateReady = continueBuffering;
+ if (DEBUG) {
+ Log.d(TAG, "mSourceStateReady: " + String.valueOf(mSourceStateReady));
+ }
+ }
+ long discontinuity = mSource.readDiscontinuity(mTrackIndex);
+ if (discontinuity != SampleSource.NO_DISCONTINUITY) {
+ AUDIO_TRACK.handleDiscontinuity();
+ mPresentationTimeUs = discontinuity;
+ mPresentationCount = 0;
+ clearDecodeState();
+ return;
+ }
+ if (mFormat == null) {
+ readFormat();
+ return;
+ }
+
+ if (mAudioDecoder != null) {
+ mAudioDecoder.maybeInitDecoder(mFormat);
+ }
+ // Process only one sample at a time for doSomeWork() when using FFmpeg decoder.
+ if (processOutput()) {
+ if (!mOutputReady) {
+ while (feedInputBuffer()) {
+ if (mOutputReady) break;
+ }
+ }
+ }
+ mCodecCounters.ensureUpdated();
+ } catch (IOException e) {
+ throw new ExoPlaybackException(e);
+ }
+ }
+
+ private void ensureAudioTrackInitialized() {
+ if (!AUDIO_TRACK.isInitialized()) {
+ try {
+ if (DEBUG) {
+ Log.d(TAG, "AudioTrack initialized");
+ }
+ AUDIO_TRACK.initialize();
+ } catch (AudioTrack.InitializationException e) {
+ Log.e(TAG, "Error on AudioTrack initialization", e);
+ notifyAudioTrackInitializationError(e);
+
+ // Do not throw exception here but just disabling audioTrack to keep playing
+ // video without audio.
+ AUDIO_TRACK.setStatus(false);
+ }
+ if (getState() == TrackRenderer.STATE_STARTED) {
+ if (DEBUG) {
+ Log.d(TAG, "AudioTrack played");
+ }
+ AUDIO_TRACK.play();
+ }
+ }
+ }
+
+ private void clearDecodeState() {
+ mOutputReady = false;
+ if (mAudioDecoder != null) {
+ mAudioDecoder.resetDecoderState(mDecodingMime);
+ }
+ AUDIO_TRACK.reset();
+ }
+
+ private void releaseDecoder() {
+ if (mAudioDecoder != null) {
+ mAudioDecoder.release();
+ }
+ }
+
+ private void readFormat() throws IOException, ExoPlaybackException {
+ int result = mSource.readData(mTrackIndex, mCurrentPositionUs,
+ mFormatHolder, mSampleHolder);
+ if (result == SampleSource.FORMAT_READ) {
+ onInputFormatChanged(mFormatHolder);
+ }
+ }
+
+ private MediaFormat convertMediaFormatToRaw(MediaFormat format) {
+ return MediaFormat.createAudioFormat(
+ format.trackId,
+ MimeTypes.AUDIO_RAW,
+ format.bitrate,
+ format.maxInputSize,
+ format.durationUs,
+ format.channelCount,
+ format.sampleRate,
+ format.initializationData,
+ format.language);
+ }
+
+ private void onInputFormatChanged(MediaFormatHolder formatHolder)
+ throws ExoPlaybackException {
+ String mimeType = formatHolder.format.mimeType;
+ mUseFrameworkDecoder = MediaCodecAudioDecoder.supportMimeType(mSelector, mimeType);
+ if (mUseFrameworkDecoder) {
+ mAudioDecoder = new MediaCodecAudioDecoder(mSelector);
+ mFormat = formatHolder.format;
+ mAudioDecoder.maybeInitDecoder(mFormat);
+ mSampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_DISABLED);
+ } else if (mSoftwareDecoderAvailable
+ && (MimeTypes.AUDIO_MPEG_L2.equalsIgnoreCase(mimeType)
+ || MimeTypes.AUDIO_AC3.equalsIgnoreCase(mimeType) && !mAc3Passthrough)) {
+ releaseDecoder();
+ mSampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_DIRECT);
+ mSampleHolder.ensureSpaceForWrite(DEFAULT_INPUT_BUFFER_SIZE);
+ mAudioDecoder = FfmpegDecoderClient.getInstance();
+ mDecodingMime = mimeType;
+ mFormat = convertMediaFormatToRaw(formatHolder.format);
+ } else {
+ mSampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_DIRECT);
+ mSampleHolder.ensureSpaceForWrite(DEFAULT_INPUT_BUFFER_SIZE);
+ mFormat = formatHolder.format;
+ releaseDecoder();
+ }
+ mFormatConfigured = true;
+ mMonitor.setEncoding(mimeType);
+ if (DEBUG && !mUseFrameworkDecoder) {
+ Log.d(TAG, "AudioTrack was configured to FORMAT: " + mFormat.toString());
+ }
+ clearDecodeState();
+ if (!mUseFrameworkDecoder) {
+ AUDIO_TRACK.reconfigure(mFormat.getFrameworkMediaFormatV16(), 0);
+ }
+ }
+
+ private void onSampleSizeChanged(int sampleSize) {
+ if (DEBUG) {
+ Log.d(TAG, "Sample size was changed to : " + sampleSize);
+ }
+ clearDecodeState();
+ int audioBufferSize = sampleSize * BUFFERED_SAMPLES_IN_AUDIOTRACK;
+ mSampleSize = sampleSize;
+ AUDIO_TRACK.reconfigure(mFormat.getFrameworkMediaFormatV16(), audioBufferSize);
+ }
+
+ private void onOutputFormatChanged(android.media.MediaFormat format) {
+ if (DEBUG) {
+ Log.d(TAG, "AudioTrack was configured to FORMAT: " + format.toString());
+ }
+ AUDIO_TRACK.reconfigure(format, 0);
+ }
+
+ private boolean feedInputBuffer() throws IOException, ExoPlaybackException {
+ if (mInputStreamEnded) {
+ return false;
+ }
+
+ if (mUseFrameworkDecoder) {
+ boolean indexChanged =
+ ((MediaCodecAudioDecoder) mAudioDecoder).getInputIndex()
+ == MediaCodecAudioDecoder.INDEX_INVALID;
+ if (indexChanged) {
+ mSampleHolder.data = mAudioDecoder.getInputBuffer();
+ if (mSampleHolder.data != null) {
+ mSampleHolder.clearData();
+ } else {
+ return false;
+ }
+ }
+ } else {
+ mSampleHolder.data.clear();
+ mSampleHolder.size = 0;
+ }
+ int result =
+ mSource.readData(mTrackIndex, mPresentationTimeUs, mFormatHolder, mSampleHolder);
+ switch (result) {
+ case SampleSource.NOTHING_READ: {
+ return false;
+ }
+ case SampleSource.FORMAT_READ: {
+ Log.i(TAG, "Format was read again");
+ onInputFormatChanged(mFormatHolder);
+ return true;
+ }
+ case SampleSource.END_OF_STREAM: {
+ Log.i(TAG, "End of stream from SampleSource");
+ mInputStreamEnded = true;
+ return false;
+ }
+ default: {
+ if (mSampleHolder.size != mSampleSize
+ && mFormatConfigured
+ && !mUseFrameworkDecoder) {
+ onSampleSizeChanged(mSampleHolder.size);
+ }
+ mSampleHolder.data.flip();
+ if (!mUseFrameworkDecoder) {
+ if (MimeTypes.AUDIO_MPEG_L2.equalsIgnoreCase(mDecodingMime)) {
+ mMonitor.addPts(
+ mSampleHolder.timeUs,
+ mOutputBuffer.position(),
+ mSampleHolder.data.get(MP2_HEADER_BITRATE_OFFSET)
+ & MP2_HEADER_BITRATE_MASK);
+ } else {
+ mMonitor.addPts(
+ mSampleHolder.timeUs,
+ mOutputBuffer.position(),
+ mSampleHolder.data.get(AC3_HEADER_BITRATE_OFFSET) & 0xff);
+ }
+ }
+ if (mAudioDecoder != null) {
+ mAudioDecoder.decode(mSampleHolder);
+ if (mUseFrameworkDecoder) {
+ int outputIndex =
+ ((MediaCodecAudioDecoder) mAudioDecoder).getOutputIndex();
+ if (outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+ onOutputFormatChanged(mAudioDecoder.getOutputFormat());
+ return true;
+ } else if (outputIndex < 0) {
+ return true;
+ }
+ if (((MediaCodecAudioDecoder) mAudioDecoder).maybeDecodeOnlyIndex()) {
+ AUDIO_TRACK.handleDiscontinuity();
+ return true;
+ }
+ }
+ ByteBuffer outputBuffer = mAudioDecoder.getDecodedSample();
+ long presentationTimeUs = mAudioDecoder.getDecodedTimeUs();
+ decodeDone(outputBuffer, presentationTimeUs);
+ } else {
+ decodeDone(mSampleHolder.data, mSampleHolder.timeUs);
+ }
+ return true;
+ }
+ }
+ }
+
+ private boolean processOutput() throws ExoPlaybackException {
+ if (mOutputStreamEnded) {
+ return false;
+ }
+ if (!mOutputReady) {
+ if (mInputStreamEnded) {
+ mOutputStreamEnded = true;
+ mEndOfStreamMs = SystemClock.elapsedRealtime();
+ return false;
+ }
+ return true;
+ }
+
+ ensureAudioTrackInitialized();
+ int handleBufferResult;
+ try {
+ // To reduce discontinuity, interpolate presentation time.
+ if (MimeTypes.AUDIO_MPEG_L2.equalsIgnoreCase(mDecodingMime)) {
+ mInterpolatedTimeUs = mPresentationTimeUs
+ + mPresentationCount * MP2_SAMPLE_DURATION_US;
+ } else if (!mUseFrameworkDecoder) {
+ mInterpolatedTimeUs = mPresentationTimeUs
+ + mPresentationCount * AC3_SAMPLE_DURATION_US;
+ } else {
+ mInterpolatedTimeUs = mPresentationTimeUs;
+ }
+ handleBufferResult =
+ AUDIO_TRACK.handleBuffer(
+ mOutputBuffer, 0, mOutputBuffer.limit(), mInterpolatedTimeUs);
+ } catch (AudioTrack.WriteException e) {
+ notifyAudioTrackWriteError(e);
+ throw new ExoPlaybackException(e);
+ }
+ if ((handleBufferResult & AudioTrack.RESULT_POSITION_DISCONTINUITY) != 0) {
+ Log.i(TAG, "Play discontinuity happened");
+ mCurrentPositionUs = Long.MIN_VALUE;
+ }
+ if ((handleBufferResult & AudioTrack.RESULT_BUFFER_CONSUMED) != 0) {
+ mCodecCounters.renderedOutputBufferCount++;
+ mOutputReady = false;
+ if (mUseFrameworkDecoder) {
+ ((MediaCodecAudioDecoder) mAudioDecoder).releaseOutputBuffer();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected long getDurationUs() {
+ return mSource.getFormat(mTrackIndex).durationUs;
+ }
+
+ @Override
+ protected long getBufferedPositionUs() {
+ long pos = mSource.getBufferedPositionUs();
+ return pos == UNKNOWN_TIME_US || pos == END_OF_TRACK_US
+ ? pos : Math.max(pos, getPositionUs());
+ }
+
+ @Override
+ public long getPositionUs() {
+ if (!AUDIO_TRACK.isInitialized()) {
+ return mAudioClock.getPositionUs();
+ } else if (!AUDIO_TRACK.isEnabled()) {
+ if (mInterpolatedTimeUs > 0 && !mUseFrameworkDecoder) {
+ return mInterpolatedTimeUs - ESTIMATED_TRACK_RENDERING_DELAY_US;
+ }
+ return mPresentationTimeUs;
+ }
+ long audioTrackCurrentPositionUs = AUDIO_TRACK.getCurrentPositionUs(isEnded());
+ if (audioTrackCurrentPositionUs == AudioTrack.CURRENT_POSITION_NOT_SET) {
+ mPreviousPositionUs = 0L;
+ if (DEBUG) {
+ long oldPositionUs = Math.max(mCurrentPositionUs, 0);
+ long currentPositionUs = Math.max(mPresentationTimeUs, mCurrentPositionUs);
+ Log.d(TAG, "Audio position is not set, diff in us: "
+ + String.valueOf(currentPositionUs - oldPositionUs));
+ }
+ mCurrentPositionUs = Math.max(mPresentationTimeUs, mCurrentPositionUs);
+ } else {
+ if (mPreviousPositionUs
+ > audioTrackCurrentPositionUs + BACKWARD_AUDIO_TRACK_MOVE_THRESHOLD_US) {
+ Log.e(TAG, "audio_position BACK JUMP: "
+ + (mPreviousPositionUs - audioTrackCurrentPositionUs));
+ mCurrentPositionUs = audioTrackCurrentPositionUs;
+ } else {
+ mCurrentPositionUs = Math.max(mCurrentPositionUs, audioTrackCurrentPositionUs);
+ }
+ mPreviousPositionUs = audioTrackCurrentPositionUs;
+ }
+ long upperBound = mPresentationTimeUs + CURRENT_POSITION_FROM_PTS_LIMIT_US;
+ if (mCurrentPositionUs > upperBound) {
+ mCurrentPositionUs = upperBound;
+ }
+ return mCurrentPositionUs;
+ }
+
+ private void decodeDone(ByteBuffer outputBuffer, long presentationTimeUs) {
+ if (outputBuffer == null || mOutputBuffer == null) {
+ return;
+ }
+ if (presentationTimeUs < 0) {
+ Log.e(TAG, "decodeDone - invalid presentationTimeUs");
+ return;
+ }
+
+ if (TunerDebug.ENABLED) {
+ TunerDebug.setAudioPtsUs(presentationTimeUs);
+ }
+
+ mOutputBuffer.clear();
+ Assertions.checkState(mOutputBuffer.remaining() >= outputBuffer.limit());
+
+ mOutputBuffer.put(outputBuffer);
+ if (presentationTimeUs == mPresentationTimeUs) {
+ mPresentationCount++;
+ } else {
+ mPresentationCount = 0;
+ mPresentationTimeUs = presentationTimeUs;
+ }
+ mOutputBuffer.flip();
+ mOutputReady = true;
+ }
+
+ private void notifyAudioTrackInitializationError(final AudioTrack.InitializationException e) {
+ if (mEventHandler == null || mEventListener == null) {
+ return;
+ }
+ mEventHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mEventListener.onAudioTrackInitializationError(e);
+ }
+ });
+ }
+
+ private void notifyAudioTrackWriteError(final AudioTrack.WriteException e) {
+ if (mEventHandler == null || mEventListener == null) {
+ return;
+ }
+ mEventHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mEventListener.onAudioTrackWriteError(e);
+ }
+ });
+ }
+
+ @Override
+ public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
+ switch (messageType) {
+ case MSG_SET_VOLUME:
+ float volume = (Float) message;
+ // Workaround: we cannot mute the audio track by setting the volume to 0, we need to
+ // disable the AUDIO_TRACK for this intent. However, enabling/disabling audio track
+ // whenever volume is being set might cause side effects, therefore we only handle
+ // "explicit mute operations", i.e., only after certain non-zero volume has been
+ // set, the subsequent volume setting operations will be consider as mute/un-mute
+ // operations and thus enable/disable the audio track.
+ if (mIsMuted && volume > 0) {
+ mIsMuted = false;
+ if (mEnabled) {
+ setStatus(true);
+ }
+ } else if (!mIsMuted && volume == 0) {
+ mIsMuted = true;
+ if (mEnabled) {
+ setStatus(false);
+ }
+ }
+ AUDIO_TRACK.setVolume(volume);
+ break;
+ case MSG_SET_AUDIO_TRACK:
+ mEnabled = (Integer) message == 1;
+ setStatus(mEnabled);
+ break;
+ case MSG_SET_PLAYBACK_SPEED:
+ mAudioClock.setPlaybackSpeed((Float) message);
+ break;
+ default:
+ super.handleMessage(messageType, message);
+ }
+ }
+
+ private void setStatus(boolean enabled) {
+ if (enabled == AUDIO_TRACK.isEnabled()) {
+ return;
+ }
+ if (!enabled) {
+ // mAudioClock can be different from getPositionUs. In order to sync them,
+ // we set mAudioClock.
+ mAudioClock.setPositionUs(getPositionUs());
+ }
+ AUDIO_TRACK.setStatus(enabled);
+ if (enabled) {
+ // When AUDIO_TRACK is enabled, we need to clear AUDIO_TRACK and seek to
+ // the current position. If not, AUDIO_TRACK has the obsolete data.
+ seekTo(mAudioClock.getPositionUs());
+ }
+ }
+}
diff --git a/src/com/android/tv/tuner/exoplayer/audio/MpegTsMediaCodecAudioTrackRenderer.java b/src/com/android/tv/tuner/exoplayer/audio/MpegTsMediaCodecAudioTrackRenderer.java
new file mode 100644
index 00000000..142aa9b2
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/audio/MpegTsMediaCodecAudioTrackRenderer.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2016 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.tv.tuner.exoplayer.audio;
+
+import android.os.Handler;
+
+import com.google.android.exoplayer.ExoPlaybackException;
+import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
+import com.google.android.exoplayer.MediaCodecSelector;
+import com.google.android.exoplayer.SampleSource;
+
+/**
+ * MPEG-2 TS audio track renderer.
+ *
+ * <p>Since the audio output from {@link android.media.MediaExtractor} contains extra samples at the
+ * beginning, using original {@link MediaCodecAudioTrackRenderer} as audio renderer causes
+ * asynchronous Audio/Video outputs. This class calculates the offset of audio data and adjust the
+ * presentation times to avoid the asynchronous Audio/Video problem.
+ */
+public class MpegTsMediaCodecAudioTrackRenderer extends MediaCodecAudioTrackRenderer {
+ private final Ac3EventListener mListener;
+
+ public interface Ac3EventListener extends EventListener {
+ /**
+ * Invoked when a {@link android.media.PlaybackParams} set to an
+ * {@link android.media.AudioTrack} is not valid.
+ *
+ * @param e The corresponding exception.
+ */
+ void onAudioTrackSetPlaybackParamsError(IllegalArgumentException e);
+ }
+
+ public MpegTsMediaCodecAudioTrackRenderer(
+ SampleSource source,
+ MediaCodecSelector mediaCodecSelector,
+ Handler eventHandler,
+ EventListener eventListener) {
+ super(source, mediaCodecSelector, eventHandler, eventListener);
+ mListener = (Ac3EventListener) eventListener;
+ }
+
+ @Override
+ public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
+ if (messageType == MSG_SET_PLAYBACK_PARAMS) {
+ try {
+ super.handleMessage(messageType, message);
+ } catch (IllegalArgumentException e) {
+ if (isAudioTrackSetPlaybackParamsError(e)) {
+ notifyAudioTrackSetPlaybackParamsError(e);
+ }
+ }
+ return;
+ }
+ super.handleMessage(messageType, message);
+ }
+
+ private void notifyAudioTrackSetPlaybackParamsError(final IllegalArgumentException e) {
+ if (eventHandler != null && mListener != null) {
+ eventHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onAudioTrackSetPlaybackParamsError(e);
+ }
+ });
+ }
+ }
+
+ static private boolean isAudioTrackSetPlaybackParamsError(IllegalArgumentException e) {
+ if (e.getStackTrace() == null || e.getStackTrace().length < 1) {
+ return false;
+ }
+ for (StackTraceElement element : e.getStackTrace()) {
+ String elementString = element.toString();
+ if (elementString.startsWith("android.media.AudioTrack.setPlaybackParams")) {
+ return true;
+ }
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/tuner/exoplayer/buffer/BufferManager.java b/src/com/android/tv/tuner/exoplayer/buffer/BufferManager.java
index eb596e93..112e9dc4 100644
--- a/src/com/android/tv/tuner/exoplayer/buffer/BufferManager.java
+++ b/src/com/android/tv/tuner/exoplayer/buffer/BufferManager.java
@@ -25,13 +25,14 @@ import android.util.Log;
import android.util.Pair;
import com.google.android.exoplayer.SampleHolder;
+import com.android.tv.common.SoftPreconditions;
import com.android.tv.tuner.exoplayer.SampleExtractor;
import com.android.tv.util.Utils;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
@@ -59,7 +60,8 @@ public class BufferManager {
private final SampleChunk.SampleChunkCreator mSampleChunkCreator;
// Maps from track name to a map which maps from starting position to {@link SampleChunk}.
- private final Map<String, SortedMap<Long, SampleChunk>> mChunkMap = new ArrayMap<>();
+ private final Map<String, SortedMap<Long, Pair<SampleChunk, Integer>>> mChunkMap =
+ new ArrayMap<>();
private final Map<String, Long> mStartPositionMap = new ArrayMap<>();
private final Map<String, ChunkEvictedListener> mEvictListeners = new ArrayMap<>();
private final StorageManager mStorageManager;
@@ -77,13 +79,11 @@ public class BufferManager {
}
};
- private volatile boolean mClosed = false;
private int mMinSampleSizeForSpeedCheck = MINIMUM_SAMPLE_SIZE_FOR_SPEED_CHECK;
private long mTotalWriteSize;
private long mTotalWriteTimeNs;
private float mWriteBandwidth = 0.0f;
private volatile int mSpeedCheckCount;
- private boolean mDisabled = false;
public interface ChunkEvictedListener {
void onChunkEvicted(String id, long createdTimeMs);
@@ -174,6 +174,66 @@ public class BufferManager {
}
/**
+ * A Track format which will be loaded and saved from the permanent storage for recordings.
+ */
+ public static class TrackFormat {
+
+ /**
+ * The track id for the specified track. The track id will be used as a track identifier
+ * for recordings.
+ */
+ public final String trackId;
+
+ /**
+ * The {@link MediaFormat} for the specified track.
+ */
+ public final MediaFormat format;
+
+ /**
+ * Creates TrackFormat.
+ * @param trackId
+ * @param format
+ */
+ public TrackFormat(String trackId, MediaFormat format) {
+ this.trackId = trackId;
+ this.format = format;
+ }
+ }
+
+ /**
+ * A Holder for a sample position which will be loaded from the index file for recordings.
+ */
+ public static class PositionHolder {
+
+ /**
+ * The current sample position in microseconds.
+ * The position is identical to the PTS(presentation time stamp) of the sample.
+ */
+ public final long positionUs;
+
+ /**
+ * Base sample position for the current {@link SampleChunk}.
+ */
+ public final long basePositionUs;
+
+ /**
+ * The file offset for the current sample in the current {@link SampleChunk}.
+ */
+ public final int offset;
+
+ /**
+ * Creates a holder for a specific position in the recording.
+ * @param positionUs
+ * @param offset
+ */
+ public PositionHolder(long positionUs, long basePositionUs, int offset) {
+ this.positionUs = positionUs;
+ this.basePositionUs = basePositionUs;
+ this.offset = offset;
+ }
+ }
+
+ /**
* Storage configuration and policy manager for {@link BufferManager}
*/
public interface StorageManager {
@@ -186,11 +246,6 @@ public class BufferManager {
File getBufferDir();
/**
- * Cleans up storage.
- */
- void clearStorage();
-
- /**
* Informs whether the storage is used for persistent use. (eg. dvr recording/play)
*
* @return {@code true} if stored files are persistent
@@ -220,29 +275,27 @@ public class BufferManager {
* Reads track name & {@link MediaFormat} from storage.
*
* @param isAudio {@code true} if it is for audio track
- * @return {@link Pair} of track name & {@link MediaFormat}
- * @throws IOException
+ * @return {@link List} of TrackFormat
*/
- Pair<String, MediaFormat> readTrackInfoFile(boolean isAudio) throws IOException;
+ List<TrackFormat> readTrackInfoFiles(boolean isAudio);
/**
- * Reads sample indexes for each written sample from storage.
+ * Reads key sample positions for each written sample from storage.
*
* @param trackId track name
* @return indexes of the specified track
* @throws IOException
*/
- ArrayList<Long> readIndexFile(String trackId) throws IOException;
+ ArrayList<PositionHolder> readIndexFile(String trackId) throws IOException;
/**
* Writes track information to storage.
*
- * @param trackId track name
- * @param format {@link android.media.MediaFormat} of the track
+ * @param formatList {@list List} of TrackFormat
* @param isAudio {@code true} if it is for audio track
* @throws IOException
*/
- void writeTrackInfoFile(String trackId, MediaFormat format, boolean isAudio)
+ void writeTrackInfoFiles(List<TrackFormat> formatList, boolean isAudio)
throws IOException;
/**
@@ -252,7 +305,7 @@ public class BufferManager {
* @param index {@link SampleChunk} container
* @throws IOException
*/
- void writeIndexFile(String trackName, SortedMap<Long, SampleChunk> index)
+ void writeIndexFile(String trackName, SortedMap<Long, Pair<SampleChunk, Integer>> index)
throws IOException;
}
@@ -307,7 +360,6 @@ public class BufferManager {
SampleChunk.SampleChunkCreator sampleChunkCreator) {
mStorageManager = storageManager;
mSampleChunkCreator = sampleChunkCreator;
- clearBuffer(true);
}
public void registerChunkEvictedListener(String id, ChunkEvictedListener listener) {
@@ -318,44 +370,44 @@ public class BufferManager {
mEvictListeners.remove(id);
}
- private void clearBuffer(boolean deleteFiles) {
- mChunkMap.clear();
- if (deleteFiles) {
- mStorageManager.clearStorage();
- }
- mBufferSize = 0;
- }
-
private static String getFileName(String id, long positionUs) {
return String.format(Locale.ENGLISH, "%s_%016x.chunk", id, positionUs);
}
/**
- * Creates a new {@link SampleChunk} for caching samples.
+ * Creates a new {@link SampleChunk} for caching samples if it is needed.
*
* @param id the name of the track
- * @param positionUs starting position of the {@link SampleChunk} in micro seconds.
+ * @param positionUs current position to write a sample in micro seconds.
* @param samplePool {@link SamplePool} for the fast creation of samples.
+ * @param currentChunk the current {@link SampleChunk} to write, {@code null} when to create
+ * a new {@link SampleChunk}.
+ * @param currentOffset the current offset to write.
* @return returns the created {@link SampleChunk}.
* @throws IOException
*/
- public SampleChunk createNewWriteFile(String id, long positionUs,
- SamplePool samplePool) throws IOException {
+ public SampleChunk createNewWriteFileIfNeeded(String id, long positionUs, SamplePool samplePool,
+ SampleChunk currentChunk, int currentOffset) throws IOException {
if (!maybeEvictChunk()) {
throw new IOException("Not enough storage space");
}
- SortedMap<Long, SampleChunk> map = mChunkMap.get(id);
+ SortedMap<Long, Pair<SampleChunk, Integer>> map = mChunkMap.get(id);
if (map == null) {
map = new TreeMap<>();
mChunkMap.put(id, map);
mStartPositionMap.put(id, positionUs);
mPendingDelete.init(id);
}
- File file = new File(mStorageManager.getBufferDir(), getFileName(id, positionUs));
- SampleChunk sampleChunk = mSampleChunkCreator.createSampleChunk(samplePool, file,
- positionUs, mChunkCallback);
- map.put(positionUs, sampleChunk);
- return sampleChunk;
+ if (currentChunk == null) {
+ File file = new File(mStorageManager.getBufferDir(), getFileName(id, positionUs));
+ SampleChunk sampleChunk = mSampleChunkCreator
+ .createSampleChunk(samplePool, file, positionUs, mChunkCallback);
+ map.put(positionUs, new Pair(sampleChunk, 0));
+ return sampleChunk;
+ } else {
+ map.put(positionUs, new Pair(currentChunk, currentOffset));
+ return null;
+ }
}
/**
@@ -366,10 +418,10 @@ public class BufferManager {
* @throws IOException
*/
public void loadTrackFromStorage(String trackId, SamplePool samplePool) throws IOException {
- ArrayList<Long> keyPositions = mStorageManager.readIndexFile(trackId);
- long startPositionUs = keyPositions.size() > 0 ? keyPositions.get(0) : 0;
+ ArrayList<PositionHolder> keyPositions = mStorageManager.readIndexFile(trackId);
+ long startPositionUs = keyPositions.size() > 0 ? keyPositions.get(0).positionUs : 0;
- SortedMap<Long, SampleChunk> map = mChunkMap.get(trackId);
+ SortedMap<Long, Pair<SampleChunk, Integer>> map = mChunkMap.get(trackId);
if (map == null) {
map = new TreeMap<>();
mChunkMap.put(trackId, map);
@@ -377,11 +429,15 @@ public class BufferManager {
mPendingDelete.init(trackId);
}
SampleChunk chunk = null;
- for (long positionUs: keyPositions) {
- chunk = mSampleChunkCreator.loadSampleChunkFromFile(samplePool,
- mStorageManager.getBufferDir(), getFileName(trackId, positionUs), positionUs,
- mChunkCallback, chunk);
- map.put(positionUs, chunk);
+ long basePositionUs = -1;
+ for (PositionHolder position: keyPositions) {
+ if (position.basePositionUs != basePositionUs) {
+ chunk = mSampleChunkCreator.loadSampleChunkFromFile(samplePool,
+ mStorageManager.getBufferDir(), getFileName(trackId, position.positionUs),
+ position.positionUs, mChunkCallback, chunk);
+ basePositionUs = position.basePositionUs;
+ }
+ map.put(position.positionUs, new Pair(chunk, position.offset));
}
}
@@ -392,19 +448,19 @@ public class BufferManager {
* @param positionUs the position.
* @return returns the found {@link SampleChunk}.
*/
- public SampleChunk getReadFile(String id, long positionUs) {
- SortedMap<Long, SampleChunk> map = mChunkMap.get(id);
+ public Pair<SampleChunk, Integer> getReadFile(String id, long positionUs) {
+ SortedMap<Long, Pair<SampleChunk, Integer>> map = mChunkMap.get(id);
if (map == null) {
return null;
}
- SampleChunk sampleChunk;
- SortedMap<Long, SampleChunk> headMap = map.headMap(positionUs + 1);
+ Pair<SampleChunk, Integer> ret;
+ SortedMap<Long, Pair<SampleChunk, Integer>> headMap = map.headMap(positionUs + 1);
if (!headMap.isEmpty()) {
- sampleChunk = headMap.get(headMap.lastKey());
+ ret = headMap.get(headMap.lastKey());
} else {
- sampleChunk = map.get(map.firstKey());
+ ret = map.get(map.firstKey());
}
- return sampleChunk;
+ return ret;
}
/**
@@ -439,15 +495,16 @@ public class BufferManager {
// Since chunks are persistent, we cannot evict chunks.
return false;
}
- SortedMap<Long, SampleChunk> earliestChunkMap = null;
+ SortedMap<Long, Pair<SampleChunk, Integer>> earliestChunkMap = null;
SampleChunk earliestChunk = null;
String earliestChunkId = null;
- for (Map.Entry<String, SortedMap<Long, SampleChunk>> entry : mChunkMap.entrySet()) {
- SortedMap<Long, SampleChunk> map = entry.getValue();
+ for (Map.Entry<String, SortedMap<Long, Pair<SampleChunk, Integer>>> entry :
+ mChunkMap.entrySet()) {
+ SortedMap<Long, Pair<SampleChunk, Integer>> map = entry.getValue();
if (map.isEmpty()) {
continue;
}
- SampleChunk chunk = map.get(map.firstKey());
+ SampleChunk chunk = map.get(map.firstKey()).first;
if (earliestChunk == null
|| chunk.getCreatedTimeMs() < earliestChunk.getCreatedTimeMs()) {
earliestChunkMap = map;
@@ -473,8 +530,9 @@ public class BufferManager {
}
pendingDelete = mPendingDelete.getSize();
}
- for (Map.Entry<String, SortedMap<Long, SampleChunk>> entry : mChunkMap.entrySet()) {
- SortedMap<Long, SampleChunk> map = entry.getValue();
+ for (Map.Entry<String, SortedMap<Long, Pair<SampleChunk, Integer>>> entry :
+ mChunkMap.entrySet()) {
+ SortedMap<Long, Pair<SampleChunk, Integer>> map = entry.getValue();
if (map.isEmpty()) {
continue;
}
@@ -489,70 +547,74 @@ public class BufferManager {
* @return returns all track information which is found by {@link BufferManager.StorageManager}.
* @throws IOException
*/
- public ArrayList<Pair<String, MediaFormat>> readTrackInfoFiles() throws IOException {
- ArrayList<Pair<String, MediaFormat>> trackInfos = new ArrayList<>();
- try {
- trackInfos.add(mStorageManager.readTrackInfoFile(false));
- } catch (FileNotFoundException e) {
- // There can be a single track only recording. (eg. audio-only, video-only)
- // So the exception should not stop the read.
+ public List<TrackFormat> readTrackInfoFiles() throws IOException {
+ List<TrackFormat> trackFormatList = new ArrayList<>();
+ trackFormatList.addAll(mStorageManager.readTrackInfoFiles(false));
+ trackFormatList.addAll(mStorageManager.readTrackInfoFiles(true));
+ if (trackFormatList.isEmpty()) {
+ throw new IOException("No track information to load");
}
- try {
- trackInfos.add(mStorageManager.readTrackInfoFile(true));
- } catch (FileNotFoundException e) {
- // See above catch block.
- }
- return trackInfos;
+ return trackFormatList;
}
/**
* Writes track information and index information for all tracks.
*
- * @param audio audio information.
- * @param video video information.
+ * @param audios list of audio track information
+ * @param videos list of audio track information
* @throws IOException
*/
- public void writeMetaFiles(Pair<String, MediaFormat> audio, Pair<String, MediaFormat> video)
+ public void writeMetaFiles(List<TrackFormat> audios, List<TrackFormat> videos)
throws IOException {
- if (audio != null) {
- mStorageManager.writeTrackInfoFile(audio.first, audio.second, true);
- SortedMap<Long, SampleChunk> map = mChunkMap.get(audio.first);
- if (map == null) {
- throw new IOException("Audio track index missing");
+ if (audios.isEmpty() && videos.isEmpty()) {
+ throw new IOException("No track information to save");
+ }
+ if (!audios.isEmpty()) {
+ mStorageManager.writeTrackInfoFiles(audios, true);
+ for (TrackFormat trackFormat : audios) {
+ SortedMap<Long, Pair<SampleChunk, Integer>> map =
+ mChunkMap.get(trackFormat.trackId);
+ if (map == null) {
+ throw new IOException("Audio track index missing");
+ }
+ mStorageManager.writeIndexFile(trackFormat.trackId, map);
}
- mStorageManager.writeIndexFile(audio.first, map);
}
- if (video != null) {
- mStorageManager.writeTrackInfoFile(video.first, video.second, false);
- SortedMap<Long, SampleChunk> map = mChunkMap.get(video.first);
- if (map == null) {
- throw new IOException("Video track index missing");
+ if (!videos.isEmpty()) {
+ mStorageManager.writeTrackInfoFiles(videos, false);
+ for (TrackFormat trackFormat : videos) {
+ SortedMap<Long, Pair<SampleChunk, Integer>> map =
+ mChunkMap.get(trackFormat.trackId);
+ if (map == null) {
+ throw new IOException("Video track index missing");
+ }
+ mStorageManager.writeIndexFile(trackFormat.trackId, map);
}
- mStorageManager.writeIndexFile(video.first, map);
}
}
/**
- * Marks it is closed and it is not used anymore.
- */
- public void close() {
- // Clean-up may happen after this is called.
- mClosed = true;
- }
-
- /**
* Releases all the resources.
*/
public void release() {
- mPendingDelete.release();
- for (Map.Entry<String, SortedMap<Long, SampleChunk>> entry : mChunkMap.entrySet()) {
- for (SampleChunk chunk : entry.getValue().values()) {
- SampleChunk.IoState.release(chunk, !mStorageManager.isPersistent());
+ try {
+ mPendingDelete.release();
+ for (Map.Entry<String, SortedMap<Long, Pair<SampleChunk, Integer>>> entry :
+ mChunkMap.entrySet()) {
+ SampleChunk toRelease = null;
+ for (Pair<SampleChunk, Integer> positions : entry.getValue().values()) {
+ if (toRelease != positions.first) {
+ toRelease = positions.first;
+ SampleChunk.IoState.release(toRelease, !mStorageManager.isPersistent());
+ }
+ }
}
- }
- mChunkMap.clear();
- if (mClosed) {
- clearBuffer(!mStorageManager.isPersistent());
+ mChunkMap.clear();
+ } catch (ConcurrentModificationException | NullPointerException e) {
+ // TODO: remove this after it it confirmed that race condition issues are resolved.
+ // b/32492258, b/32373376
+ SoftPreconditions.checkState(false, "Exception on BufferManager#release: ",
+ e.toString());
}
}
@@ -611,20 +673,6 @@ public class BufferManager {
}
/**
- * Marks {@link BufferManager} object disabled to prevent it from the future use.
- */
- public void disable() {
- mDisabled = true;
- }
-
- /**
- * Returns if {@link BufferManager} object is disabled.
- */
- public boolean isDisabled() {
- return mDisabled;
- }
-
- /**
* Returns if {@link BufferManager} has checked the write speed,
* which is suitable for Trickplay.
*/
diff --git a/src/com/android/tv/tuner/exoplayer/buffer/DvrStorageManager.java b/src/com/android/tv/tuner/exoplayer/buffer/DvrStorageManager.java
index 6a0502a7..6a09016c 100644
--- a/src/com/android/tv/tuner/exoplayer/buffer/DvrStorageManager.java
+++ b/src/com/android/tv/tuner/exoplayer/buffer/DvrStorageManager.java
@@ -17,8 +17,12 @@
package com.android.tv.tuner.exoplayer.buffer;
import android.media.MediaFormat;
+import android.util.Log;
import android.util.Pair;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
+import com.google.protobuf.nano.MessageNano;
+
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
@@ -28,18 +32,25 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
import java.util.SortedMap;
/**
* Manages DVR storage.
*/
public class DvrStorageManager implements BufferManager.StorageManager {
+ private static final String TAG = "DvrStorageManager";
// TODO: make serializable classes and use protobuf after internal data structure is finalized.
private static final String KEY_PIXEL_WIDTH_HEIGHT_RATIO =
"com.google.android.videos.pixelWidthHeightRatio";
+ private static final String META_FILE_TYPE_AUDIO = "audio";
+ private static final String META_FILE_TYPE_VIDEO = "video";
+ private static final String META_FILE_TYPE_CAPTION = "caption";
private static final String META_FILE_SUFFIX = ".meta";
private static final String IDX_FILE_SUFFIX = ".idx";
+ private static final String IDX_FILE_SUFFIX_V2 = IDX_FILE_SUFFIX + "2";
// Size of minimum reserved storage buffer which will be used to save meta files
// and index files after actual recording finished.
@@ -59,18 +70,6 @@ public class DvrStorageManager implements BufferManager.StorageManager {
}
@Override
- public void clearStorage() {
- if (mIsRecording) {
- File[] files = mBufferDir.listFiles();
- if (files != null && files.length > 0) {
- for (File file : files) {
- file.delete();
- }
- }
- }
- }
-
- @Override
public File getBufferDir() {
return mBufferDir;
}
@@ -132,6 +131,17 @@ public class DvrStorageManager implements BufferManager.StorageManager {
}
}
+ private void readFormatStringOptional(DataInputStream in, MediaFormat format, String key) {
+ try {
+ String str = readString(in);
+ if (str != null) {
+ format.setString(key, str);
+ }
+ } catch (IOException e) {
+ // Since we are reading optional field, ignore the exception.
+ }
+ }
+
private ByteBuffer readByteBuffer(DataInputStream in) throws IOException {
int len = in.readInt();
if (len <= 0) {
@@ -155,39 +165,104 @@ public class DvrStorageManager implements BufferManager.StorageManager {
}
@Override
- public Pair<String, MediaFormat> readTrackInfoFile(boolean isAudio) throws IOException {
- File file = new File(getBufferDir(), (isAudio ? "audio" : "video") + META_FILE_SUFFIX);
- try (DataInputStream in = new DataInputStream(new FileInputStream(file))) {
- String name = readString(in);
- MediaFormat format = new MediaFormat();
- readFormatString(in, format, MediaFormat.KEY_MIME);
- readFormatInt(in, format, MediaFormat.KEY_MAX_INPUT_SIZE);
- readFormatInt(in, format, MediaFormat.KEY_WIDTH);
- readFormatInt(in, format, MediaFormat.KEY_HEIGHT);
- readFormatInt(in, format, MediaFormat.KEY_CHANNEL_COUNT);
- readFormatInt(in, format, MediaFormat.KEY_SAMPLE_RATE);
- readFormatFloat(in, format, KEY_PIXEL_WIDTH_HEIGHT_RATIO);
- for (int i = 0; i < 3; ++i) {
- readFormatByteBuffer(in, format, "csd-" + i);
+ public List<BufferManager.TrackFormat> readTrackInfoFiles(boolean isAudio) {
+ List<BufferManager.TrackFormat> trackFormatList = new ArrayList<>();
+ int index = 0;
+ boolean trackNotFound = false;
+ do {
+ String fileName = (isAudio ? META_FILE_TYPE_AUDIO : META_FILE_TYPE_VIDEO)
+ + ((index == 0) ? META_FILE_SUFFIX : (index + META_FILE_SUFFIX));
+ File file = new File(getBufferDir(), fileName);
+ try (DataInputStream in = new DataInputStream(new FileInputStream(file))) {
+ String name = readString(in);
+ MediaFormat format = new MediaFormat();
+ readFormatString(in, format, MediaFormat.KEY_MIME);
+ readFormatInt(in, format, MediaFormat.KEY_MAX_INPUT_SIZE);
+ readFormatInt(in, format, MediaFormat.KEY_WIDTH);
+ readFormatInt(in, format, MediaFormat.KEY_HEIGHT);
+ readFormatInt(in, format, MediaFormat.KEY_CHANNEL_COUNT);
+ readFormatInt(in, format, MediaFormat.KEY_SAMPLE_RATE);
+ readFormatFloat(in, format, KEY_PIXEL_WIDTH_HEIGHT_RATIO);
+ for (int i = 0; i < 3; ++i) {
+ readFormatByteBuffer(in, format, "csd-" + i);
+ }
+ readFormatLong(in, format, MediaFormat.KEY_DURATION);
+
+ // This is optional since language field is added later.
+ readFormatStringOptional(in, format, MediaFormat.KEY_LANGUAGE);
+ trackFormatList.add(new BufferManager.TrackFormat(name, format));
+ } catch (IOException e) {
+ trackNotFound = true;
}
- readFormatLong(in, format, MediaFormat.KEY_DURATION);
- return new Pair<>(name, format);
+ index++;
+ } while(!trackNotFound);
+ return trackFormatList;
+ }
+
+ /**
+ * Reads caption information from files.
+ *
+ * @return a list of {@link AtscCaptionTrack} objects which store caption information.
+ */
+ public List<AtscCaptionTrack> readCaptionInfoFiles() {
+ List<AtscCaptionTrack> tracks = new ArrayList<>();
+ int index = 0;
+ boolean trackNotFound = false;
+ do {
+ String fileName = META_FILE_TYPE_CAPTION +
+ ((index == 0) ? META_FILE_SUFFIX : (index + META_FILE_SUFFIX));
+ File file = new File(getBufferDir(), fileName);
+ try (DataInputStream in = new DataInputStream(new FileInputStream(file))) {
+ byte[] data = new byte[(int) file.length()];
+ in.read(data);
+ tracks.add(AtscCaptionTrack.parseFrom(data));
+ } catch (IOException e) {
+ trackNotFound = true;
+ }
+ index++;
+ } while(!trackNotFound);
+ return tracks;
+ }
+
+ private ArrayList<BufferManager.PositionHolder> readOldIndexFile(File indexFile)
+ throws IOException {
+ ArrayList<BufferManager.PositionHolder> indices = new ArrayList<>();
+ try (DataInputStream in = new DataInputStream(new FileInputStream(indexFile))) {
+ long count = in.readLong();
+ for (long i = 0; i < count; ++i) {
+ long positionUs = in.readLong();
+ indices.add(new BufferManager.PositionHolder(positionUs, positionUs, 0));
+ }
+ return indices;
}
}
- @Override
- public ArrayList<Long> readIndexFile(String trackId) throws IOException {
- ArrayList<Long> indices = new ArrayList<>();
- File file = new File(getBufferDir(), trackId + IDX_FILE_SUFFIX);
- try (DataInputStream in = new DataInputStream(new FileInputStream(file))) {
+ private ArrayList<BufferManager.PositionHolder> readNewIndexFile(File indexFile)
+ throws IOException {
+ ArrayList<BufferManager.PositionHolder> indices = new ArrayList<>();
+ try (DataInputStream in = new DataInputStream(new FileInputStream(indexFile))) {
long count = in.readLong();
for (long i = 0; i < count; ++i) {
- indices.add(in.readLong());
+ long positionUs = in.readLong();
+ long basePositionUs = in.readLong();
+ int offset = in.readInt();
+ indices.add(new BufferManager.PositionHolder(positionUs, basePositionUs, offset));
}
return indices;
}
}
+ @Override
+ public ArrayList<BufferManager.PositionHolder> readIndexFile(String trackId)
+ throws IOException {
+ File file = new File(getBufferDir(), trackId + IDX_FILE_SUFFIX_V2);
+ if (file.exists()) {
+ return readNewIndexFile(file);
+ } else {
+ return readOldIndexFile(new File(getBufferDir(),trackId + IDX_FILE_SUFFIX));
+ }
+ }
+
private void writeFormatInt(DataOutputStream out, MediaFormat format, String key)
throws IOException {
if (format.containsKey(key)) {
@@ -254,33 +329,63 @@ public class DvrStorageManager implements BufferManager.StorageManager {
}
@Override
- public void writeTrackInfoFile(String trackId, MediaFormat format, boolean isAudio)
+ public void writeTrackInfoFiles(List<BufferManager.TrackFormat> formatList, boolean isAudio)
throws IOException {
- File file = new File(getBufferDir(), (isAudio ? "audio" : "video") + META_FILE_SUFFIX);
- try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) {
- writeString(out, trackId);
- writeFormatString(out, format, MediaFormat.KEY_MIME);
- writeFormatInt(out, format, MediaFormat.KEY_MAX_INPUT_SIZE);
- writeFormatInt(out, format, MediaFormat.KEY_WIDTH);
- writeFormatInt(out, format, MediaFormat.KEY_HEIGHT);
- writeFormatInt(out, format, MediaFormat.KEY_CHANNEL_COUNT);
- writeFormatInt(out, format, MediaFormat.KEY_SAMPLE_RATE);
- writeFormatFloat(out, format, KEY_PIXEL_WIDTH_HEIGHT_RATIO);
- for (int i = 0; i < 3; ++i) {
- writeFormatByteBuffer(out, format, "csd-" + i);
+ for (int i = 0; i < formatList.size() ; ++i) {
+ BufferManager.TrackFormat trackFormat = formatList.get(i);
+ String fileName = (isAudio ? META_FILE_TYPE_AUDIO : META_FILE_TYPE_VIDEO)
+ + ((i == 0) ? META_FILE_SUFFIX : (i + META_FILE_SUFFIX));
+ File file = new File(getBufferDir(), fileName);
+ try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) {
+ writeString(out, trackFormat.trackId);
+ writeFormatString(out, trackFormat.format, MediaFormat.KEY_MIME);
+ writeFormatInt(out, trackFormat.format, MediaFormat.KEY_MAX_INPUT_SIZE);
+ writeFormatInt(out, trackFormat.format, MediaFormat.KEY_WIDTH);
+ writeFormatInt(out, trackFormat.format, MediaFormat.KEY_HEIGHT);
+ writeFormatInt(out, trackFormat.format, MediaFormat.KEY_CHANNEL_COUNT);
+ writeFormatInt(out, trackFormat.format, MediaFormat.KEY_SAMPLE_RATE);
+ writeFormatFloat(out, trackFormat.format, KEY_PIXEL_WIDTH_HEIGHT_RATIO);
+ for (int j = 0; j < 3; ++j) {
+ writeFormatByteBuffer(out, trackFormat.format, "csd-" + j);
+ }
+ writeFormatLong(out, trackFormat.format, MediaFormat.KEY_DURATION);
+ writeFormatString(out, trackFormat.format, MediaFormat.KEY_LANGUAGE);
+ }
+ }
+ }
+
+ /**
+ * Writes caption information to files.
+ *
+ * @param tracks a list of {@link AtscCaptionTrack} objects which store caption information.
+ */
+ public void writeCaptionInfoFiles(List<AtscCaptionTrack> tracks) {
+ if (tracks == null || tracks.isEmpty()) {
+ return;
+ }
+ for (int i = 0; i < tracks.size(); i++) {
+ AtscCaptionTrack track = tracks.get(i);
+ String fileName = META_FILE_TYPE_CAPTION +
+ ((i == 0) ? META_FILE_SUFFIX : (i + META_FILE_SUFFIX));
+ File file = new File(getBufferDir(), fileName);
+ try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) {
+ out.write(MessageNano.toByteArray(track));
+ } catch (Exception e) {
+ Log.e(TAG, "Fail to write caption info to files", e);
}
- writeFormatLong(out, format, MediaFormat.KEY_DURATION);
}
}
@Override
- public void writeIndexFile(String trackName, SortedMap<Long, SampleChunk> index)
+ public void writeIndexFile(String trackName, SortedMap<Long, Pair<SampleChunk, Integer>> index)
throws IOException {
- File indexFile = new File(getBufferDir(), trackName + IDX_FILE_SUFFIX);
+ File indexFile = new File(getBufferDir(), trackName + IDX_FILE_SUFFIX_V2);
try (DataOutputStream out = new DataOutputStream(new FileOutputStream(indexFile))) {
out.writeLong(index.size());
- for (Long key : index.keySet()) {
- out.writeLong(key);
+ for (Map.Entry<Long, Pair<SampleChunk, Integer>> entry : index.entrySet()) {
+ out.writeLong(entry.getKey());
+ out.writeLong(entry.getValue().first.getStartPositionUs());
+ out.writeInt(entry.getValue().second);
}
}
}
diff --git a/src/com/android/tv/tuner/exoplayer/buffer/RecordingSampleBuffer.java b/src/com/android/tv/tuner/exoplayer/buffer/RecordingSampleBuffer.java
index 4869b49f..af0c3f0d 100644
--- a/src/com/android/tv/tuner/exoplayer/buffer/RecordingSampleBuffer.java
+++ b/src/com/android/tv/tuner/exoplayer/buffer/RecordingSampleBuffer.java
@@ -66,9 +66,14 @@ public class RecordingSampleBuffer implements BufferManager.SampleBuffer,
public static final int BUFFER_REASON_RECORDING = 2;
/**
- * The duration of a chunk of samples, {@link SampleChunk}.
+ * The minimum duration to support seek in Trickplay.
*/
- static final long CHUNK_DURATION_US = TimeUnit.MILLISECONDS.toMicros(500);
+ static final long MIN_SEEK_DURATION_US = TimeUnit.MILLISECONDS.toMicros(500);
+
+ /**
+ * The duration of a {@link SampleChunk} for recordings.
+ */
+ static final long RECORDING_CHUNK_DURATION_US = MIN_SEEK_DURATION_US * 1200; // 10 minutes
private static final long BUFFER_WRITE_TIMEOUT_MS = 10 * 1000; // 10 seconds
private static final long BUFFER_NEEDED_US =
1000L * Math.max(MpegTsPlayer.MIN_BUFFER_MS, MpegTsPlayer.MIN_REBUFFER_MS);
@@ -79,7 +84,6 @@ public class RecordingSampleBuffer implements BufferManager.SampleBuffer,
private int mTrackCount;
private boolean[] mTrackSelected;
- private List<String> mIds;
private List<SampleQueue> mReadSampleQueues;
private final SamplePool mSamplePool = new SamplePool();
private long mLastBufferedPositionUs = C.UNKNOWN_TIME_US;
@@ -130,7 +134,6 @@ public class RecordingSampleBuffer implements BufferManager.SampleBuffer,
if (mTrackCount <= 0) {
throw new IOException("No tracks to initialize");
}
- mIds = ids;
mTrackSelected = new boolean[mTrackCount];
mReadSampleQueues = new ArrayList<>();
mSampleChunkIoHelper = new SampleChunkIoHelper(ids, mediaFormats, mBufferReason,
@@ -139,6 +142,9 @@ public class RecordingSampleBuffer implements BufferManager.SampleBuffer,
mReadSampleQueues.add(i, new SampleQueue(mSamplePool));
}
mSampleChunkIoHelper.init();
+ for (int i = 0; i < mTrackCount; ++i) {
+ mBufferManager.registerChunkEvictedListener(ids.get(i), RecordingSampleBuffer.this);
+ }
}
@Override
@@ -146,8 +152,6 @@ public class RecordingSampleBuffer implements BufferManager.SampleBuffer,
if (!mTrackSelected[index]) {
mTrackSelected[index] = true;
mReadSampleQueues.get(index).clear();
- mBufferManager.registerChunkEvictedListener(mIds.get(index),
- RecordingSampleBuffer.this);
mSampleChunkIoHelper.openRead(index, mCurrentPlaybackPositionUs);
}
}
@@ -157,7 +161,7 @@ public class RecordingSampleBuffer implements BufferManager.SampleBuffer,
if (mTrackSelected[index]) {
mTrackSelected[index] = false;
mReadSampleQueues.get(index).clear();
- mBufferManager.unregisterChunkEvictedListener(mIds.get(index));
+ mSampleChunkIoHelper.closeRead(index);
}
}
@@ -193,7 +197,6 @@ public class RecordingSampleBuffer implements BufferManager.SampleBuffer,
}
// Disables buffering samples afterwards, and notifies the disk speed is slow.
Log.w(TAG, "Disk is too slow for trickplay");
- mBufferManager.disable();
mBufferListener.onDiskTooSlow();
}
@@ -205,7 +208,7 @@ public class RecordingSampleBuffer implements BufferManager.SampleBuffer,
private boolean maybeReadSample(SampleQueue queue, int index) {
if (queue.getLastQueuedPositionUs() != null
&& queue.getLastQueuedPositionUs() > mCurrentPlaybackPositionUs + BUFFER_NEEDED_US
- && queue.isDurationGreaterThan(CHUNK_DURATION_US)) {
+ && queue.isDurationGreaterThan(MIN_SEEK_DURATION_US)) {
// The speed of queuing samples can be higher than the playback speed.
// If the duration of the samples in the queue is not limited,
// samples can be accumulated and there can be out-of-memory issues.
@@ -300,7 +303,7 @@ public class RecordingSampleBuffer implements BufferManager.SampleBuffer,
public void onChunkEvicted(String id, long createdTimeMs) {
if (mBufferListener != null) {
mBufferListener.onBufferStartTimeChanged(
- createdTimeMs + TimeUnit.MICROSECONDS.toMillis(CHUNK_DURATION_US));
+ createdTimeMs + TimeUnit.MICROSECONDS.toMillis(MIN_SEEK_DURATION_US));
}
}
}
diff --git a/src/com/android/tv/tuner/exoplayer/buffer/SampleChunk.java b/src/com/android/tv/tuner/exoplayer/buffer/SampleChunk.java
index 552caaef..04b5a071 100644
--- a/src/com/android/tv/tuner/exoplayer/buffer/SampleChunk.java
+++ b/src/com/android/tv/tuner/exoplayer/buffer/SampleChunk.java
@@ -78,7 +78,6 @@ public class SampleChunk {
/**
* A class for SampleChunk creation.
*/
- @VisibleForTesting
public static class SampleChunkCreator {
/**
@@ -151,18 +150,23 @@ public class SampleChunk {
mCurrentOffset = 0;
}
+ private void reset(SampleChunk chunk, long offset) {
+ mChunk = chunk;
+ mCurrentOffset = offset;
+ }
+
/**
* Prepares for read I/O operation from a new SampleChunk.
*
* @param chunk the new SampleChunk to read from
* @throws IOException
*/
- void openRead(SampleChunk chunk) throws IOException {
+ void openRead(SampleChunk chunk, long offset) throws IOException {
if (mChunk != null) {
mChunk.closeRead();
}
chunk.openRead();
- reset(chunk);
+ reset(chunk, offset);
}
/**
@@ -241,6 +245,20 @@ public class SampleChunk {
}
/**
+ * Returns the current SampleChunk for subsequent I/O operation.
+ */
+ SampleChunk getChunk() {
+ return mChunk;
+ }
+
+ /**
+ * Returns the current offset of the current SampleChunk for subsequent I/O operation.
+ */
+ long getOffset() {
+ return mCurrentOffset;
+ }
+
+ /**
* Releases SampleChunk. the SampleChunk will not be used anymore.
*
* @param chunk to release
diff --git a/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java b/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java
index 37ae4022..ca97a91a 100644
--- a/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java
+++ b/src/com/android/tv/tuner/exoplayer/buffer/SampleChunkIoHelper.java
@@ -21,6 +21,7 @@ import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
+import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
@@ -31,7 +32,9 @@ import com.android.tv.common.SoftPreconditions;
import com.android.tv.tuner.exoplayer.buffer.RecordingSampleBuffer.BufferReason;
import java.io.IOException;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
@@ -46,11 +49,13 @@ public class SampleChunkIoHelper implements Handler.Callback {
private static final int MSG_OPEN_READ = 1;
private static final int MSG_OPEN_WRITE = 2;
- private static final int MSG_CLOSE_WRITE = 3;
- private static final int MSG_READ = 4;
- private static final int MSG_WRITE = 5;
- private static final int MSG_RELEASE = 6;
+ private static final int MSG_CLOSE_READ = 3;
+ private static final int MSG_CLOSE_WRITE = 4;
+ private static final int MSG_READ = 5;
+ private static final int MSG_WRITE = 6;
+ private static final int MSG_RELEASE = 7;
+ private final long mSampleChunkDurationUs;
private final int mTrackCount;
private final List<String> mIds;
private final List<MediaFormat> mMediaFormats;
@@ -62,9 +67,11 @@ public class SampleChunkIoHelper implements Handler.Callback {
private Handler mIoHandler;
private final ConcurrentLinkedQueue<SampleHolder> mReadSampleBuffers[];
private final ConcurrentLinkedQueue<SampleHolder> mHandlerReadSampleBuffers[];
- private final long[] mWriteEndPositionUs;
+ private final long[] mWriteIndexEndPositionUs;
+ private final long[] mWriteChunkEndPositionUs;
private final SampleChunk.IoState[] mReadIoStates;
private final SampleChunk.IoState[] mWriteIoStates;
+ private final Set<Integer> mSelectedTracks = new ArraySet<>();
private long mBufferDurationUs = 0;
private boolean mWriteEnded;
private boolean mErrorNotified;
@@ -129,11 +136,20 @@ public class SampleChunkIoHelper implements Handler.Callback {
mReadSampleBuffers = new ConcurrentLinkedQueue[mTrackCount];
mHandlerReadSampleBuffers = new ConcurrentLinkedQueue[mTrackCount];
- mWriteEndPositionUs = new long[mTrackCount];
+ mWriteIndexEndPositionUs = new long[mTrackCount];
+ mWriteChunkEndPositionUs = new long[mTrackCount];
mReadIoStates = new SampleChunk.IoState[mTrackCount];
mWriteIoStates = new SampleChunk.IoState[mTrackCount];
+
+ // Small chunk duration for live playback will give more fine grained storage usage
+ // and eviction handling for trickplay.
+ mSampleChunkDurationUs =
+ bufferReason == RecordingSampleBuffer.BUFFER_REASON_LIVE_PLAYBACK ?
+ RecordingSampleBuffer.MIN_SEEK_DURATION_US :
+ RecordingSampleBuffer.RECORDING_CHUNK_DURATION_US;
for (int i = 0; i < mTrackCount; ++i) {
- mWriteEndPositionUs[i] = RecordingSampleBuffer.CHUNK_DURATION_US;
+ mWriteIndexEndPositionUs[i] = RecordingSampleBuffer.MIN_SEEK_DURATION_US;
+ mWriteChunkEndPositionUs[i] = mSampleChunkDurationUs;
mReadIoStates[i] = new SampleChunk.IoState();
mWriteIoStates[i] = new SampleChunk.IoState();
}
@@ -204,6 +220,15 @@ public class SampleChunkIoHelper implements Handler.Callback {
}
/**
+ * Closes read from the specified track.
+ *
+ * @param index track index
+ */
+ public void closeRead(int index) {
+ mIoHandler.sendMessage(mIoHandler.obtainMessage(MSG_CLOSE_READ, index));
+ }
+
+ /**
* Notifies writes are finished.
*/
public void closeWrite() {
@@ -229,21 +254,19 @@ public class SampleChunkIoHelper implements Handler.Callback {
try {
if (mBufferReason == RecordingSampleBuffer.BUFFER_REASON_RECORDING && mTrackCount > 0) {
// Saves meta information for recording.
- Pair<String, android.media.MediaFormat> audio = null, video = null;
+ List<BufferManager.TrackFormat> audios = new LinkedList<>();
+ List<BufferManager.TrackFormat> videos = new LinkedList<>();
for (int i = 0; i < mTrackCount; ++i) {
android.media.MediaFormat format =
mMediaFormats.get(i).getFrameworkMediaFormatV16();
format.setLong(android.media.MediaFormat.KEY_DURATION, mBufferDurationUs);
- if (audio == null && MimeTypes.isAudio(mMediaFormats.get(i).mimeType)) {
- audio = new Pair<>(mIds.get(i), format);
- } else if (video == null && MimeTypes.isVideo(mMediaFormats.get(i).mimeType)) {
- video = new Pair<>(mIds.get(i), format);
- }
- if (audio != null && video != null) {
- break;
+ if (MimeTypes.isAudio(mMediaFormats.get(i).mimeType)) {
+ audios.add(new BufferManager.TrackFormat(mIds.get(i), format));
+ } else if (MimeTypes.isVideo(mMediaFormats.get(i).mimeType)) {
+ videos.add(new BufferManager.TrackFormat(mIds.get(i), format));
}
}
- mBufferManager.writeMetaFiles(audio, video);
+ mBufferManager.writeMetaFiles(audios, videos);
}
} finally {
mBufferManager.release();
@@ -265,6 +288,9 @@ public class SampleChunkIoHelper implements Handler.Callback {
case MSG_OPEN_WRITE:
doOpenWrite((int) message.obj);
return true;
+ case MSG_CLOSE_READ:
+ doCloseRead((int) message.obj);
+ return true;
case MSG_CLOSE_WRITE:
doCloseWrite();
return true;
@@ -291,14 +317,16 @@ public class SampleChunkIoHelper implements Handler.Callback {
private void doOpenRead(IoParams params) throws IOException {
int index = params.index;
mIoHandler.removeMessages(MSG_READ, index);
- SampleChunk chunk = mBufferManager.getReadFile(mIds.get(index), params.positionUs);
- if (chunk == null) {
+ Pair<SampleChunk, Integer> readPosition =
+ mBufferManager.getReadFile(mIds.get(index), params.positionUs);
+ if (readPosition == null) {
String errorMessage = "Chunk ID:" + mIds.get(index) + " pos:" + params.positionUs
+ "is not found";
- SoftPreconditions.checkNotNull(chunk, TAG, errorMessage);
+ SoftPreconditions.checkNotNull(readPosition, TAG, errorMessage);
throw new IOException(errorMessage);
}
- mReadIoStates[index].openRead(chunk);
+ mSelectedTracks.add(index);
+ mReadIoStates[index].openRead(readPosition.first, (long) readPosition.second);
if (mHandlerReadSampleBuffers[index] != null) {
SampleHolder sample;
while ((sample = mHandlerReadSampleBuffers[index].poll()) != null) {
@@ -310,10 +338,22 @@ public class SampleChunkIoHelper implements Handler.Callback {
}
private void doOpenWrite(int index) throws IOException {
- SampleChunk chunk = mBufferManager.createNewWriteFile(mIds.get(index), 0, mSamplePool);
+ SampleChunk chunk = mBufferManager.createNewWriteFileIfNeeded(mIds.get(index), 0,
+ mSamplePool, null, 0);
mWriteIoStates[index].openWrite(chunk);
}
+ private void doCloseRead(int index) {
+ mSelectedTracks.remove(index);
+ if (mHandlerReadSampleBuffers[index] != null) {
+ SampleHolder sample;
+ while ((sample = mHandlerReadSampleBuffers[index].poll()) != null) {
+ mSamplePool.releaseSample(sample);
+ }
+ }
+ mIoHandler.removeMessages(MSG_READ, index);
+ }
+
private void doRead(int index) throws IOException {
mIoHandler.removeMessages(MSG_READ, index);
if (mHandlerReadSampleBuffers[index].size() >= MAX_READ_BUFFER_SAMPLES) {
@@ -357,13 +397,21 @@ public class SampleChunkIoHelper implements Handler.Callback {
if (sample.timeUs > mBufferDurationUs) {
mBufferDurationUs = sample.timeUs;
}
-
- if (sample.timeUs >= mWriteEndPositionUs[index]) {
- nextChunk = mBufferManager.createNewWriteFile(mIds.get(index),
- mWriteEndPositionUs[index], mSamplePool);
- mWriteEndPositionUs[index] =
- ((sample.timeUs / RecordingSampleBuffer.CHUNK_DURATION_US) + 1) *
- RecordingSampleBuffer.CHUNK_DURATION_US;
+ if (sample.timeUs >= mWriteIndexEndPositionUs[index]) {
+ SampleChunk currentChunk = sample.timeUs >= mWriteChunkEndPositionUs[index] ?
+ null : mWriteIoStates[params.index].getChunk();
+ int currentOffset = (int) mWriteIoStates[params.index].getOffset();
+ nextChunk = mBufferManager.createNewWriteFileIfNeeded(
+ mIds.get(index), mWriteIndexEndPositionUs[index], mSamplePool,
+ currentChunk, currentOffset);
+ mWriteIndexEndPositionUs[index] =
+ ((sample.timeUs / RecordingSampleBuffer.MIN_SEEK_DURATION_US) + 1) *
+ RecordingSampleBuffer.MIN_SEEK_DURATION_US;
+ if (nextChunk != null) {
+ mWriteChunkEndPositionUs[index] =
+ ((sample.timeUs / mSampleChunkDurationUs) + 1)
+ * mSampleChunkDurationUs;
+ }
}
}
mWriteIoStates[params.index].write(params.sample, nextChunk);
@@ -391,15 +439,22 @@ public class SampleChunkIoHelper implements Handler.Callback {
mIoHandler.removeCallbacksAndMessages(null);
mFinished = true;
conditionVariable.open();
+ mSelectedTracks.clear();
}
private void releaseEvictedChunks() {
- if (mBufferReason != RecordingSampleBuffer.BUFFER_REASON_LIVE_PLAYBACK) {
+ if (mBufferReason != RecordingSampleBuffer.BUFFER_REASON_LIVE_PLAYBACK
+ || mSelectedTracks.isEmpty()) {
return;
}
+ long currentStartPositionUs = Long.MAX_VALUE;
+ for (int trackIndex : mSelectedTracks) {
+ currentStartPositionUs = Math.min(currentStartPositionUs,
+ mReadIoStates[trackIndex].getStartPositionUs());
+ }
for (int i = 0; i < mTrackCount; ++i) {
long evictEndPositionUs = Math.min(mBufferManager.getStartPositionUs(mIds.get(i)),
- mReadIoStates[i].getStartPositionUs());
+ currentStartPositionUs);
mBufferManager.evictChunks(mIds.get(i), evictEndPositionUs);
}
}
diff --git a/src/com/android/tv/tuner/exoplayer/buffer/SampleQueue.java b/src/com/android/tv/tuner/exoplayer/buffer/SampleQueue.java
index 7b098f40..75eac5a2 100644
--- a/src/com/android/tv/tuner/exoplayer/buffer/SampleQueue.java
+++ b/src/com/android/tv/tuner/exoplayer/buffer/SampleQueue.java
@@ -43,6 +43,7 @@ public class SampleQueue {
if (sampleFromQueue == null) {
return SampleSource.NOTHING_READ;
}
+ sample.ensureSpaceForWrite(sampleFromQueue.size);
sample.size = sampleFromQueue.size;
sample.flags = sampleFromQueue.flags;
sample.timeUs = sampleFromQueue.timeUs;
diff --git a/src/com/android/tv/tuner/exoplayer/buffer/SimpleSampleBuffer.java b/src/com/android/tv/tuner/exoplayer/buffer/SimpleSampleBuffer.java
index 40c4ef95..159fde18 100644
--- a/src/com/android/tv/tuner/exoplayer/buffer/SimpleSampleBuffer.java
+++ b/src/com/android/tv/tuner/exoplayer/buffer/SimpleSampleBuffer.java
@@ -19,18 +19,18 @@ package com.android.tv.tuner.exoplayer.buffer;
import android.os.ConditionVariable;
import android.support.annotation.NonNull;
+
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.SampleSource;
+import com.android.tv.common.SoftPreconditions;
import com.android.tv.tuner.tvinput.PlaybackBufferListener;
import com.android.tv.tuner.exoplayer.SampleExtractor;
import java.io.IOException;
import java.util.List;
-import junit.framework.Assert;
-
/**
* Handles I/O for {@link SampleExtractor} when
* physical storage based buffer is not used. Trickplay is disabled.
@@ -115,8 +115,8 @@ public class SimpleSampleBuffer implements BufferManager.SampleBuffer {
@Override
public synchronized int readSample(int track, SampleHolder sampleHolder) {
SampleQueue queue = mPlayingSampleQueues[track];
- Assert.assertNotNull(queue);
- int result = queue.dequeueSample(sampleHolder);
+ SoftPreconditions.checkNotNull(queue);
+ int result = queue == null ? SampleSource.NOTHING_READ : queue.dequeueSample(sampleHolder);
if (result != SampleSource.SAMPLE_READ && reachedEos()) {
return SampleSource.END_OF_STREAM;
}
diff --git a/src/com/android/tv/tuner/exoplayer/buffer/TrickplayStorageManager.java b/src/com/android/tv/tuner/exoplayer/buffer/TrickplayStorageManager.java
index 258a5cd0..9fe921b8 100644
--- a/src/com/android/tv/tuner/exoplayer/buffer/TrickplayStorageManager.java
+++ b/src/com/android/tv/tuner/exoplayer/buffer/TrickplayStorageManager.java
@@ -17,20 +17,23 @@
package com.android.tv.tuner.exoplayer.buffer;
import android.content.Context;
-import android.media.MediaFormat;
import android.os.AsyncTask;
-import android.os.Looper;
import android.provider.Settings;
+import android.support.annotation.NonNull;
import android.util.Pair;
+import com.android.tv.common.SoftPreconditions;
+
import java.io.File;
import java.util.ArrayList;
+import java.util.List;
import java.util.SortedMap;
/**
* Manages Trickplay storage.
*/
public class TrickplayStorageManager implements BufferManager.StorageManager {
+ // TODO: Support multi-sessions.
private static final String BUFFER_DIR = "timeshift";
// Copied from android.provider.Settings.Global (hidden fields)
@@ -43,53 +46,68 @@ public class TrickplayStorageManager implements BufferManager.StorageManager {
private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500L * 1024 * 1024;
- private final File mBufferDir;
+ private static AsyncTask<Void, Void, Void> sLastCacheCleanUpTask;
+ private static File sBufferDir;
+ private static long sStorageBufferBytes;
+
private final long mMaxBufferSize;
- private final long mStorageBufferBytes;
- private static long getStorageBufferBytes(Context context, File path) {
+ private static void initParamsIfNeeded(Context context, @NonNull File path) {
+ // TODO: Support multi-sessions.
+ SoftPreconditions.checkState(
+ sBufferDir == null || sBufferDir.equals(path));
+ if (path.equals(sBufferDir)) {
+ return;
+ }
+ sBufferDir = path;
long lowPercentage = Settings.Global.getInt(context.getContentResolver(),
SYS_STORAGE_THRESHOLD_PERCENTAGE, DEFAULT_THRESHOLD_PERCENTAGE);
- long lowBytes = path.getTotalSpace() * lowPercentage / 100;
+ long lowPercentageToBytes = path.getTotalSpace() * lowPercentage / 100;
long maxLowBytes = Settings.Global.getLong(context.getContentResolver(),
SYS_STORAGE_THRESHOLD_MAX_BYTES, DEFAULT_THRESHOLD_MAX_BYTES);
- return Math.min(lowBytes, maxLowBytes);
+ sStorageBufferBytes = Math.min(lowPercentageToBytes, maxLowBytes);
}
- public TrickplayStorageManager(Context context, File baseDir, long maxBufferSize) {
- mBufferDir = new File(baseDir, BUFFER_DIR);
- mBufferDir.mkdirs();
+ public TrickplayStorageManager(Context context, @NonNull File baseDir, long maxBufferSize) {
+ initParamsIfNeeded(context, new File(baseDir, BUFFER_DIR));
+ sBufferDir.mkdirs();
mMaxBufferSize = maxBufferSize;
clearStorage();
- mStorageBufferBytes = getStorageBufferBytes(context, mBufferDir);
}
- @Override
- public void clearStorage() {
- File files[] = mBufferDir.listFiles();
- if (files == null || files.length == 0) {
- return;
+ private void clearStorage() {
+ long now = System.currentTimeMillis();
+ if (sLastCacheCleanUpTask != null) {
+ sLastCacheCleanUpTask.cancel(true);
}
- if (Looper.myLooper() == Looper.getMainLooper()) {
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- for (File file : files) {
+ sLastCacheCleanUpTask = new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ if (isCancelled()) {
+ return null;
+ }
+ File files[] = sBufferDir.listFiles();
+ if (files == null || files.length == 0) {
+ return null;
+ }
+ for (File file : files) {
+ if (isCancelled()) {
+ break;
+ }
+ long lastModified = file.lastModified();
+ if (lastModified != 0 && lastModified < now) {
file.delete();
}
- return null;
}
- }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- } else {
- for (File file : files) {
- file.delete();
+ return null;
}
- }
+ };
+ sLastCacheCleanUpTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@Override
public File getBufferDir() {
- return mBufferDir;
+ return sBufferDir;
}
@Override
@@ -104,25 +122,26 @@ public class TrickplayStorageManager implements BufferManager.StorageManager {
@Override
public boolean hasEnoughBuffer(long pendingDelete) {
- return mBufferDir.getUsableSpace() + pendingDelete >= mStorageBufferBytes;
+ return sBufferDir.getUsableSpace() + pendingDelete >= sStorageBufferBytes;
}
@Override
- public Pair<String, MediaFormat> readTrackInfoFile(boolean isAudio) {
+ public List<BufferManager.TrackFormat> readTrackInfoFiles(boolean isAudio) {
return null;
}
@Override
- public ArrayList<Long> readIndexFile(String trackId) {
+ public ArrayList<BufferManager.PositionHolder> readIndexFile(String trackId) {
return null;
}
@Override
- public void writeTrackInfoFile(String trackId, MediaFormat format, boolean isAudio) {
+ public void writeTrackInfoFiles(List<BufferManager.TrackFormat> formatList, boolean isAudio) {
}
@Override
- public void writeIndexFile(String trackName, SortedMap<Long, SampleChunk> index) {
+ public void writeIndexFile(String trackName,
+ SortedMap<Long, Pair<SampleChunk, Integer>> index) {
}
}
diff --git a/src/com/android/tv/tuner/exoplayer/ffmpeg/FfmpegDecoderClient.java b/src/com/android/tv/tuner/exoplayer/ffmpeg/FfmpegDecoderClient.java
new file mode 100644
index 00000000..356636cc
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/ffmpeg/FfmpegDecoderClient.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2017 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.tv.tuner.exoplayer.ffmpeg;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import android.support.annotation.MainThread;
+import android.support.annotation.WorkerThread;
+import android.support.annotation.VisibleForTesting;
+import com.google.android.exoplayer.SampleHolder;
+import com.android.tv.Features;
+import com.android.tv.tuner.exoplayer.audio.AudioDecoder;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The class connects {@link FfmpegDecoderService} to decode audio samples.
+ * In order to sandbox ffmpeg based decoder, {@link FfmpegDecoderService} is an isolated process
+ * without any permission and connected by binder.
+ */
+public class FfmpegDecoderClient extends AudioDecoder {
+ private static FfmpegDecoderClient sInstance;
+
+ private IFfmpegDecoder mService;
+ private Boolean mIsAvailable;
+
+ private static final String FFMPEG_DECODER_SERVICE_FILTER =
+ "com.android.tv.tuner.exoplayer.ffmpeg.IFfmpegDecoder";
+ private static final long FFMPEG_SERVICE_CONNECT_TIMEOUT_MS = 500;
+
+ private final ServiceConnection mConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ mService = IFfmpegDecoder.Stub.asInterface(service);
+ synchronized (FfmpegDecoderClient.this) {
+ try {
+ mIsAvailable = mService.isAvailable();
+ } catch (RemoteException e) {
+ }
+ FfmpegDecoderClient.this.notify();
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName className) {
+ synchronized (FfmpegDecoderClient.this) {
+ sInstance.releaseLocked();
+ mIsAvailable = false;
+ mService = null;
+ }
+ }
+ };
+
+ /**
+ * Connects to the decoder service for future uses.
+ * @param context
+ * @return {@code true} when decoder service is connected.
+ */
+ @MainThread
+ public synchronized static boolean connect(Context context) {
+ if (Features.AC3_SOFTWARE_DECODE.isEnabled(context)) {
+ if (sInstance == null) {
+ sInstance = new FfmpegDecoderClient();
+ Intent intent =
+ new Intent(FFMPEG_DECODER_SERVICE_FILTER)
+ .setComponent(
+ new ComponentName(context, FfmpegDecoderService.class));
+ if (context.bindService(intent, sInstance.mConnection, Context.BIND_AUTO_CREATE)) {
+ return true;
+ } else {
+ sInstance = null;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Disconnects from the decoder service and release resources.
+ * @param context
+ */
+ @MainThread
+ public synchronized static void disconnect(Context context) {
+ if (sInstance != null) {
+ synchronized (sInstance) {
+ sInstance.releaseLocked();
+ if (sInstance.mIsAvailable != null && sInstance.mIsAvailable) {
+ context.unbindService(sInstance.mConnection);
+ }
+ sInstance.mIsAvailable = false;
+ sInstance.mService = null;
+ }
+ sInstance = null;
+ }
+ }
+
+ /**
+ * Returns whether service is available or not.
+ * Before using client, this should be used to check availability.
+ */
+ @WorkerThread
+ public synchronized static boolean isAvailable() {
+ if (sInstance != null) {
+ return sInstance.available();
+ }
+ return false;
+ }
+
+ /**
+ * Returns an client instance.
+ */
+ public synchronized static FfmpegDecoderClient getInstance() {
+ if (sInstance != null) {
+ sInstance.createDecoder();
+ }
+ return sInstance;
+ }
+
+ private FfmpegDecoderClient() {
+ }
+
+ private synchronized boolean available() {
+ if (mIsAvailable == null) {
+ try {
+ this.wait(FFMPEG_SERVICE_CONNECT_TIMEOUT_MS);
+ } catch (InterruptedException e) {
+ }
+ }
+ return mIsAvailable != null && mIsAvailable == true;
+ }
+
+ private synchronized void createDecoder() {
+ if (mIsAvailable == null || mIsAvailable == false) {
+ return;
+ }
+ try {
+ mService.create();
+ } catch (RemoteException e) {
+ }
+ }
+
+ private void releaseLocked() {
+ if (mIsAvailable == null || mIsAvailable == false) {
+ return;
+ }
+ try {
+ mService.release();
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public synchronized void release() {
+ releaseLocked();
+ }
+
+ @Override
+ public synchronized void decode(SampleHolder sampleHolder) {
+ if (mIsAvailable == null || mIsAvailable == false) {
+ return;
+ }
+ byte[] sampleBytes = new byte [sampleHolder.data.limit()];
+ sampleHolder.data.get(sampleBytes, 0, sampleBytes.length);
+ try {
+ mService.decode(sampleHolder.timeUs, sampleBytes);
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public synchronized void resetDecoderState(String mimeType) {
+ if (mIsAvailable == null || mIsAvailable == false) {
+ return;
+ }
+ try {
+ mService.resetDecoderState(mimeType);
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public synchronized ByteBuffer getDecodedSample() {
+ if (mIsAvailable == null || mIsAvailable == false) {
+ return null;
+ }
+ try {
+ byte[] outputBytes = mService.getDecodedSample();
+ if (outputBytes != null && outputBytes.length > 0) {
+ return ByteBuffer.wrap(outputBytes);
+ }
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ @Override
+ public synchronized long getDecodedTimeUs() {
+ if (mIsAvailable == null || mIsAvailable == false) {
+ return 0;
+ }
+ try {
+ return mService.getDecodedTimeUs();
+ } catch (RemoteException e) {
+ }
+ return 0;
+ }
+
+ @VisibleForTesting
+ public boolean testSandboxIsolatedProcess() {
+ // When testing isolated process, we will check the permission in FfmpegDecoderService.
+ // If the service have any permission, an exception will be thrown.
+ try {
+ mService.testSandboxIsolatedProcess();
+ } catch (RemoteException e) {
+ return false;
+ }
+ return true;
+ }
+
+ @VisibleForTesting
+ public void testSandboxMinijail() {
+ // When testing minijail, we will call a system call which is blocked by minijail. In that
+ // case, the FfmpegDecoderService will be disconnected, we can check the connection status
+ // to make sure if the minijail works or not.
+ try {
+ mService.testSandboxMinijail();
+ } catch (RemoteException e) {
+ }
+ }
+}
diff --git a/src/com/android/tv/tuner/exoplayer/ffmpeg/FfmpegDecoderService.java b/src/com/android/tv/tuner/exoplayer/ffmpeg/FfmpegDecoderService.java
new file mode 100644
index 00000000..3ebdd381
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/ffmpeg/FfmpegDecoderService.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2017 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.tv.tuner.exoplayer.ffmpeg;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.AssetFileDescriptor;
+import android.os.AsyncTask;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioDecoder;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Ffmpeg based audio decoder service.
+ * It should be isolatedProcess due to security reason.
+ */
+public class FfmpegDecoderService extends Service {
+ private static final String TAG = "FfmpegDecoderService";
+ private static final boolean DEBUG = false;
+
+ private static final String POLICY_FILE = "whitelist.policy";
+
+ private static final long MINIJAIL_SETUP_WAIT_TIMEOUT_MS = 5000;
+
+ private static boolean sLibraryLoaded = true;
+
+ static {
+ try {
+ System.loadLibrary("minijail_jni");
+ } catch (Exception | Error e) {
+ Log.e(TAG, "Load minijail failed:", e);
+ sLibraryLoaded = false;
+ }
+ }
+
+ private FfmpegDecoder mBinder = new FfmpegDecoder();
+ private volatile Object mMinijailSetupMonitor = new Object();
+ //@GuardedBy("mMinijailSetupMonitor")
+ private volatile Boolean mMinijailSetup;
+
+ @Override
+ public void onCreate() {
+ if (sLibraryLoaded) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ synchronized (mMinijailSetupMonitor) {
+ int pipeFd = getPolicyPipeFd();
+ if (pipeFd <= 0) {
+ Log.e(TAG, "fail to open policy file");
+ mMinijailSetup = false;
+ } else {
+ nativeSetupMinijail(pipeFd);
+ mMinijailSetup = true;
+ if (DEBUG) Log.d(TAG, "Minijail setup successfully");
+ }
+ mMinijailSetupMonitor.notify();
+ }
+ return null;
+ }
+ }.execute();
+ } else {
+ synchronized (mMinijailSetupMonitor) {
+ mMinijailSetup = false;
+ mMinijailSetupMonitor.notify();
+ }
+ }
+ super.onCreate();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ private int getPolicyPipeFd() {
+ try {
+ ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+ final ParcelFileDescriptor.AutoCloseOutputStream outputStream =
+ new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
+ final AssetFileDescriptor policyFile = getAssets().openFd("whitelist.policy");
+ final byte[] buffer = new byte[2048];
+ final FileInputStream policyStream = policyFile.createInputStream();
+ while (true) {
+ int bytesRead = policyStream.read(buffer);
+ if (bytesRead == -1) break;
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ policyStream.close();
+ outputStream.close();
+ return pipe[0].detachFd();
+ } catch (IOException e) {
+ Log.e(TAG, "Policy file not found:" + e);
+ }
+ return -1;
+ }
+
+ private final class FfmpegDecoder extends IFfmpegDecoder.Stub {
+ FfmpegAudioDecoder mDecoder;
+ @Override
+ public boolean isAvailable() {
+ return isMinijailSetupDone() && FfmpegAudioDecoder.isAvailable();
+ }
+
+ @Override
+ public void create() {
+ mDecoder = new FfmpegAudioDecoder(FfmpegDecoderService.this);
+ }
+
+ @Override
+ public void release() {
+ if (mDecoder != null) {
+ mDecoder.release();
+ mDecoder = null;
+ }
+ }
+
+ @Override
+ public void decode(long timeUs, byte[] sample) {
+ if (!isMinijailSetupDone()) {
+ // If minijail is not setup, we don't run decode for better security.
+ return;
+ }
+ mDecoder.decode(timeUs, sample);
+ }
+
+ @Override
+ public void resetDecoderState(String mimetype) {
+ mDecoder.resetDecoderState(mimetype);
+ }
+
+ @Override
+ public byte[] getDecodedSample() {
+ ByteBuffer decodedBuffer = mDecoder.getDecodedSample();
+ byte[] ret = new byte[decodedBuffer.limit()];
+ decodedBuffer.get(ret, 0, ret.length);
+ return ret;
+ }
+
+ @Override
+ public long getDecodedTimeUs() {
+ return mDecoder.getDecodedTimeUs();
+ }
+
+ private boolean isMinijailSetupDone() {
+ synchronized (mMinijailSetupMonitor) {
+ if (DEBUG) Log.d(TAG, "mMinijailSetup in isAvailable(): " + mMinijailSetup);
+ if (mMinijailSetup == null) {
+ try {
+ if (DEBUG) Log.d(TAG, "Wait till Minijail setup is done");
+ mMinijailSetupMonitor.wait(MINIJAIL_SETUP_WAIT_TIMEOUT_MS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ return mMinijailSetup != null && mMinijailSetup;
+ }
+ }
+
+ @Override
+ public void testSandboxIsolatedProcess() {
+ if (!isMinijailSetupDone()) {
+ // If minijail is not setup, we return directly to make the test fail.
+ return;
+ }
+ if (FfmpegDecoderService.this.checkSelfPermission("android.permission.INTERNET")
+ == PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Shouldn't have the permission of internet");
+ }
+ }
+
+ @Override
+ public void testSandboxMinijail() {
+ if (!isMinijailSetupDone()) {
+ // If minijail is not setup, we return directly to make the test fail.
+ return;
+ }
+ nativeTestMinijail();
+ }
+ }
+
+ private native void nativeSetupMinijail(int policyFd);
+ private native void nativeTestMinijail();
+}
diff --git a/src/com/android/tv/tuner/exoplayer/ffmpeg/IFfmpegDecoder.aidl b/src/com/android/tv/tuner/exoplayer/ffmpeg/IFfmpegDecoder.aidl
new file mode 100644
index 00000000..ed053790
--- /dev/null
+++ b/src/com/android/tv/tuner/exoplayer/ffmpeg/IFfmpegDecoder.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017 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.tv.tuner.exoplayer.ffmpeg;
+
+interface IFfmpegDecoder {
+ boolean isAvailable();
+ void create();
+ void release();
+ void resetDecoderState(String mimetype);
+ void decode(long timeUs, in byte[] sample);
+ byte[] getDecodedSample();
+ long getDecodedTimeUs();
+ void testSandboxIsolatedProcess();
+ void testSandboxMinijail();
+} \ No newline at end of file
diff --git a/src/com/android/tv/tuner/setup/ConnectionTypeFragment.java b/src/com/android/tv/tuner/setup/ConnectionTypeFragment.java
index 97d9ece3..e0e21a20 100644
--- a/src/com/android/tv/tuner/setup/ConnectionTypeFragment.java
+++ b/src/com/android/tv/tuner/setup/ConnectionTypeFragment.java
@@ -21,6 +21,7 @@ import android.support.annotation.NonNull;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
import android.support.v17.leanback.widget.GuidedAction;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.tuner.R;
@@ -36,6 +37,24 @@ public class ConnectionTypeFragment extends SetupMultiPaneFragment {
"com.android.tv.tuner.setup.ConnectionTypeFragment";
@Override
+ public void onCreate(Bundle savedInstanceState) {
+ ((TunerSetupActivity) getActivity()).generateTunerHal();
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onResume() {
+ ((TunerSetupActivity) getActivity()).generateTunerHal();
+ super.onResume();
+ }
+
+ @Override
+ public void onDestroy() {
+ ((TunerSetupActivity) getActivity()).clearTunerHal();
+ super.onDestroy();
+ }
+
+ @Override
protected SetupGuidedStepFragment onCreateContentFragment() {
return new ContentFragment();
}
diff --git a/src/com/android/tv/tuner/setup/PostalCodeFragment.java b/src/com/android/tv/tuner/setup/PostalCodeFragment.java
new file mode 100644
index 00000000..025b9193
--- /dev/null
+++ b/src/com/android/tv/tuner/setup/PostalCodeFragment.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2017 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.tv.tuner.setup;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v17.leanback.widget.GuidedActionsStylist;
+import android.text.InputFilter;
+import android.text.InputFilter.AllCaps;
+import android.view.View;
+import android.widget.TextView;
+import com.android.tv.R;
+import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
+import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
+import com.android.tv.tuner.util.PostalCodeUtils;
+import com.android.tv.util.LocationUtils;
+import java.util.List;
+
+/**
+ * A fragment for initial screen.
+ */
+public class PostalCodeFragment extends SetupMultiPaneFragment {
+ public static final String ACTION_CATEGORY =
+ "com.android.tv.tuner.setup.PostalCodeFragment";
+ private static final int VIEW_TYPE_EDITABLE = 1;
+
+ @Override
+ protected SetupGuidedStepFragment onCreateContentFragment() {
+ ContentFragment fragment = new ContentFragment();
+ Bundle arguments = new Bundle();
+ arguments.putBoolean(SetupGuidedStepFragment.KEY_THREE_PANE, true);
+ fragment.setArguments(arguments);
+ return fragment;
+ }
+
+ @Override
+ protected String getActionCategory() {
+ return ACTION_CATEGORY;
+ }
+
+ @Override
+ protected boolean needsDoneButton() {
+ return true;
+ }
+
+ @Override
+ protected boolean needsSkipButton() {
+ return true;
+ }
+
+ @Override
+ protected void setOnClickAction(View view, final String category, final int actionId) {
+ if (actionId == ACTION_DONE) {
+ view.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ CharSequence postalCode =
+ ((ContentFragment) getContentFragment()).mEditAction.getTitle();
+ String region = LocationUtils.getCurrentCountry(getContext());
+ if (postalCode != null && PostalCodeUtils.matches(postalCode, region)) {
+ PostalCodeUtils.setLastPostalCode(
+ getContext(), postalCode.toString());
+ onActionClick(category, actionId);
+ } else {
+ ContentFragment contentFragment =
+ (ContentFragment) getContentFragment();
+ contentFragment.mEditAction.setDescription(
+ getString(R.string.postal_code_invalid_warning));
+ contentFragment.notifyActionChanged(0);
+ contentFragment.mEditedActionView.performClick();
+ }
+ }
+ });
+ } else if (actionId == ACTION_SKIP) {
+ super.setOnClickAction(view, category, ACTION_SKIP);
+ }
+ }
+
+ public static class ContentFragment extends SetupGuidedStepFragment {
+ private GuidedAction mEditAction;
+ private View mEditedActionView;
+ private View mDoneActionView;
+ private boolean mProceed;
+
+ @Override
+ public void onGuidedActionFocused(GuidedAction action) {
+ if (action.equals(mEditAction)) {
+ if (mProceed) {
+ // "NEXT" in IME was just clicked, moves focus to Done button.
+ if (mDoneActionView == null) {
+ mDoneActionView = getActivity().findViewById(R.id.button_done);
+ }
+ mDoneActionView.requestFocus();
+ mProceed = false;
+ } else {
+ // Directly opens IME to input postal/zip code.
+ if (mEditedActionView == null) {
+ int maxLength = PostalCodeUtils.getRegionMaxLength(getContext());
+ mEditedActionView = getView().findViewById(R.id.guidedactions_editable);
+ ((TextView) mEditedActionView.findViewById(R.id.guidedactions_item_title))
+ .setFilters(
+ new InputFilter[] {
+ new InputFilter.LengthFilter(maxLength), new AllCaps()
+ });
+ }
+ mEditedActionView.performClick();
+ }
+ }
+ }
+
+ @Override
+ public long onGuidedActionEditedAndProceed(GuidedAction action) {
+ mProceed = true;
+ return 0;
+ }
+
+ @NonNull
+ @Override
+ public Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title = getString(R.string.postal_code_guidance_title);
+ String description = getString(R.string.postal_code_guidance_description);
+ String breadcrumb = getString(R.string.ut_setup_breadcrumb);
+ return new Guidance(title, description, breadcrumb, null);
+ }
+
+ @Override
+ public void onCreateActions(@NonNull List<GuidedAction> actions,
+ Bundle savedInstanceState) {
+ String description = getString(R.string.postal_code_action_description);
+ mEditAction = new GuidedAction.Builder(getActivity()).id(0).editable(true)
+ .description(description).build();
+ actions.add(mEditAction);
+ }
+
+ @Override
+ protected String getActionCategory() {
+ return ACTION_CATEGORY;
+ }
+
+ @Override
+ public GuidedActionsStylist onCreateActionsStylist() {
+ return new GuidedActionsStylist() {
+ @Override
+ public int getItemViewType(GuidedAction action) {
+ if (action.isEditable()) {
+ return VIEW_TYPE_EDITABLE;
+ }
+ return super.getItemViewType(action);
+ }
+
+ @Override
+ public int onProvideItemLayoutId(int viewType) {
+ if (viewType == VIEW_TYPE_EDITABLE) {
+ return R.layout.guided_action_editable;
+ }
+ return super.onProvideItemLayoutId(viewType);
+ }
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/tuner/setup/ScanFragment.java b/src/com/android/tv/tuner/setup/ScanFragment.java
index 3b61debb..b6936e38 100644
--- a/src/com/android/tv/tuner/setup/ScanFragment.java
+++ b/src/com/android/tv/tuner/setup/ScanFragment.java
@@ -21,6 +21,7 @@ import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
import android.os.ConditionVariable;
import android.os.Handler;
@@ -35,25 +36,21 @@ import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import com.android.tv.common.AutoCloseableUtils;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.ui.setup.SetupFragment;
import com.android.tv.tuner.ChannelScanFileParser;
-import com.android.tv.tuner.TunerHal;
import com.android.tv.tuner.R;
+import com.android.tv.tuner.TunerHal;
import com.android.tv.tuner.TunerPreferences;
-import com.android.tv.tuner.data.nano.Channel;
import com.android.tv.tuner.data.PsipData;
import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Channel;
import com.android.tv.tuner.source.FileTsStreamer;
import com.android.tv.tuner.source.TsDataSource;
import com.android.tv.tuner.source.TsStreamer;
import com.android.tv.tuner.source.TunerTsStreamer;
import com.android.tv.tuner.tvinput.ChannelDataManager;
import com.android.tv.tuner.tvinput.EventDetector;
-import com.android.tv.tuner.util.TunerInputInfoUtils;
-
-import junit.framework.Assert;
import java.util.ArrayList;
import java.util.List;
@@ -67,6 +64,7 @@ import java.util.concurrent.TimeUnit;
public class ScanFragment extends SetupFragment {
private static final String TAG = "ScanFragment";
private static final boolean DEBUG = false;
+
// In the fake mode, the connection to antenna or cable is not necessary.
// Instead dummy channels are added.
private static final boolean FAKE_MODE = false;
@@ -98,6 +96,7 @@ public class ScanFragment extends SetupFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
+ if (DEBUG) Log.d(TAG, "onCreateView");
View view = super.onCreateView(inflater, container, savedInstanceState);
mChannelDataManager = new ChannelDataManager(getActivity());
mChannelDataManager.checkDataVersion(getActivity());
@@ -120,13 +119,19 @@ public class ScanFragment extends SetupFragment {
}
});
Bundle args = getArguments();
+ int tunerType = (args == null ? 0 : args.getInt(TunerSetupActivity.KEY_TUNER_TYPE, 0));
// TODO: Handle the case when the fragment is restored.
startScan(args == null ? 0 : args.getInt(EXTRA_FOR_CHANNEL_SCAN_FILE, 0));
TextView scanTitleView = (TextView) view.findViewById(R.id.tune_title);
- if (TunerInputInfoUtils.isBuiltInTuner(getActivity())){
- scanTitleView.setText(R.string.bt_channel_scan);
- } else {
- scanTitleView.setText(R.string.ut_channel_scan);
+ switch (tunerType) {
+ case TunerHal.TUNER_TYPE_USB:
+ scanTitleView.setText(R.string.ut_channel_scan);
+ break;
+ case TunerHal.TUNER_TYPE_NETWORK:
+ scanTitleView.setText(R.string.nt_channel_scan);
+ break;
+ default:
+ scanTitleView.setText(R.string.bt_channel_scan);
}
return view;
}
@@ -147,12 +152,14 @@ public class ScanFragment extends SetupFragment {
}
@Override
- public void onDetach() {
+ public void onPause() {
+ Log.d(TAG, "onPause");
if (mChannelScanTask != null) {
// Ensure scan task will stop.
+ Log.w(TAG, "The activity went to the background. Stopping channel scan.");
mChannelScanTask.stopScan();
}
- super.onDetach();
+ super.onPause();
}
/**
@@ -168,7 +175,9 @@ public class ScanFragment extends SetupFragment {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
- mChannelScanTask.showFinishingProgressDialog();
+ if (mChannelScanTask != null) {
+ mChannelScanTask.showFinishingProgressDialog();
+ }
}
}, SHOW_PROGRESS_DIALOG_DELAY_MS);
@@ -255,13 +264,13 @@ public class ScanFragment extends SetupFragment {
if (FAKE_MODE) {
mScanTsStreamer = new FakeTsStreamer(this);
} else {
- TunerHal hal = TunerHal.createInstance(mActivity.getApplicationContext());
+ TunerHal hal = ((TunerSetupActivity) mActivity).getTunerHal();
if (hal == null) {
throw new RuntimeException("Failed to open a DVB device");
}
mScanTsStreamer = new TunerTsStreamer(hal, this);
}
- mFileTsStreamer = SCAN_LOCAL_STREAMS ? new FileTsStreamer(this) : null;
+ mFileTsStreamer = SCAN_LOCAL_STREAMS ? new FileTsStreamer(this, mActivity) : null;
mConditionStopped = new ConditionVariable();
mChannelDataManager.setChannelScanListener(this, new Handler());
}
@@ -316,10 +325,17 @@ public class ScanFragment extends SetupFragment {
@Override
protected void onProgressUpdate(Integer... values) {
- mProgressBar.setProgress(values[0]);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ mProgressBar.setProgress(values[0], true);
+ } else {
+ mProgressBar.setProgress(values[0]);
+ }
}
private void stopScan() {
+ if (mLatch != null) {
+ mLatch.countDown();
+ }
mConditionStopped.open();
}
@@ -340,8 +356,8 @@ public class ScanFragment extends SetupFragment {
Log.i(TAG, "Tuning to " + frequency + " " + modulation);
TsStreamer streamer = getStreamer(scanChannel.type);
- Assert.assertNotNull(streamer);
- if (streamer.startStream(scanChannel)) {
+ SoftPreconditions.checkNotNull(streamer);
+ if (streamer != null && streamer.startStream(scanChannel)) {
mLatch = new CountDownLatch(1);
try {
mLatch.await(CHANNEL_SCAN_PERIOD_MS, TimeUnit.MILLISECONDS);
@@ -360,11 +376,7 @@ public class ScanFragment extends SetupFragment {
if (mConditionStopped.block(-1)) {
break;
}
- onProgressUpdate(MAX_PROGRESS * i++ / mScanChannelList.size());
- }
- if (mScanTsStreamer instanceof TunerTsStreamer) {
- AutoCloseableUtils.closeQuietly(
- ((TunerTsStreamer) mScanTsStreamer).getTunerHal());
+ publishProgress(MAX_PROGRESS * i++ / mScanChannelList.size());
}
mChannelDataManager.notifyScanCompleted();
if (!mConditionStopped.block(-1)) {
@@ -427,8 +439,8 @@ public class ScanFragment extends SetupFragment {
// Playbacks with video-only stream have not been tested yet.
// No video-only channel has been found.
addChannel(channel);
+ mChannelDataManager.notifyChannelDetected(channel, channelArrivedAtFirstTime);
}
- mChannelDataManager.notifyChannelDetected(channel, channelArrivedAtFirstTime);
}
public void showFinishingProgressDialog() {
@@ -446,15 +458,21 @@ public class ScanFragment extends SetupFragment {
mIsFinished = true;
TunerPreferences.setScannedChannelCount(mActivity.getApplicationContext(),
mChannelDataManager.getScannedChannelCount());
- // Cancel a previously shown recommendation card.
- TunerSetupActivity.cancelRecommendationCard(mActivity.getApplicationContext());
+ // Cancel a previously shown notification.
+ TunerSetupActivity.cancelNotification(mActivity.getApplicationContext());
// Mark scan as done
TunerPreferences.setScanDone(mActivity.getApplicationContext());
// finishing will be done manually.
if (mFinishingProgressDialog != null) {
mFinishingProgressDialog.dismiss();
}
- onActionClick(ACTION_CATEGORY, mIsCanceled ? ACTION_CANCEL : ACTION_FINISH);
+ // If the fragment is not resumed, the next fragment (scan result page) can't be
+ // displayed. In that case, just close the activity.
+ if (isResumed()) {
+ onActionClick(ACTION_CATEGORY, mIsCanceled ? ACTION_CANCEL : ACTION_FINISH);
+ } else if (getActivity() != null) {
+ getActivity().finish();
+ }
mChannelScanTask = null;
}
}
diff --git a/src/com/android/tv/tuner/setup/ScanResultFragment.java b/src/com/android/tv/tuner/setup/ScanResultFragment.java
index 068543cd..3b8cd823 100644
--- a/src/com/android/tv/tuner/setup/ScanResultFragment.java
+++ b/src/com/android/tv/tuner/setup/ScanResultFragment.java
@@ -26,6 +26,7 @@ import android.support.v17.leanback.widget.GuidedAction;
import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.tuner.R;
+import com.android.tv.tuner.TunerHal;
import com.android.tv.tuner.TunerPreferences;
import com.android.tv.tuner.util.TunerInputInfoUtils;
@@ -76,11 +77,19 @@ public class ScanResultFragment extends SetupMultiPaneFragment {
mChannelCountOnPreference, mChannelCountOnPreference);
breadcrumb = null;
} else {
+ Bundle args = getArguments();
+ int tunerType =
+ (args == null ? 0 : args.getInt(TunerSetupActivity.KEY_TUNER_TYPE, 0));
title = getString(R.string.ut_result_not_found_title);
- if (TunerInputInfoUtils.isBuiltInTuner(getActivity())) {
- description = getString(R.string.bt_result_not_found_description);
- } else {
- description = getString(R.string.ut_result_not_found_description);
+ switch (tunerType) {
+ case TunerHal.TUNER_TYPE_USB:
+ description = getString(R.string.ut_result_not_found_description);
+ break;
+ case TunerHal.TUNER_TYPE_NETWORK:
+ description = getString(R.string.nt_result_not_found_description);
+ break;
+ default:
+ description = getString(R.string.bt_result_not_found_description);
}
breadcrumb = getString(R.string.ut_setup_breadcrumb);
}
diff --git a/src/com/android/tv/tuner/setup/TunerSetupActivity.java b/src/com/android/tv/tuner/setup/TunerSetupActivity.java
index 78121bc5..e9f3baa7 100644
--- a/src/com/android/tv/tuner/setup/TunerSetupActivity.java
+++ b/src/com/android/tv/tuner/setup/TunerSetupActivity.java
@@ -19,6 +19,7 @@ package com.android.tv.tuner.setup;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -29,49 +30,98 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.tv.TvContract;
+import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
+import android.support.annotation.WorkerThread;
import android.support.v4.app.NotificationCompat;
+import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;
+import com.android.tv.Features;
import com.android.tv.TvApplication;
+import com.android.tv.common.AutoCloseableUtils;
+import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.TvCommonConstants;
import com.android.tv.common.TvCommonUtils;
import com.android.tv.common.ui.setup.SetupActivity;
import com.android.tv.common.ui.setup.SetupFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
+import com.android.tv.experiments.Experiments;
import com.android.tv.tuner.R;
import com.android.tv.tuner.TunerHal;
import com.android.tv.tuner.TunerPreferences;
import com.android.tv.tuner.tvinput.TunerTvInputService;
-import com.android.tv.tuner.util.TunerInputInfoUtils;
+import com.android.tv.tuner.util.PostalCodeUtils;
+
+import java.util.concurrent.Executor;
/**
* An activity that serves tuner setup process.
*/
public class TunerSetupActivity extends SetupActivity {
- private final String TAG = "TunerSetupActivity";
- // For the recommendation card
+ private static final String TAG = "TunerSetupActivity";
+ private static final boolean DEBUG = false;
+
+ /**
+ * Key for passing tuner type to sub-fragments.
+ */
+ public static final String KEY_TUNER_TYPE = "TunerSetupActivity.tunerType";
+
+ // For the notification.
private static final String TV_ACTIVITY_CLASS_NAME = "com.android.tv.TvActivity";
+ private static final String TUNER_SET_UP_NOTIFICATION_CHANNEL_ID = "tuner_setup_channel";
private static final String NOTIFY_TAG = "TunerSetup";
private static final int NOTIFY_ID = 1000;
private static final String TAG_DRAWABLE = "drawable";
private static final String TAG_ICON = "ic_launcher_s";
+ private static final int PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1;
private static final int CHANNEL_MAP_SCAN_FILE[] = {
- R.raw.ut_us_atsc_center_frequencies_8vsb,
- R.raw.ut_us_cable_standard_center_frequencies_qam256,
- R.raw.ut_us_all,
- R.raw.ut_kr_atsc_center_frequencies_8vsb,
- R.raw.ut_kr_cable_standard_center_frequencies_qam256,
- R.raw.ut_kr_all,
- R.raw.ut_kr_dev_cj_cable_center_frequencies_qam256};
+ R.raw.ut_us_atsc_center_frequencies_8vsb,
+ R.raw.ut_us_cable_standard_center_frequencies_qam256,
+ R.raw.ut_us_all,
+ R.raw.ut_kr_atsc_center_frequencies_8vsb,
+ R.raw.ut_kr_cable_standard_center_frequencies_qam256,
+ R.raw.ut_kr_all,
+ R.raw.ut_kr_dev_cj_cable_center_frequencies_qam256,
+ R.raw.ut_euro_dvbt_all,
+ R.raw.ut_euro_dvbt_all,
+ R.raw.ut_euro_dvbt_all
+ };
private ScanFragment mLastScanFragment;
+ private Integer mTunerType;
+ private TunerHalFactory mTunerHalFactory;
+ private boolean mNeedToShowPostalCodeFragment;
+ private String mPreviousPostalCode;
@Override
protected void onCreate(Bundle savedInstanceState) {
+ if (DEBUG) Log.d(TAG, "onCreate");
+ new AsyncTask<Void, Void, Integer>() {
+ @Override
+ protected Integer doInBackground(Void... arg0) {
+ return TunerHal.getTunerTypeAndCount(TunerSetupActivity.this).first;
+ }
+
+ @Override
+ protected void onPostExecute(Integer result) {
+ if (!TunerSetupActivity.this.isDestroyed()) {
+ mTunerType = result;
+ if (result == null) {
+ finish();
+ } else {
+ showInitialFragment();
+ }
+ }
+ }
+ }.execute();
TvApplication.setCurrentRunningProcess(this, false);
super.onCreate(savedInstanceState);
// TODO: check {@link shouldShowRequestPermissionRationale}.
@@ -79,16 +129,52 @@ public class TunerSetupActivity extends SetupActivity {
!= PackageManager.PERMISSION_GRANTED) {
// No need to check the request result.
requestPermissions(new String[] {android.Manifest.permission.ACCESS_COARSE_LOCATION},
- 0);
+ PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
+ }
+ mTunerHalFactory = new TunerHalFactory(getApplicationContext());
+ try {
+ // Updating postal code takes time, therefore we called it here for "warm-up".
+ mPreviousPostalCode = PostalCodeUtils.getLastPostalCode(this);
+ PostalCodeUtils.setLastPostalCode(this, null);
+ PostalCodeUtils.updatePostalCode(this);
+ } catch (Exception e) {
+ // Do nothing. If the last known postal code is null, we'll show guided fragment to
+ // prompt users to input postal code before ConnectionTypeFragment is shown.
+ Log.i(TAG, "Can't get postal code:" + e);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+ @NonNull int[] grantResults) {
+ if (requestCode == PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
+ && Experiments.CLOUD_EPG.get()) {
+ try {
+ // Updating postal code takes time, therefore we should update postal code
+ // right after the permission is granted, so that the subsequent operations,
+ // especially EPG fetcher, could get the newly updated postal code.
+ PostalCodeUtils.updatePostalCode(this);
+ } catch (Exception e) {
+ // Do nothing
+ }
+ }
}
}
@Override
protected Fragment onCreateInitialFragment() {
- SetupFragment fragment = new WelcomeFragment();
- fragment.setShortDistance(SetupFragment.FRAGMENT_EXIT_TRANSITION
- | SetupFragment.FRAGMENT_REENTER_TRANSITION);
- return fragment;
+ if (mTunerType != null) {
+ SetupFragment fragment = new WelcomeFragment();
+ Bundle args = new Bundle();
+ args.putInt(KEY_TUNER_TYPE, mTunerType);
+ fragment.setArguments(args);
+ fragment.setShortDistance(SetupFragment.FRAGMENT_EXIT_TRANSITION
+ | SetupFragment.FRAGMENT_REENTER_TRANSITION);
+ return fragment;
+ } else {
+ return null;
+ }
}
@Override
@@ -101,34 +187,42 @@ public class TunerSetupActivity extends SetupActivity {
setResult(mLastScanFragment == null ? RESULT_CANCELED : RESULT_OK);
finish();
break;
- default: {
- SetupFragment fragment = new ConnectionTypeFragment();
- fragment.setShortDistance(SetupFragment.FRAGMENT_ENTER_TRANSITION
- | SetupFragment.FRAGMENT_RETURN_TRANSITION);
- showFragment(fragment, true);
+ default:
+ if (mNeedToShowPostalCodeFragment
+ || Features.ENABLE_CLOUD_EPG_REGION.isEnabled(
+ getApplicationContext())
+ && TextUtils.isEmpty(
+ PostalCodeUtils.getLastPostalCode(this))) {
+ // We cannot get postal code automatically. Postal code input fragment
+ // should always be shown even if users have input some valid postal
+ // code in this activity before.
+ mNeedToShowPostalCodeFragment = true;
+ showPostalCodeFragment();
+ } else {
+ showConnectionTypeFragment();
+ }
break;
- }
+ }
+ return true;
+ case PostalCodeFragment.ACTION_CATEGORY:
+ if (actionId == SetupMultiPaneFragment.ACTION_DONE
+ || actionId == SetupMultiPaneFragment.ACTION_SKIP) {
+ showConnectionTypeFragment();
}
return true;
case ConnectionTypeFragment.ACTION_CATEGORY:
- TunerHal hal = TunerHal.createInstance(getApplicationContext());
- if (hal == null) {
+ if (mTunerHalFactory.getOrCreate() == null) {
finish();
Toast.makeText(getApplicationContext(),
R.string.ut_channel_scan_tuner_unavailable,Toast.LENGTH_LONG).show();
return true;
}
- try {
- hal.close();
- } catch (Exception e) {
- Log.e(TAG, "Tuner hal close failed", e);
- return true;
- }
mLastScanFragment = new ScanFragment();
- Bundle args = new Bundle();
- args.putInt(ScanFragment.EXTRA_FOR_CHANNEL_SCAN_FILE,
+ Bundle args1 = new Bundle();
+ args1.putInt(ScanFragment.EXTRA_FOR_CHANNEL_SCAN_FILE,
CHANNEL_MAP_SCAN_FILE[actionId]);
- mLastScanFragment.setArguments(args);
+ args1.putInt(KEY_TUNER_TYPE, mTunerType);
+ mLastScanFragment.setArguments(args1);
showFragment(mLastScanFragment, true);
return true;
case ScanFragment.ACTION_CATEGORY:
@@ -137,7 +231,11 @@ public class TunerSetupActivity extends SetupActivity {
getFragmentManager().popBackStack();
return true;
case ScanFragment.ACTION_FINISH:
+ mTunerHalFactory.clear();
SetupFragment fragment = new ScanResultFragment();
+ Bundle args2 = new Bundle();
+ args2.putInt(KEY_TUNER_TYPE, mTunerType);
+ fragment.setArguments(args2);
fragment.setShortDistance(SetupFragment.FRAGMENT_EXIT_TRANSITION
| SetupFragment.FRAGMENT_REENTER_TRANSITION);
showFragment(fragment, true);
@@ -183,6 +281,14 @@ public class TunerSetupActivity extends SetupActivity {
return super.onKeyUp(keyCode, event);
}
+ @Override
+ public void onDestroy() {
+ if (mPreviousPostalCode != null && PostalCodeUtils.getLastPostalCode(this) == null) {
+ PostalCodeUtils.setLastPostalCode(this, mPreviousPostalCode);
+ }
+ super.onDestroy();
+ }
+
/**
* A callback to be invoked when the TvInputService is enabled or disabled.
*
@@ -190,17 +296,17 @@ public class TunerSetupActivity extends SetupActivity {
* @param enabled {@code true} for the {@link TunerTvInputService} to be enabled;
* otherwise {@code false}
*/
- public static void onTvInputEnabled(Context context, boolean enabled) {
- // Send a recommendation card for tuner setup if there's no channels and the tuner TV input
+ public static void onTvInputEnabled(Context context, boolean enabled, Integer tunerType) {
+ // Send a notification for tuner setup if there's no channels and the tuner TV input
// setup has been not done.
boolean channelScanDoneOnPreference = TunerPreferences.isScanDone(context);
int channelCountOnPreference = TunerPreferences.getScannedChannelCount(context);
if (enabled && !channelScanDoneOnPreference && channelCountOnPreference == 0) {
TunerPreferences.setShouldShowSetupActivity(context, true);
- sendRecommendationCard(context);
+ sendNotification(context, tunerType);
} else {
TunerPreferences.setShouldShowSetupActivity(context, false);
- cancelRecommendationCard(context);
+ cancelNotification(context);
}
}
@@ -213,7 +319,7 @@ public class TunerSetupActivity extends SetupActivity {
String inputId = TvContract.buildInputId(new ComponentName(context.getPackageName(),
TunerTvInputService.class.getName()));
- // Make an intent to launch the setup activity of USB tuner TV input.
+ // Make an intent to launch the setup activity of TV tuner input.
Intent intent = TvCommonUtils.createSetupIntent(
new Intent(context, TunerSetupActivity.class), inputId);
intent.putExtra(TvCommonConstants.EXTRA_INPUT_ID, inputId);
@@ -224,6 +330,27 @@ public class TunerSetupActivity extends SetupActivity {
}
/**
+ * Gets the currently used tuner HAL.
+ */
+ TunerHal getTunerHal() {
+ return mTunerHalFactory.getOrCreate();
+ }
+
+ /**
+ * Generates tuner HAL.
+ */
+ void generateTunerHal() {
+ mTunerHalFactory.generate();
+ }
+
+ /**
+ * Clears the currently used tuner HAL.
+ */
+ void clearTunerHal() {
+ mTunerHalFactory.clear();
+ }
+
+ /**
* Returns a {@link PendingIntent} to launch the tuner TV input service.
*
* @param context a {@link Context} instance
@@ -233,34 +360,53 @@ public class TunerSetupActivity extends SetupActivity {
PendingIntent.FLAG_UPDATE_CURRENT);
}
+ private static void sendNotification(Context context, Integer tunerType) {
+ SoftPreconditions.checkState(tunerType != null, TAG,
+ "tunerType is null when send notification");
+ if (tunerType == null) {
+ return;
+ }
+ Resources resources = context.getResources();
+ String contentTitle = resources.getString(R.string.ut_setup_notification_content_title);
+ int contentTextId = 0;
+ switch (tunerType) {
+ case TunerHal.TUNER_TYPE_BUILT_IN:
+ contentTextId = R.string.bt_setup_notification_content_text;
+ break;
+ case TunerHal.TUNER_TYPE_USB:
+ contentTextId = R.string.ut_setup_notification_content_text;
+ break;
+ case TunerHal.TUNER_TYPE_NETWORK:
+ contentTextId = R.string.nt_setup_notification_content_text;
+ break;
+ }
+ String contentText = resources.getString(contentTextId);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ sendNotificationInternal(context, contentTitle, contentText);
+ } else {
+ Bitmap largeIcon = BitmapFactory.decodeResource(resources,
+ R.drawable.recommendation_antenna);
+ sendRecommendationCard(context, contentTitle, contentText, largeIcon);
+ }
+ }
+
/**
* Sends the recommendation card to start the tuner TV input setup activity.
*
* @param context a {@link Context} instance
*/
- private static void sendRecommendationCard(Context context) {
- Resources resources = context.getResources();
- String focusedTitle = resources.getString(
- R.string.ut_setup_recommendation_card_focused_title);
- String title;
- if (TunerInputInfoUtils.isBuiltInTuner(context)) {
- title = resources.getString(R.string.bt_setup_recommendation_card_title);
- } else {
- title = resources.getString(R.string.ut_setup_recommendation_card_title);
- }
- Bitmap largeIcon = BitmapFactory.decodeResource(resources,
- R.drawable.recommendation_antenna);
-
+ private static void sendRecommendationCard(Context context, String contentTitle,
+ String contentText, Bitmap largeIcon) {
// Build and send the notification.
Notification notification = new NotificationCompat.BigPictureStyle(
new NotificationCompat.Builder(context)
.setAutoCancel(false)
- .setContentTitle(focusedTitle)
- .setContentText(title)
- .setContentInfo(title)
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .setContentInfo(contentText)
.setCategory(Notification.CATEGORY_RECOMMENDATION)
.setLargeIcon(largeIcon)
- .setSmallIcon(resources.getIdentifier(
+ .setSmallIcon(context.getResources().getIdentifier(
TAG_ICON, TAG_DRAWABLE, context.getPackageName()))
.setContentIntent(createPendingIntentForSetupActivity(context)))
.build();
@@ -269,14 +415,129 @@ public class TunerSetupActivity extends SetupActivity {
notificationManager.notify(NOTIFY_TAG, NOTIFY_ID, notification);
}
+ private static void sendNotificationInternal(Context context, String contentTitle,
+ String contentText) {
+ NotificationManager notificationManager = (NotificationManager) context.getSystemService(
+ Context.NOTIFICATION_SERVICE);
+ notificationManager.createNotificationChannel(new NotificationChannel(
+ TUNER_SET_UP_NOTIFICATION_CHANNEL_ID,
+ context.getResources().getString(R.string.ut_setup_notification_channel_name),
+ NotificationManager.IMPORTANCE_HIGH));
+ Notification notification = new Notification.Builder(
+ context, TUNER_SET_UP_NOTIFICATION_CHANNEL_ID)
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .setSmallIcon(context.getResources().getIdentifier(
+ TAG_ICON, TAG_DRAWABLE, context.getPackageName()))
+ .setContentIntent(createPendingIntentForSetupActivity(context))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .extend(new Notification.TvExtender())
+ .build();
+ notificationManager.notify(NOTIFY_TAG, NOTIFY_ID, notification);
+ }
+
+ private void showPostalCodeFragment() {
+ SetupFragment fragment = new PostalCodeFragment();
+ fragment.setShortDistance(SetupFragment.FRAGMENT_ENTER_TRANSITION
+ | SetupFragment.FRAGMENT_RETURN_TRANSITION);
+ showFragment(fragment, true);
+ }
+
+ private void showConnectionTypeFragment() {
+ SetupFragment fragment = new ConnectionTypeFragment();
+ fragment.setShortDistance(SetupFragment.FRAGMENT_ENTER_TRANSITION
+ | SetupFragment.FRAGMENT_RETURN_TRANSITION);
+ showFragment(fragment, true);
+ }
+
/**
- * Cancels the previously shown recommendation card.
+ * Cancels the previously shown notification.
*
* @param context a {@link Context} instance
*/
- public static void cancelRecommendationCard(Context context) {
+ public static void cancelNotification(Context context) {
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(NOTIFY_TAG, NOTIFY_ID);
}
-}
+
+ @VisibleForTesting
+ static class TunerHalFactory {
+ private Context mContext;
+ @VisibleForTesting
+ TunerHal mTunerHal;
+ private GenerateTunerHalTask mGenerateTunerHalTask;
+ private final Executor mExecutor;
+
+ TunerHalFactory(Context context) {
+ this(context, AsyncTask.SERIAL_EXECUTOR);
+ }
+
+ TunerHalFactory(Context context, Executor executor) {
+ mContext = context;
+ mExecutor = executor;
+ }
+
+ /**
+ * Returns tuner HAL currently used. If it's {@code null} and tuner HAL is not generated
+ * before, tries to generate it synchronously.
+ */
+ @WorkerThread
+ TunerHal getOrCreate() {
+ if (mGenerateTunerHalTask != null
+ && mGenerateTunerHalTask.getStatus() != AsyncTask.Status.FINISHED) {
+ try {
+ return mGenerateTunerHalTask.get();
+ } catch (Exception e) {
+ Log.e(TAG, "Cannot get Tuner HAL: " + e);
+ }
+ } else if (mGenerateTunerHalTask == null && mTunerHal == null) {
+ mTunerHal = createInstance();
+ }
+ return mTunerHal;
+ }
+
+ /**
+ * Generates tuner hal for scanning with asynchronous tasks.
+ */
+ @MainThread
+ void generate() {
+ if (mGenerateTunerHalTask == null && mTunerHal == null) {
+ mGenerateTunerHalTask = new GenerateTunerHalTask();
+ mGenerateTunerHalTask.executeOnExecutor(mExecutor);
+ }
+ }
+
+ /**
+ * Clears the currently used tuner hal.
+ */
+ @MainThread
+ void clear() {
+ if (mGenerateTunerHalTask != null) {
+ mGenerateTunerHalTask.cancel(true);
+ mGenerateTunerHalTask = null;
+ }
+ if (mTunerHal != null) {
+ AutoCloseableUtils.closeQuietly(mTunerHal);
+ mTunerHal = null;
+ }
+ }
+
+ @WorkerThread
+ protected TunerHal createInstance() {
+ return TunerHal.createInstance(mContext);
+ }
+
+ class GenerateTunerHalTask extends AsyncTask<Void, Void, TunerHal> {
+ @Override
+ protected TunerHal doInBackground(Void... args) {
+ return createInstance();
+ }
+
+ @Override
+ protected void onPostExecute(TunerHal tunerHal) {
+ mTunerHal = tunerHal;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/tuner/setup/WelcomeFragment.java b/src/com/android/tv/tuner/setup/WelcomeFragment.java
index 7e809411..feae1ec9 100644
--- a/src/com/android/tv/tuner/setup/WelcomeFragment.java
+++ b/src/com/android/tv/tuner/setup/WelcomeFragment.java
@@ -18,18 +18,14 @@ package com.android.tv.tuner.setup;
import android.os.Bundle;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
import android.support.v17.leanback.widget.GuidedAction;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
import com.android.tv.common.ui.setup.SetupGuidedStepFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.tuner.R;
+import com.android.tv.tuner.TunerHal;
import com.android.tv.tuner.TunerPreferences;
-import com.android.tv.tuner.util.TunerInputInfoUtils;
-
import java.util.List;
/**
@@ -41,7 +37,9 @@ public class WelcomeFragment extends SetupMultiPaneFragment {
@Override
protected SetupGuidedStepFragment onCreateContentFragment() {
- return new ContentFragment();
+ ContentFragment fragment = new ContentFragment();
+ fragment.setArguments(getArguments());
+ return fragment;
}
@Override
@@ -58,11 +56,10 @@ public class WelcomeFragment extends SetupMultiPaneFragment {
private int mChannelCountOnPreference;
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- mChannelCountOnPreference = TunerPreferences
- .getScannedChannelCount(getActivity().getApplicationContext());
- return super.onCreateView(inflater, container, savedInstanceState);
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ mChannelCountOnPreference =
+ TunerPreferences.getScannedChannelCount(getActivity().getApplicationContext());
+ super.onCreate(savedInstanceState);
}
@NonNull
@@ -70,20 +67,33 @@ public class WelcomeFragment extends SetupMultiPaneFragment {
public Guidance onCreateGuidance(Bundle savedInstanceState) {
String title;
String description;
+ int tunerType = getArguments().getInt(TunerSetupActivity.KEY_TUNER_TYPE,
+ TunerHal.TUNER_TYPE_BUILT_IN);
if (mChannelCountOnPreference == 0) {
- if (TunerInputInfoUtils.isBuiltInTuner(getActivity())) {
- title = getString(R.string.bt_setup_new_title);
- description = getString(R.string.bt_setup_new_description);
- } else {
- title = getString(R.string.ut_setup_new_title);
- description = getString(R.string.ut_setup_new_description);
+ switch (tunerType) {
+ case TunerHal.TUNER_TYPE_USB:
+ title = getString(R.string.ut_setup_new_title);
+ description = getString(R.string.ut_setup_new_description);
+ break;
+ case TunerHal.TUNER_TYPE_NETWORK:
+ title = getString(R.string.nt_setup_new_title);
+ description = getString(R.string.nt_setup_new_description);
+ break;
+ default:
+ title = getString(R.string.bt_setup_new_title);
+ description = getString(R.string.bt_setup_new_description);
}
} else {
title = getString(R.string.bt_setup_again_title);
- if (TunerInputInfoUtils.isBuiltInTuner(getActivity())) {
- description = getString(R.string.bt_setup_again_description);
- } else {
- description = getString(R.string.ut_setup_again_description);
+ switch (tunerType) {
+ case TunerHal.TUNER_TYPE_USB:
+ description = getString(R.string.ut_setup_again_description);
+ break;
+ case TunerHal.TUNER_TYPE_NETWORK:
+ description = getString(R.string.nt_setup_again_description);
+ break;
+ default:
+ description = getString(R.string.bt_setup_again_description);
}
}
return new Guidance(title, description, null, null);
diff --git a/src/com/android/tv/tuner/source/FileTsStreamer.java b/src/com/android/tv/tuner/source/FileTsStreamer.java
index 14997ee4..f17dd46b 100644
--- a/src/com/android/tv/tuner/source/FileTsStreamer.java
+++ b/src/com/android/tv/tuner/source/FileTsStreamer.java
@@ -16,12 +16,14 @@
package com.android.tv.tuner.source;
+import android.content.Context;
import android.os.Environment;
import android.util.Log;
import android.util.SparseBooleanArray;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.upstream.DataSpec;
+import com.android.tv.Features;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.tuner.ChannelScanFileParser.ScanChannel;
import com.android.tv.tuner.data.TunerChannel;
@@ -60,6 +62,7 @@ public class FileTsStreamer implements TsStreamer {
private final Object mCircularBufferMonitor = new Object();
private final byte[] mCircularBuffer = new byte[CIRCULAR_BUFFER_SIZE];
private final FileSourceEventDetector mEventDetector;
+ private final Context mContext;
private long mBytesFetched;
private long mLastReadPosition;
@@ -120,8 +123,11 @@ public class FileTsStreamer implements TsStreamer {
* Creates {@link TsStreamer} for scanning & playing MPEG-2 TS file.
* @param eventListener the listener for channel & program information
*/
- public FileTsStreamer(EventDetector.EventListener eventListener) {
- mEventDetector = new FileSourceEventDetector(eventListener);
+ public FileTsStreamer(EventDetector.EventListener eventListener, Context context) {
+ mEventDetector =
+ new FileSourceEventDetector(
+ eventListener, Features.ENABLE_FILE_DVB.isEnabled(context));
+ mContext = context;
}
@Override
@@ -132,8 +138,12 @@ public class FileTsStreamer implements TsStreamer {
return false;
}
mEventDetector.start(mSource, FileSourceEventDetector.ALL_PROGRAM_NUMBERS);
- mSource.addPidFilter(TsParser.ATSC_SI_BASE_PID);
mSource.addPidFilter(TsParser.PAT_PID);
+ mSource.addPidFilter(TsParser.ATSC_SI_BASE_PID);
+ if (Features.ENABLE_FILE_DVB.isEnabled(mContext)) {
+ mSource.addPidFilter(TsParser.DVB_EIT_PID);
+ mSource.addPidFilter(TsParser.DVB_SDT_PID);
+ }
synchronized (mCircularBufferMonitor) {
if (mStreaming) {
return true;
@@ -160,8 +170,12 @@ public class FileTsStreamer implements TsStreamer {
mSource.addPidFilter(i);
}
mSource.addPidFilter(channel.getPcrPid());
- mSource.addPidFilter(TsParser.ATSC_SI_BASE_PID);
mSource.addPidFilter(TsParser.PAT_PID);
+ mSource.addPidFilter(TsParser.ATSC_SI_BASE_PID);
+ if (Features.ENABLE_FILE_DVB.isEnabled(mContext)) {
+ mSource.addPidFilter(TsParser.DVB_EIT_PID);
+ mSource.addPidFilter(TsParser.DVB_SDT_PID);
+ }
synchronized (mCircularBufferMonitor) {
if (mStreaming) {
return true;
@@ -256,7 +270,7 @@ public class FileTsStreamer implements TsStreamer {
* Returns whether the current pid filter is empty or not.
*/
public boolean isFilterEmpty() {
- return mPids.size() > 0;
+ return mPids.size() == 0;
}
/**
diff --git a/src/com/android/tv/tuner/source/TsDataSourceManager.java b/src/com/android/tv/tuner/source/TsDataSourceManager.java
index ccbb75ba..16be7582 100644
--- a/src/com/android/tv/tuner/source/TsDataSourceManager.java
+++ b/src/com/android/tv/tuner/source/TsDataSourceManager.java
@@ -17,9 +17,11 @@
package com.android.tv.tuner.source;
import android.content.Context;
+import android.support.annotation.VisibleForTesting;
-import com.android.tv.tuner.data.nano.Channel;
+import com.android.tv.tuner.TunerHal;
import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Channel;
import com.android.tv.tuner.tvinput.EventDetector;
import java.util.Map;
@@ -31,8 +33,6 @@ import java.util.concurrent.ConcurrentHashMap;
* One TsDataSourceManager should be created for per session.
*/
public class TsDataSourceManager {
- private static String TAG = "TsDataSourceManager";
-
private static final Object sLock = new Object();
private static final Map<TsDataSource, TsStreamer> sTsStreamers =
new ConcurrentHashMap<>();
@@ -80,7 +80,7 @@ public class TsDataSourceManager {
if (mIsRecording) {
return null;
}
- FileTsStreamer streamer = new FileTsStreamer(eventListener);
+ FileTsStreamer streamer = new FileTsStreamer(eventListener, context);
if (streamer.startStream(channel)) {
TsDataSource source = streamer.createDataSource();
sTsStreamers.put(source, streamer);
@@ -127,6 +127,14 @@ public class TsDataSourceManager {
}
/**
+ * Add tuner hal into TunerTsStreamerManager for test.
+ */
+ @VisibleForTesting
+ public void addTunerHalForTest(TunerHal tunerHal) {
+ mTunerStreamerManager.addTunerHal(tunerHal, mId);
+ }
+
+ /**
* Releases persistent resources.
*/
public void release() {
diff --git a/src/com/android/tv/tuner/source/TunerTsStreamer.java b/src/com/android/tv/tuner/source/TunerTsStreamer.java
index b24048e6..843cbdb7 100644
--- a/src/com/android/tv/tuner/source/TunerTsStreamer.java
+++ b/src/com/android/tv/tuner/source/TunerTsStreamer.java
@@ -18,6 +18,7 @@ package com.android.tv.tuner.source;
import android.content.Context;
import android.util.Log;
+import android.util.Pair;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.upstream.DataSpec;
@@ -30,6 +31,7 @@ import com.android.tv.tuner.tvinput.EventDetector;
import com.android.tv.tuner.tvinput.EventDetector.EventListener;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
@@ -42,23 +44,27 @@ public class TunerTsStreamer implements TsStreamer {
private static final int MIN_READ_UNIT = 1500;
private static final int READ_BUFFER_SIZE = MIN_READ_UNIT * 10; // ~15KB
private static final int CIRCULAR_BUFFER_SIZE = MIN_READ_UNIT * 20000; // ~ 30MB
+ private static final int TS_PACKET_SIZE = 188;
private static final int READ_TIMEOUT_MS = 5000; // 5 secs.
private static final int BUFFER_UNDERRUN_SLEEP_MS = 10;
+ private static final int READ_ERROR_STREAMING_ENDED = -1;
+ private static final int READ_ERROR_BUFFER_OVERWRITTEN = -2;
private final Object mCircularBufferMonitor = new Object();
private final byte[] mCircularBuffer = new byte[CIRCULAR_BUFFER_SIZE];
private long mBytesFetched;
private final AtomicLong mLastReadPosition = new AtomicLong();
- private boolean mEndOfStreamSent;
private boolean mStreaming;
private final TunerHal mTunerHal;
private TunerChannel mChannel;
private Thread mStreamingThread;
private final EventDetector mEventDetector;
+ private final List<Pair<EventListener, Boolean>> mEventListenerActions = new ArrayList<>();
private final TsStreamWriter mTsStreamWriter;
+ private String mChannelNumber;
public static class TunerDataSource extends TsDataSource {
private final TunerTsStreamer mTsStreamer;
@@ -103,6 +109,15 @@ public class TunerTsStreamer implements TsStreamer {
offset, readLength);
if (ret > 0) {
mLastReadPosition.addAndGet(ret);
+ } else if (ret == READ_ERROR_BUFFER_OVERWRITTEN) {
+ long currentPosition = mStartBufferedPosition + mLastReadPosition.get();
+ long endPosition = mTsStreamer.getBufferedPosition();
+ long diff = ((endPosition - currentPosition + TS_PACKET_SIZE - 1) / TS_PACKET_SIZE)
+ * TS_PACKET_SIZE;
+ Log.w(TAG, "Demux position jump by overwritten buffer: " + diff);
+ mStartBufferedPosition = currentPosition + diff;
+ mLastReadPosition.set(0);
+ return 0;
}
return ret;
}
@@ -114,7 +129,10 @@ public class TunerTsStreamer implements TsStreamer {
*/
public TunerTsStreamer(TunerHal tunerHal, EventListener eventListener, Context context) {
mTunerHal = tunerHal;
- mEventDetector = new EventDetector(mTunerHal, eventListener);
+ mEventDetector = new EventDetector(mTunerHal);
+ if (eventListener != null) {
+ mEventDetector.registerListener(eventListener);
+ }
mTsStreamWriter = context != null && TunerPreferences.getStoreTsStream(context) ?
new TsStreamWriter(context) : null;
}
@@ -125,7 +143,8 @@ public class TunerTsStreamer implements TsStreamer {
@Override
public boolean startStream(TunerChannel channel) {
- if (mTunerHal.tune(channel.getFrequency(), channel.getModulation())) {
+ if (mTunerHal.tune(channel.getFrequency(), channel.getModulation(),
+ channel.getDisplayNumber(false))) {
if (channel.hasVideo()) {
mTunerHal.addPidFilter(channel.getVideoPid(),
TunerHal.FILTER_TYPE_VIDEO);
@@ -148,6 +167,7 @@ public class TunerTsStreamer implements TsStreamer {
channel.getProgramNumber());
}
mChannel = channel;
+ mChannelNumber = channel.getDisplayNumber();
synchronized (mCircularBufferMonitor) {
if (mStreaming) {
Log.w(TAG, "Streaming should be stopped before start streaming");
@@ -156,7 +176,6 @@ public class TunerTsStreamer implements TsStreamer {
mStreaming = true;
mBytesFetched = 0;
mLastReadPosition.set(0L);
- mEndOfStreamSent = false;
}
if (mTsStreamWriter != null) {
mTsStreamWriter.setChannel(mChannel);
@@ -172,7 +191,7 @@ public class TunerTsStreamer implements TsStreamer {
@Override
public boolean startStream(ChannelScanFileParser.ScanChannel channel) {
- if (mTunerHal.tune(channel.frequency, channel.modulation)) {
+ if (mTunerHal.tune(channel.frequency, channel.modulation, null)) {
mEventDetector.startDetecting(
channel.frequency, channel.modulation, EventDetector.ALL_PROGRAM_NUMBERS);
synchronized (mCircularBufferMonitor) {
@@ -183,7 +202,6 @@ public class TunerTsStreamer implements TsStreamer {
mStreaming = true;
mBytesFetched = 0;
mLastReadPosition.set(0L);
- mEndOfStreamSent = false;
}
mStreamingThread = new StreamingThread();
mStreamingThread.start();
@@ -258,6 +276,26 @@ public class TunerTsStreamer implements TsStreamer {
}
}
+ public String getStreamerInfo() {
+ return "Channel: " + mChannelNumber + ", Streaming: " + mStreaming;
+ }
+
+ public void registerListener(EventListener listener) {
+ if (mEventDetector != null && listener != null) {
+ synchronized (mEventListenerActions) {
+ mEventListenerActions.add(new Pair<>(listener, true));
+ }
+ }
+ }
+
+ public void unregisterListener(EventListener listener) {
+ if (mEventDetector != null) {
+ synchronized (mEventListenerActions) {
+ mEventListenerActions.add(new Pair(listener, false));
+ }
+ }
+ }
+
private class StreamingThread extends Thread {
@Override
public void run() {
@@ -271,6 +309,20 @@ public class TunerTsStreamer implements TsStreamer {
}
}
+ if (mEventDetector != null) {
+ synchronized (mEventListenerActions) {
+ for (Pair listenerAction : mEventListenerActions) {
+ EventListener listener = (EventListener) listenerAction.first;
+ if ((boolean) listenerAction.second) {
+ mEventDetector.registerListener(listener);
+ } else {
+ mEventDetector.unregisterListener(listener);
+ }
+ }
+ mEventListenerActions.clear();
+ }
+ }
+
int bytesWritten = mTunerHal.readTsStream(dataBuffer, dataBuffer.length);
if (bytesWritten <= 0) {
try {
@@ -321,21 +373,14 @@ public class TunerTsStreamer implements TsStreamer {
* @throws IOException
*/
public int readAt(long pos, byte[] buffer, int offset, int amount) throws IOException {
- long readStartTime = System.currentTimeMillis();
while (true) {
synchronized (mCircularBufferMonitor) {
- if (mEndOfStreamSent || !mStreaming) {
- return -1;
+ if (!mStreaming) {
+ return READ_ERROR_STREAMING_ENDED;
}
if (mBytesFetched - CIRCULAR_BUFFER_SIZE > pos) {
- Log.e(TAG, "Demux is requesting the data which is already overwritten.");
- return -1;
- }
- if (System.currentTimeMillis() - readStartTime > READ_TIMEOUT_MS) {
- // Nothing was received during READ_TIMEOUT_MS before.
- mEndOfStreamSent = true;
- mCircularBufferMonitor.notifyAll();
- return -1;
+ Log.w(TAG, "Demux is requesting the data which is already overwritten.");
+ return READ_ERROR_BUFFER_OVERWRITTEN;
}
if (mBytesFetched < pos + amount) {
try {
diff --git a/src/com/android/tv/tuner/source/TunerTsStreamerManager.java b/src/com/android/tv/tuner/source/TunerTsStreamerManager.java
index cf1f6dcf..258a4d86 100644
--- a/src/com/android/tv/tuner/source/TunerTsStreamerManager.java
+++ b/src/com/android/tv/tuner/source/TunerTsStreamerManager.java
@@ -42,6 +42,7 @@ class TunerTsStreamerManager {
private final Object mCancelLock = new Object();
private final StreamerFinder mStreamerFinder = new StreamerFinder();
private final Map<Integer, TsStreamerCreator> mCreators = new HashMap<>();
+ private final Map<Integer, EventDetector.EventListener> mListeners = new HashMap<>();
private final Map<TsDataSource, TunerTsStreamer> mSourceToStreamerMap = new HashMap<>();
private final TunerHalManager mTunerHalManager = new TunerHalManager();
private static TunerTsStreamerManager sInstance;
@@ -68,6 +69,8 @@ class TunerTsStreamerManager {
mStreamerFinder.appendSessionLocked(channel, sessionId);
TunerTsStreamer streamer = mStreamerFinder.getStreamerLocked(channel);
TsDataSource source = streamer.createDataSource();
+ mListeners.put(sessionId, listener);
+ streamer.registerListener(listener);
mSourceToStreamerMap.put(source, streamer);
return source;
}
@@ -83,6 +86,7 @@ class TunerTsStreamerManager {
if (!creator.isCancelledLocked()) {
mStreamerFinder.putLocked(channel, sessionId, streamer);
TsDataSource source = streamer.createDataSource();
+ mListeners.put(sessionId, listener);
mSourceToStreamerMap.put(source, streamer);
return source;
}
@@ -104,6 +108,8 @@ class TunerTsStreamerManager {
if (streamer == null) {
return;
}
+ EventDetector.EventListener listener = mListeners.remove(sessionId);
+ streamer.unregisterListener(listener);
TunerChannel channel = streamer.getChannel();
SoftPreconditions.checkState(channel != null);
mStreamerFinder.removeSessionLocked(channel, sessionId);
@@ -125,6 +131,13 @@ class TunerTsStreamerManager {
}
}
+ /**
+ * Add tuner hal into TunerHalManager for test.
+ */
+ void addTunerHal(TunerHal tunerHal, int sessionId) {
+ mTunerHalManager.addTunerHal(tunerHal, sessionId);
+ }
+
synchronized void release(int sessionId) {
mTunerHalManager.releaseCachedHal(sessionId);
}
@@ -261,16 +274,16 @@ class TunerTsStreamerManager {
}
private void releaseTunerHal(TunerHal hal, int sessionId, boolean reuse) {
- if (!reuse) {
+ if (!reuse || !hal.isReusable()) {
AutoCloseableUtils.closeQuietly(hal);
return;
}
TunerHal cachedHal = mTunerHals.get(sessionId);
if (cachedHal != hal) {
mTunerHals.put(sessionId, hal);
- }
- if (cachedHal != null && cachedHal != hal) {
- AutoCloseableUtils.closeQuietly(cachedHal);
+ if (cachedHal != null) {
+ AutoCloseableUtils.closeQuietly(cachedHal);
+ }
}
}
@@ -283,5 +296,9 @@ class TunerTsStreamerManager {
AutoCloseableUtils.closeQuietly(hal);
}
}
+
+ private void addTunerHal(TunerHal tunerHal, int sessionId) {
+ mTunerHals.put(sessionId, tunerHal);
+ }
}
} \ No newline at end of file
diff --git a/src/com/android/tv/tuner/ts/SectionParser.java b/src/com/android/tv/tuner/ts/SectionParser.java
index 8c1f6a1b..e1f890f3 100644
--- a/src/com/android/tv/tuner/ts/SectionParser.java
+++ b/src/com/android/tv/tuner/ts/SectionParser.java
@@ -18,11 +18,12 @@ package com.android.tv.tuner.ts;
import android.media.tv.TvContentRating;
import android.media.tv.TvContract.Programs.Genres;
+import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
-import com.android.tv.tuner.data.nano.Channel;
import com.android.tv.tuner.data.PsiData.PatItem;
import com.android.tv.tuner.data.PsiData.PmtItem;
import com.android.tv.tuner.data.PsipData.Ac3AudioDescriptor;
@@ -34,24 +35,32 @@ import com.android.tv.tuner.data.PsipData.ExtendedChannelNameDescriptor;
import com.android.tv.tuner.data.PsipData.GenreDescriptor;
import com.android.tv.tuner.data.PsipData.Iso639LanguageDescriptor;
import com.android.tv.tuner.data.PsipData.MgtItem;
+import com.android.tv.tuner.data.PsipData.ParentalRatingDescriptor;
import com.android.tv.tuner.data.PsipData.PsipSection;
import com.android.tv.tuner.data.PsipData.RatingRegion;
import com.android.tv.tuner.data.PsipData.RegionalRating;
+import com.android.tv.tuner.data.PsipData.SdtItem;
+import com.android.tv.tuner.data.PsipData.ServiceDescriptor;
+import com.android.tv.tuner.data.PsipData.ShortEventDescriptor;
import com.android.tv.tuner.data.PsipData.TsDescriptor;
import com.android.tv.tuner.data.PsipData.VctItem;
+import com.android.tv.tuner.data.nano.Channel;
import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.util.ByteArrayBuffer;
+import com.android.tv.tuner.util.ConvertUtils;
import com.ibm.icu.text.UnicodeDecompressor;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
+import java.util.Calendar;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* Parses ATSC PSIP sections.
@@ -68,6 +77,13 @@ public class SectionParser {
private static final byte TABLE_ID_EIT = (byte) 0xcb;
private static final byte TABLE_ID_ETT = (byte) 0xcc;
+ // Table id for DVB
+ private static final byte TABLE_ID_SDT = (byte) 0x42;
+ private static final byte TABLE_ID_DVB_ACTUAL_P_F_EIT = (byte) 0x4e;
+ private static final byte TABLE_ID_DVB_OTHER_P_F_EIT = (byte) 0x4f;
+ private static final byte TABLE_ID_DVB_ACTUAL_SCHEDULE_EIT = (byte) 0x50;
+ private static final byte TABLE_ID_DVB_OTHER_SCHEDULE_EIT = (byte) 0x60;
+
// For details of the structure for the tags of descriptors, see ATSC A/65 Table 6.25.
public static final int DESCRIPTOR_TAG_ISO639LANGUAGE = 0x0a;
public static final int DESCRIPTOR_TAG_CAPTION_SERVICE = 0x86;
@@ -76,6 +92,12 @@ public class SectionParser {
public static final int DESCRIPTOR_TAG_EXTENDED_CHANNEL_NAME = 0xa0;
public static final int DESCRIPTOR_TAG_GENRE = 0xab;
+ // For details of the structure for the tags of DVB descriptors, see DVB Document A038 Table 12.
+ public static final int DVB_DESCRIPTOR_TAG_SERVICE = 0x48;
+ public static final int DVB_DESCRIPTOR_TAG_SHORT_EVENT = 0X4d;
+ public static final int DVB_DESCRIPTOR_TAG_CONTENT = 0x54;
+ public static final int DVB_DESCRIPTOR_TAG_PARENTAL_RATING = 0x55;
+
private static final byte COMPRESSION_TYPE_NO_COMPRESSION = (byte) 0x00;
private static final byte MODE_SELECTED_UNICODE_RANGE_1 = (byte) 0x00; // 0x0000 - 0x00ff
private static final byte MODE_UTF16 = (byte) 0x3f;
@@ -88,17 +110,57 @@ public class SectionParser {
// The following values are defined in the live channels app.
// See https://developer.android.com/reference/android/media/tv/TvContentRating.html.
+ private static final String RATING_DOMAIN = "com.android.tv";
private static final String RATING_REGION_RATING_SYSTEM_US_TV = "US_TV";
+ private static final String RATING_REGION_RATING_SYSTEM_US_MV = "US_MV";
private static final String RATING_REGION_RATING_SYSTEM_KR_TV = "KR_TV";
private static final String[] RATING_REGION_TABLE_US_TV = {
"US_TV_Y", "US_TV_Y7", "US_TV_G", "US_TV_PG", "US_TV_14", "US_TV_MA"
};
+ private static final String[] RATING_REGION_TABLE_US_MV = {
+ "US_MV_G", "US_MV_PG", "US_MV_PG13", "US_MV_R", "US_MV_NC17"
+ };
+
private static final String[] RATING_REGION_TABLE_KR_TV = {
"KR_TV_ALL", "KR_TV_7", "KR_TV_12", "KR_TV_15", "KR_TV_19"
};
+ private static final String[] RATING_REGION_TABLE_US_TV_SUBRATING = {
+ "US_TV_D", "US_TV_L", "US_TV_S", "US_TV_V", "US_TV_FV"
+ };
+
+ // According to ANSI-CEA-766-D
+ private static final int VALUE_US_TV_Y = 1;
+ private static final int VALUE_US_TV_Y7 = 2;
+ private static final int VALUE_US_TV_NONE = 1;
+ private static final int VALUE_US_TV_G = 2;
+ private static final int VALUE_US_TV_PG = 3;
+ private static final int VALUE_US_TV_14 = 4;
+ private static final int VALUE_US_TV_MA = 5;
+
+ private static final int DIMENSION_US_TV_RATING = 0;
+ private static final int DIMENSION_US_TV_D = 1;
+ private static final int DIMENSION_US_TV_L = 2;
+ private static final int DIMENSION_US_TV_S = 3;
+ private static final int DIMENSION_US_TV_V = 4;
+ private static final int DIMENSION_US_TV_Y = 5;
+ private static final int DIMENSION_US_TV_FV = 6;
+ private static final int DIMENSION_US_MV_RATING = 7;
+
+ private static final int VALUE_US_MV_G = 2;
+ private static final int VALUE_US_MV_PG = 3;
+ private static final int VALUE_US_MV_PG13 = 4;
+ private static final int VALUE_US_MV_R = 5;
+ private static final int VALUE_US_MV_NC17 = 6;
+ private static final int VALUE_US_MV_X = 7;
+
+ private static final String STRING_US_TV_Y = "US_TV_Y";
+ private static final String STRING_US_TV_Y7 = "US_TV_Y7";
+ private static final String STRING_US_TV_FV = "US_TV_FV";
+
+
/*
* The following CRC table is from the code generated by the following command.
* $ python pycrc.py --model crc-32-mpeg --algorithm table-driven --generate c
@@ -330,6 +392,7 @@ public class SectionParser {
void onVctParsed(List<VctItem> items, int sectionNumber, int lastSectionNumber);
void onEitParsed(int sourceId, List<EitItem> items);
void onEttParsed(int sourceId, List<EttItem> descriptions);
+ void onSdtParsed(List<SdtItem> items);
}
private final OutputListener mListener;
@@ -367,6 +430,10 @@ public class SectionParser {
mParsedEttItems.clear();
}
+ public void resetVersionNumbers() {
+ mSectionVersionMap.clear();
+ }
+
private void parseSection(byte[] data) {
if (!checkSanity(data)) {
Log.d(TAG, "Bad CRC!");
@@ -410,6 +477,13 @@ public class SectionParser {
case TABLE_ID_ETT:
result = parseETT(data);
break;
+ case TABLE_ID_SDT:
+ result = parseSDT(data);
+ break;
+ case TABLE_ID_DVB_ACTUAL_P_F_EIT:
+ case TABLE_ID_DVB_ACTUAL_SCHEDULE_EIT:
+ result = parseDVBEIT(data);
+ break;
default:
break;
}
@@ -510,10 +584,8 @@ public class SectionParser {
pos += 11 + descriptorsLength;
results.add(new MgtItem(tableType, tableTypePid));
}
- if ((data[pos] & 0xf0) != 0xf0) {
- Log.e(TAG, "Broken MGT.");
- return false;
- }
+ // Skip the remaining descriptor part which we don't use.
+
if (mListener != null) {
mListener.onMgtParsed(results);
}
@@ -704,6 +776,127 @@ public class SectionParser {
return true;
}
+ private boolean parseSDT(byte[] data) {
+ // For details of the structure for SDT, see DVB Document A038 Table 5.
+ if (DEBUG) {
+ Log.d(TAG, "SDT id discovered");
+ }
+ if (data.length <= 11) {
+ Log.e(TAG, "Broken SDT.");
+ return false;
+ }
+ if ((data[1] & 0x80) >> 7 != 1) {
+ Log.e(TAG, "Broken SDT, section syntax indicator error.");
+ return false;
+ }
+ int sectionLength = ((data[1] & 0x0f) << 8) | (data[2] & 0xff);
+ int transportStreamId = ((data[3] & 0xff) << 8) | (data[4] & 0xff);
+ int originalNetworkId = ((data[8] & 0xff) << 8) | (data[9] & 0xff);
+ int pos = 11;
+ if (sectionLength + 3 > data.length) {
+ Log.e(TAG, "Broken SDT.");
+ }
+ List<SdtItem> sdtItems = new ArrayList<>();
+ while (pos + 9 < data.length) {
+ int serviceId = ((data[pos] & 0xff) << 8) | (data[pos + 1] & 0xff);
+ int descriptorsLength = ((data[pos + 3] & 0x0f) << 8) | (data[pos + 4] & 0xff);
+ pos += 5;
+ List<TsDescriptor> descriptors = parseDescriptors(data, pos, pos + descriptorsLength);
+ List<ServiceDescriptor> serviceDescriptors = generateServiceDescriptors(descriptors);
+ String serviceName = "";
+ String serviceProviderName = "";
+ int serviceType = 0;
+ for (ServiceDescriptor serviceDescriptor : serviceDescriptors) {
+ serviceName = serviceDescriptor.getServiceName();
+ serviceProviderName = serviceDescriptor.getServiceProviderName();
+ serviceType = serviceDescriptor.getServiceType();
+ }
+ if (serviceDescriptors.size() > 0) {
+ sdtItems.add(new SdtItem(serviceName, serviceProviderName, serviceType, serviceId,
+ originalNetworkId));
+ }
+ pos += descriptorsLength;
+ }
+ if (mListener != null) {
+ mListener.onSdtParsed(sdtItems);
+ }
+ return true;
+ }
+
+ private boolean parseDVBEIT(byte[] data) {
+ // For details of the structure for DVB ETT, see DVB Document A038 Table 7.
+ if (DEBUG) {
+ Log.d(TAG, "DVB EIT is discovered.");
+ }
+ if (data.length < 18) {
+ Log.e(TAG, "Broken DVB EIT.");
+ return false;
+ }
+ int sectionLength = ((data[1] & 0x0f) << 8) | (data[2] & 0xff);
+ int sourceId = ((data[3] & 0xff) << 8) | (data[4] & 0xff);
+ int transportStreamId = ((data[8] & 0xff) << 8) | (data[9] & 0xff);
+ int originalNetworkId = ((data[10] & 0xff) << 8) | (data[11] & 0xff);
+
+ int pos = 14;
+ List<EitItem> results = new ArrayList<>();
+ while (pos + 12 < data.length) {
+ int eventId = ((data[pos] & 0xff) << 8) + (data[pos + 1] & 0xff);
+ float modifiedJulianDate = ((data[pos + 2] & 0xff) << 8) | (data[pos + 3] & 0xff);
+ int startYear = (int) ((modifiedJulianDate - 15078.2f) / 365.25f);
+ int mjdMonth = (int) ((modifiedJulianDate - 14956.1f
+ - (int) (startYear * 365.25f)) / 30.6001f);
+ int startDay = (int) modifiedJulianDate - 14956 - (int) (startYear * 365.25f)
+ - (int) (mjdMonth * 30.6001f);
+ int startMonth = mjdMonth - 1;
+ if (mjdMonth == 14 || mjdMonth == 15) {
+ startYear += 1;
+ startMonth -= 12;
+ }
+ int startHour = ((data[pos + 4] & 0xf0) >> 4) * 10 + (data[pos + 4] & 0x0f);
+ int startMinute = ((data[pos + 5] & 0xf0) >> 4) * 10 + (data[pos + 5] & 0x0f);
+ int startSecond = ((data[pos + 6] & 0xf0) >> 4) * 10 + (data[pos + 6] & 0x0f);
+ Calendar calendar = Calendar.getInstance();
+ startYear += 1900;
+ calendar.set(startYear, startMonth, startDay, startHour, startMinute, startSecond);
+ long startTime = ConvertUtils.convertUnixEpochToGPSTime(
+ calendar.getTimeInMillis() / 1000);
+ int durationInSecond = (((data[pos + 7] & 0xf0) >> 4) * 10
+ + (data[pos + 7] & 0x0f)) * 3600
+ + (((data[pos + 8] & 0xf0) >> 4) * 10 + (data[pos + 8] & 0x0f)) * 60
+ + (((data[pos + 9] & 0xf0) >> 4) * 10 + (data[pos + 9] & 0x0f));
+ int descriptorsLength = ((data[pos + 10] & 0x0f) << 8)
+ | (data[pos + 10 + 1] & 0xff);
+ int descriptorsPos = pos + 10 + 2;
+ if (data.length < descriptorsPos + descriptorsLength) {
+ Log.e(TAG, "Broken EIT.");
+ return false;
+ }
+ List<TsDescriptor> descriptors = parseDescriptors(
+ data, descriptorsPos, descriptorsPos + descriptorsLength);
+ if (DEBUG) {
+ Log.d(TAG, String.format("DVB EIT descriptors size: %d", descriptors.size()));
+ }
+ // TODO: Add logic to generating content rating for dvb. See DVB document 6.2.28 for
+ // details. Content rating here will be null
+ String contentRating = generateContentRating(descriptors);
+ // TODO: Add logic for generating genre for dvb. See DVB document 6.2.9 for details.
+ // Genre here will be null here.
+ String broadcastGenre = generateBroadcastGenre(descriptors);
+ String canonicalGenre = generateCanonicalGenre(descriptors);
+ String titleText = generateShortEventName(descriptors);
+ List<AtscAudioTrack> audioTracks = generateAudioTracks(descriptors);
+ List<AtscCaptionTrack> captionTracks = generateCaptionTracks(descriptors);
+ pos += 12 + descriptorsLength;
+ results.add(new EitItem(EitItem.INVALID_PROGRAM_ID, eventId, titleText,
+ startTime, durationInSecond, contentRating, audioTracks, captionTracks,
+ broadcastGenre, canonicalGenre, null));
+ }
+ if (mListener != null) {
+ mListener.onEitParsed(sourceId, results);
+ }
+ return true;
+ }
+
private static List<AtscAudioTrack> generateAudioTracks(List<TsDescriptor> descriptors) {
// The list of audio tracks sent is located at both AC3 Audio descriptor and ISO 639
// Language descriptor.
@@ -717,6 +910,9 @@ public class SectionParser {
if (audioDescriptor.getLanguage() != null) {
audioTrack.language = audioDescriptor.getLanguage();
}
+ if (audioTrack.language == null) {
+ audioTrack.language = "";
+ }
audioTrack.audioType = AtscAudioTrack.AUDIOTYPE_UNDEFINED;
audioTrack.channelCount = audioDescriptor.getNumChannels();
audioTrack.sampleRate = audioDescriptor.getSampleRate();
@@ -787,44 +983,179 @@ public class SectionParser {
return services;
}
- private static String generateContentRating(List<TsDescriptor> descriptors) {
- List<String> contentRatings = new ArrayList<>();
+ @VisibleForTesting
+ static String generateContentRating(List<TsDescriptor> descriptors) {
+ Set<String> contentRatings = new ArraySet<>();
+ List<RatingRegion> usRatingRegions = getRatingRegions(descriptors, RATING_REGION_US_TV);
+ List<RatingRegion> krRatingRegions = getRatingRegions(descriptors, RATING_REGION_KR_TV);
+ for (RatingRegion region : usRatingRegions) {
+ String contentRating = getUsRating(region);
+ if (contentRating != null) {
+ contentRatings.add(contentRating);
+ }
+ }
+ for (RatingRegion region : krRatingRegions) {
+ String contentRating = getKrRating(region);
+ if (contentRating != null) {
+ contentRatings.add(contentRating);
+ }
+ }
+ return TextUtils.join(",", contentRatings);
+ }
+
+ /**
+ * Gets a list of {@link RatingRegion} in the specific region.
+ *
+ * @param descriptors {@link TsDescriptor} list which may contains rating information
+ * @param region the specific region
+ * @return a list of {@link RatingRegion} in the specific region
+ */
+ private static List<RatingRegion> getRatingRegions(List<TsDescriptor> descriptors, int region) {
+ List<RatingRegion> ratingRegions = new ArrayList<>();
for (TsDescriptor descriptor : descriptors) {
- if (descriptor instanceof ContentAdvisoryDescriptor) {
- ContentAdvisoryDescriptor contentAdvisoryDescriptor =
- (ContentAdvisoryDescriptor) descriptor;
- for (RatingRegion ratingRegion : contentAdvisoryDescriptor.getRatingRegions()) {
- for (RegionalRating index : ratingRegion.getRegionalRatings()) {
- String ratingSystem = null;
- String rating = null;
- switch (ratingRegion.getName()) {
- case RATING_REGION_US_TV:
- ratingSystem = RATING_REGION_RATING_SYSTEM_US_TV;
- if (index.getDimension() == 0 && index.getRating() >= 0
- && index.getRating() < RATING_REGION_TABLE_US_TV.length) {
- rating = RATING_REGION_TABLE_US_TV[index.getRating()];
- }
- break;
- case RATING_REGION_KR_TV:
- ratingSystem = RATING_REGION_RATING_SYSTEM_KR_TV;
- if (index.getDimension() == 0 && index.getRating() >= 0
- && index.getRating() < RATING_REGION_TABLE_KR_TV.length) {
- rating = RATING_REGION_TABLE_KR_TV[index.getRating()];
- }
- break;
- default:
- break;
+ if (!(descriptor instanceof ContentAdvisoryDescriptor)) {
+ continue;
+ }
+ ContentAdvisoryDescriptor contentAdvisoryDescriptor =
+ (ContentAdvisoryDescriptor) descriptor;
+ for (RatingRegion ratingRegion : contentAdvisoryDescriptor.getRatingRegions()) {
+ if (ratingRegion.getName() == region) {
+ ratingRegions.add(ratingRegion);
+ }
+ }
+ }
+ return ratingRegions;
+ }
+
+ /**
+ * Gets US content rating and subratings (if any).
+ *
+ * @param ratingRegion a {@link RatingRegion} instance which may contain rating information.
+ * @return A string representing the US content rating and subratings. The format of the string
+ * is defined in {@link TvContentRating}. null, if no such a string exists.
+ */
+ private static String getUsRating(RatingRegion ratingRegion) {
+ if (ratingRegion.getName() != RATING_REGION_US_TV) {
+ return null;
+ }
+ List<RegionalRating> regionalRatings = ratingRegion.getRegionalRatings();
+ String rating = null;
+ int ratingIndex = VALUE_US_TV_NONE;
+ List<String> subratings = new ArrayList<>();
+ for (RegionalRating index : regionalRatings) {
+ // See Table 3 of ANSI-CEA-766-D
+ int dimension = index.getDimension();
+ int value = index.getRating();
+ switch (dimension) {
+ // According to Table 6.27 of ATSC A65,
+ // the dimensions shall be in increasing order.
+ // Therefore, rating and ratingIndex are assigned before any corresponding
+ // subrating.
+ case DIMENSION_US_TV_RATING:
+ if (value >= VALUE_US_TV_G && value < RATING_REGION_TABLE_US_TV.length) {
+ rating = RATING_REGION_TABLE_US_TV[value];
+ ratingIndex = value;
+ }
+ break;
+ case DIMENSION_US_TV_D:
+ if (value == 1
+ && (ratingIndex == VALUE_US_TV_PG || ratingIndex == VALUE_US_TV_14)) {
+ // US_TV_D is applicable to US_TV_PG and US_TV_14
+ subratings.add(RATING_REGION_TABLE_US_TV_SUBRATING[dimension - 1]);
+ }
+ break;
+ case DIMENSION_US_TV_L:
+ case DIMENSION_US_TV_S:
+ case DIMENSION_US_TV_V:
+ if (value == 1
+ && ratingIndex >= VALUE_US_TV_PG
+ && ratingIndex <= VALUE_US_TV_MA) {
+ // US_TV_L, US_TV_S, and US_TV_V are applicable to
+ // US_TV_PG, US_TV_14 and US_TV_MA
+ subratings.add(RATING_REGION_TABLE_US_TV_SUBRATING[dimension - 1]);
+ }
+ break;
+ case DIMENSION_US_TV_Y:
+ if (rating == null) {
+ if (value == VALUE_US_TV_Y) {
+ rating = STRING_US_TV_Y;
+ } else if (value == VALUE_US_TV_Y7) {
+ rating = STRING_US_TV_Y7;
}
- if (ratingSystem != null && rating != null) {
- contentRatings.add(TvContentRating
- .createRating("com.android.tv", ratingSystem, rating)
- .flattenToString());
+ }
+ break;
+ case DIMENSION_US_TV_FV:
+ if (STRING_US_TV_Y7.equals(rating) && value == 1) {
+ // US_TV_FV is applicable to US_TV_Y7
+ subratings.add(STRING_US_TV_FV);
+ }
+ break;
+ case DIMENSION_US_MV_RATING:
+ if (value >= VALUE_US_MV_G && value <= VALUE_US_MV_X) {
+ if (value == VALUE_US_MV_X) {
+ // US_MV_X was replaced by US_MV_NC17 in 1990,
+ // and it's not supported by TvContentRating
+ value = VALUE_US_MV_NC17;
+ }
+ if (rating != null) {
+ // According to Table 3 of ANSI-CEA-766-D,
+ // DIMENSION_US_TV_RATING and DIMENSION_US_MV_RATING shall not be
+ // present in the same descriptor.
+ Log.w(
+ TAG,
+ "DIMENSION_US_TV_RATING and DIMENSION_US_MV_RATING are "
+ + "present in the same descriptor");
+ } else {
+ return TvContentRating.createRating(
+ RATING_DOMAIN,
+ RATING_REGION_RATING_SYSTEM_US_MV,
+ RATING_REGION_TABLE_US_MV[value - 2])
+ .flattenToString();
}
}
- }
+ break;
+
+ default:
+ break;
}
}
- return TextUtils.join(",", contentRatings);
+ if (rating == null) {
+ return null;
+ }
+
+ String[] subratingArray = subratings.toArray(new String[subratings.size()]);
+ return TvContentRating.createRating(
+ RATING_DOMAIN, RATING_REGION_RATING_SYSTEM_US_TV, rating, subratingArray)
+ .flattenToString();
+ }
+
+ /**
+ * Gets KR(South Korea) content rating.
+ *
+ * @param ratingRegion a {@link RatingRegion} instance which may contain rating information.
+ * @return A string representing the KR content rating. The format of the string is defined in
+ * {@link TvContentRating}. null, if no such a string exists.
+ */
+ private static String getKrRating(RatingRegion ratingRegion) {
+ if (ratingRegion.getName() != RATING_REGION_KR_TV) {
+ return null;
+ }
+ List<RegionalRating> regionalRatings = ratingRegion.getRegionalRatings();
+ String rating = null;
+ for (RegionalRating index : regionalRatings) {
+ if (index.getDimension() == 0
+ && index.getRating() >= 0
+ && index.getRating() < RATING_REGION_TABLE_KR_TV.length) {
+ rating = RATING_REGION_TABLE_KR_TV[index.getRating()];
+ break;
+ }
+ }
+ if (rating == null) {
+ return null;
+ }
+ return TvContentRating.createRating(
+ RATING_DOMAIN, RATING_REGION_RATING_SYSTEM_KR_TV, rating)
+ .flattenToString();
}
private static String generateBroadcastGenre(List<TsDescriptor> descriptors) {
@@ -849,6 +1180,28 @@ public class SectionParser {
return null;
}
+ private static List<ServiceDescriptor> generateServiceDescriptors(
+ List<TsDescriptor> descriptors) {
+ List<ServiceDescriptor> serviceDescriptors = new ArrayList<>();
+ for (TsDescriptor descriptor : descriptors) {
+ if (descriptor instanceof ServiceDescriptor) {
+ ServiceDescriptor serviceDescriptor = (ServiceDescriptor) descriptor;
+ serviceDescriptors.add(serviceDescriptor);
+ }
+ }
+ return serviceDescriptors;
+ }
+
+ private static String generateShortEventName(List<TsDescriptor> descriptors) {
+ for (TsDescriptor descriptor : descriptors) {
+ if (descriptor instanceof ShortEventDescriptor) {
+ ShortEventDescriptor shortEventDescriptor = (ShortEventDescriptor) descriptor;
+ return shortEventDescriptor.getEventName();
+ }
+ }
+ return "";
+ }
+
private static List<TsDescriptor> parseDescriptors(byte[] data, int offset, int limit) {
// For details of the structure for descriptors, see ATSC A/65 Section 6.9.
List<TsDescriptor> descriptors = new ArrayList<>();
@@ -894,6 +1247,22 @@ public class SectionParser {
descriptor = parseIso639Language(data, pos, pos + length + 2);
break;
+ case DVB_DESCRIPTOR_TAG_SERVICE:
+ descriptor = parseDvbService(data, pos, pos + length + 2);
+ break;
+
+ case DVB_DESCRIPTOR_TAG_SHORT_EVENT:
+ descriptor = parseDvbShortEvent(data, pos, pos + length + 2);
+ break;
+
+ case DVB_DESCRIPTOR_TAG_CONTENT:
+ descriptor = parseDvbContent(data, pos, pos + length + 2);
+ break;
+
+ case DVB_DESCRIPTOR_TAG_PARENTAL_RATING:
+ descriptor = parseDvbParentalRating(data, pos, pos + length + 2);
+ break;
+
default:
}
if (descriptor != null) {
@@ -948,6 +1317,7 @@ public class SectionParser {
pos += 3;
boolean ccType = (data[pos] & 0x80) != 0;
if (!ccType) {
+ pos +=3;
continue;
}
int captionServiceNumber = data[pos] & 0x3f;
@@ -987,6 +1357,7 @@ public class SectionParser {
int ratingRegion = data[pos] & 0xff;
int dimensionCount = data[pos + 1] & 0xff;
pos += 2;
+ int previousDimension = -1;
for (int j = 0; j < dimensionCount; ++j) {
if (limit <= pos + 1) {
Log.e(TAG, "Broken ContentAdvisory");
@@ -994,6 +1365,13 @@ public class SectionParser {
}
int dimensionIndex = data[pos] & 0xff;
int ratingValue = data[pos + 1] & 0x0f;
+ if (dimensionIndex <= previousDimension) {
+ // According to Table 6.27 of ATSC A65,
+ // the indices shall be in increasing order.
+ Log.e(TAG, "Broken ContentAdvisory");
+ return null;
+ }
+ previousDimension = dimensionIndex;
pos += 2;
indices.add(new RegionalRating(dimensionIndex, ratingValue));
}
@@ -1189,6 +1567,74 @@ public class SectionParser {
language, language2);
}
+ private static TsDescriptor parseDvbService(byte[] data, int pos, int limit) {
+ // For details of DVB service descriptors, see DVB Document A038 Table 86.
+ if (limit < pos + 5) {
+ Log.e(TAG, "Broken service descriptor.");
+ return null;
+ }
+ pos += 2;
+ int serviceType = data[pos] & 0xff;
+ pos++;
+ int serviceProviderNameLength = data[pos] & 0xff;
+ pos++;
+ String serviceProviderName = extractTextFromDvb(data, pos, serviceProviderNameLength);
+ pos += serviceProviderNameLength;
+ int serviceNameLength = data[pos] & 0xff;
+ pos++;
+ String serviceName = extractTextFromDvb(data, pos, serviceNameLength);
+ return new ServiceDescriptor(serviceType, serviceProviderName, serviceName);
+ }
+
+ private static TsDescriptor parseDvbShortEvent(byte[] data, int pos, int limit) {
+ // For details of DVB service descriptors, see DVB Document A038 Table 91.
+ if (limit < pos + 7) {
+ Log.e(TAG, "Broken short event descriptor.");
+ return null;
+ }
+ pos += 2;
+ String language = new String(data, pos, 3);
+ int eventNameLength = data[pos + 3] & 0xff;
+ pos += 4;
+ if (pos + eventNameLength > limit) {
+ Log.e(TAG, "Broken short event descriptor.");
+ return null;
+ }
+ String eventName = new String(data, pos, eventNameLength);
+ pos += eventNameLength;
+ int textLength = data[pos] & 0xff;
+ if (pos + textLength > limit) {
+ Log.e(TAG, "Broken short event descriptor.");
+ return null;
+ }
+ pos++;
+ String text = new String(data, pos, textLength);
+ return new ShortEventDescriptor(language, eventName, text);
+ }
+
+ private static TsDescriptor parseDvbContent(byte[] data, int pos, int limit) {
+ // TODO: According to DVB Document A038 Table 27 to add a parser for content descriptor to
+ // get content genre.
+ return null;
+ }
+
+ private static TsDescriptor parseDvbParentalRating(byte[] data, int pos, int limit) {
+ // For details of DVB service descriptors, see DVB Document A038 Table 81.
+ HashMap<String, Integer> ratings = new HashMap<>();
+ pos += 2;
+ while (pos + 4 <= limit) {
+ String countryCode = new String(data, pos, 3);
+ int rating = data[pos + 3] & 0xff;
+ pos += 4;
+ if (rating > 15) {
+ // Rating > 15 means that the ratings is defined by broadcaster.
+ continue;
+ }
+ ratings.put(countryCode, rating + 3);
+ }
+ return new ParentalRatingDescriptor(ratings);
+ }
+
private static int getShortNameSize(byte[] data, int offset) {
for (int i = 0; i < MAX_SHORT_NAME_BYTES; i += 2) {
if (data[offset + i] == 0 && data[offset + i + 1] == 0) {
@@ -1244,6 +1690,55 @@ public class SectionParser {
return null;
}
+ private static String extractTextFromDvb(byte[] data, int pos, int length) {
+ // For details of DVB character set selection, see DVB Document A038 Annex A.
+ if (data.length < pos + length) {
+ return null;
+ }
+ try {
+ String charsetPrefix = "ISO-8859-";
+ switch (data[0]) {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x09:
+ case 0x0A:
+ case 0x0B:
+ String charset = charsetPrefix + String.valueOf(data[0] & 0xff + 4);
+ return new String(data, pos, length, charset);
+ case 0x10:
+ if (length < 3) {
+ Log.e(TAG, "Broken DVB text");
+ return null;
+ }
+ int codeTable = data[pos + 2] & 0xff;
+ if (data[pos + 1] == 0 && codeTable > 0 && codeTable < 15) {
+ return new String(
+ data, pos, length, charsetPrefix + String.valueOf(codeTable));
+ } else {
+ return new String(data, pos, length, "ISO-8859-1");
+ }
+ case 0x11:
+ case 0x14:
+ case 0x15:
+ return new String(data, pos, length, "UTF-16BE");
+ case 0x12:
+ return new String(data, pos, length, "EUC-KR");
+ case 0x13:
+ return new String(data, pos, length, "GB2312");
+ default:
+ return new String(data, pos, length, "ISO-8859-1");
+ }
+ } catch (UnsupportedEncodingException e) {
+ Log.e(TAG, "Unsupported text format.", e);
+ }
+ return new String(data, pos, length);
+ }
+
private static boolean checkSanity(byte[] data) {
if (data.length <= 1) {
return false;
diff --git a/src/com/android/tv/tuner/ts/TsParser.java b/src/com/android/tv/tuner/ts/TsParser.java
index c24c2a21..7cdb534e 100644
--- a/src/com/android/tv/tuner/ts/TsParser.java
+++ b/src/com/android/tv/tuner/ts/TsParser.java
@@ -25,6 +25,7 @@ import com.android.tv.tuner.data.PsiData.PmtItem;
import com.android.tv.tuner.data.PsipData.EitItem;
import com.android.tv.tuner.data.PsipData.EttItem;
import com.android.tv.tuner.data.PsipData.MgtItem;
+import com.android.tv.tuner.data.PsipData.SdtItem;
import com.android.tv.tuner.data.PsipData.VctItem;
import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.ts.SectionParser.OutputListener;
@@ -46,6 +47,8 @@ public class TsParser {
public static final int ATSC_SI_BASE_PID = 0x1ffb;
public static final int PAT_PID = 0x0000;
+ public static final int DVB_SDT_PID = 0x0011;
+ public static final int DVB_EIT_PID = 0x0012;
private static final int TS_PACKET_START_CODE = 0x47;
private static final int TS_PACKET_TEI_MASK = 0x80;
private static final int TS_PACKET_SIZE = 188;
@@ -64,6 +67,7 @@ public class TsParser {
private final Map<Integer, VctItem> mProgramNumberToVctItemMap = new HashMap<>();
private final Map<Integer, List<PmtItem>> mProgramNumberToPMTMap = new HashMap<>();
private final Map<Integer, List<EitItem>> mSourceIdToEitMap = new HashMap<>();
+ private final Map<Integer, SdtItem> mProgramNumberToSdtItemMap = new HashMap<>();
private final Map<EventSourceEntry, List<EitItem>> mEitMap = new HashMap<>();
private final Map<EventSourceEntry, List<EttItem>> mETTMap = new HashMap<>();
private final TreeSet<Integer> mEITPids = new TreeSet<>();
@@ -71,6 +75,7 @@ public class TsParser {
private final SparseBooleanArray mProgramNumberHandledStatus = new SparseBooleanArray();
private final SparseBooleanArray mVctItemHandledStatus = new SparseBooleanArray();
private final TsOutputListener mListener;
+ private final boolean mIsDvbSignal;
private int mVctItemCount;
private int mHandledVctItemCount;
@@ -84,6 +89,7 @@ public class TsParser {
void onEitItemParsed(VctItem channel, List<EitItem> items);
void onEttPidDetected(int pid);
void onAllVctItemsParsed();
+ void onSdtItemParsed(SdtItem channel, List<PmtItem> pmtItems);
}
private abstract class Stream {
@@ -102,6 +108,7 @@ public class TsParser {
}
protected abstract void handleData(byte[] data, boolean startIndicator);
+ protected abstract void resetDataVersions();
}
private class SectionStream extends Stream {
@@ -138,6 +145,11 @@ public class TsParser {
mSectionParser.parseSections(mPacket);
}
+ @Override
+ protected void resetDataVersions() {
+ mSectionParser.resetVersionNumbers();
+ }
+
private final OutputListener mSectionListener = new OutputListener() {
@Override
public void onPatParsed(List<PatItem> items) {
@@ -173,6 +185,12 @@ public class TsParser {
mListener.onAllVctItemsParsed();
}
}
+ SdtItem sdtItem = mProgramNumberToSdtItemMap.get(programNumber);
+ if (sdtItem != null) {
+ // When PMT is parsed later than SDT.
+ mProgramNumberHandledStatus.put(programNumber, true);
+ handleSdtItem(sdtItem, items);
+ }
}
}
@@ -276,6 +294,24 @@ public class TsParser {
mETTMap.put(entry, descriptions);
handleEvents(sourceId);
}
+
+ @Override
+ public void onSdtParsed(List<SdtItem> sdtItems) {
+ for (SdtItem sdtItem : sdtItems) {
+ if (DEBUG) Log.d(TAG, "onSdtParsed " + sdtItem);
+ int programNumber = sdtItem.getServiceId();
+ mProgramNumberToSdtItemMap.put(programNumber, sdtItem);
+ List<PmtItem> pmtList = mProgramNumberToPMTMap.get(programNumber);
+ if (pmtList != null) {
+ mProgramNumberHandledStatus.put(programNumber, true);
+ handleSdtItem(sdtItem, pmtList);
+ } else {
+ mProgramNumberHandledStatus.put(programNumber, false);
+ Log.i(TAG, "onSdtParsed, but PMT for programNo " + programNumber
+ + " is not found yet.");
+ }
+ }
+ }
};
}
@@ -335,6 +371,15 @@ public class TsParser {
}
}
+ private void handleSdtItem(SdtItem channel, List<PmtItem> pmtItems) {
+ if (DEBUG) {
+ Log.d(TAG, "handleSdtItem " + channel);
+ }
+ if (mListener != null) {
+ mListener.onSdtItemParsed(channel, pmtItems);
+ }
+ }
+
private void handleEvents(int sourceId) {
Map<Integer, EitItem> itemSet = new HashMap<>();
for (int pid : mEITPids) {
@@ -367,17 +412,26 @@ public class TsParser {
handleEitItems(channel, items);
} else {
mVctItemHandledStatus.put(sourceId, false);
- Log.i(TAG, "onEITParsed, but VCT for sourceId " + sourceId + " is not found yet.");
+ if (!mIsDvbSignal) {
+ // Log only when zapping to non-DVB channels, since there is not VCT in DVB signal.
+ Log.i(TAG, "onEITParsed, but VCT for sourceId " + sourceId + " is not found yet.");
+ }
}
}
/**
* Creates MPEG-2 TS parser.
+ *
* @param listener TsOutputListener
*/
- public TsParser(TsOutputListener listener) {
- startListening(ATSC_SI_BASE_PID);
+ public TsParser(TsOutputListener listener, boolean isDvbSignal) {
startListening(PAT_PID);
+ startListening(ATSC_SI_BASE_PID);
+ mIsDvbSignal = isDvbSignal;
+ if (isDvbSignal) {
+ startListening(DVB_EIT_PID);
+ startListening(DVB_SDT_PID);
+ }
mListener = listener;
}
@@ -412,7 +466,7 @@ public class TsParser {
// We are not interested in this packet.
return false;
}
- if (payloadPos > pos + TS_PACKET_SIZE) {
+ if (payloadPos >= pos + TS_PACKET_SIZE) {
if (DEBUG) Log.d(TAG, "Payload should be included in a single TS packet.");
return false;
}
@@ -451,4 +505,16 @@ public class TsParser {
}
return incompleteChannels;
}
+
+ /**
+ * Reset the versions so that data with old version number can be handled.
+ */
+ public void resetDataVersions() {
+ for (int eitPid : mEITPids) {
+ Stream stream = mStreamMap.get(eitPid);
+ if (stream != null) {
+ stream.resetDataVersions();
+ }
+ }
+ }
}
diff --git a/src/com/android/tv/tuner/tvinput/ChannelDataManager.java b/src/com/android/tv/tuner/tvinput/ChannelDataManager.java
index a16bc522..d2b4998a 100644
--- a/src/com/android/tv/tuner/tvinput/ChannelDataManager.java
+++ b/src/com/android/tv/tuner/tvinput/ChannelDataManager.java
@@ -25,6 +25,7 @@ import android.content.OperationApplicationException;
import android.database.Cursor;
import android.media.tv.TvContract;
import android.net.Uri;
+import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@@ -37,6 +38,7 @@ import com.android.tv.tuner.TunerPreferences;
import com.android.tv.tuner.data.PsipData.EitItem;
import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.util.ConvertUtils;
+import com.android.tv.util.PermissionUtils;
import java.util.ArrayList;
import java.util.Collections;
@@ -192,11 +194,14 @@ public class ChannelDataManager implements Handler.Callback {
public void release() {
mHandler.removeCallbacksAndMessages(null);
- mHandlerThread.quitSafely();
+ releaseSafely();
}
public void releaseSafely() {
mHandlerThread.quitSafely();
+ mListener = null;
+ mChannelScanListener = null;
+ mChannelScanHandler = null;
}
public TunerChannel getChannel(long channelId) {
@@ -435,7 +440,7 @@ public class ChannelDataManager implements Handler.Callback {
}
}
ops.add(buildContentProviderOperation(ContentProviderOperation.newInsert(
- TvContract.Programs.CONTENT_URI), newItem, channel.getChannelId()));
+ TvContract.Programs.CONTENT_URI), newItem, channel));
if (ops.size() >= BATCH_OPERATION_COUNT) {
applyBatch(channel.getName(), ops);
ops.clear();
@@ -505,7 +510,7 @@ public class ChannelDataManager implements Handler.Callback {
continue;
}
ops.add(buildContentProviderOperation(ContentProviderOperation.newInsert(
- TvContract.Programs.CONTENT_URI), item, channel.getChannelId()));
+ TvContract.Programs.CONTENT_URI), item, channel));
if (ops.size() >= BATCH_OPERATION_COUNT) {
applyBatch(channel.getName(), ops);
ops.clear();
@@ -516,9 +521,13 @@ public class ChannelDataManager implements Handler.Callback {
}
private ContentProviderOperation buildContentProviderOperation(
- ContentProviderOperation.Builder builder, EitItem item, Long channelId) {
- if (channelId != null) {
- builder.withValue(TvContract.Programs.COLUMN_CHANNEL_ID, channelId);
+ ContentProviderOperation.Builder builder, EitItem item, TunerChannel channel) {
+ if (channel != null) {
+ builder.withValue(TvContract.Programs.COLUMN_CHANNEL_ID, channel.getChannelId());
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ builder.withValue(TvContract.Programs.COLUMN_RECORDING_PROHIBITED,
+ channel.isRecordingProhibited() ? 1 : 0);
+ }
}
if (item != null) {
builder.withValue(TvContract.Programs.COLUMN_TITLE, item.getTitleText())
@@ -556,7 +565,10 @@ public class ChannelDataManager implements Handler.Callback {
values.put(TvContract.Channels.COLUMN_DISPLAY_NAME, channel.getName());
values.put(TvContract.Channels.COLUMN_INTERNAL_PROVIDER_DATA, channel.toByteArray());
values.put(TvContract.Channels.COLUMN_DESCRIPTION, channel.getDescription());
+ values.put(TvContract.Channels.COLUMN_VIDEO_FORMAT, channel.getVideoFormat());
values.put(TvContract.Channels.COLUMN_INTERNAL_PROVIDER_FLAG1, VERSION);
+ values.put(TvContract.Channels.COLUMN_INTERNAL_PROVIDER_FLAG2,
+ channel.isRecordingProhibited() ? 1 : 0);
if (channelId <= 0) {
values.put(TvContract.Channels.COLUMN_INPUT_ID, mInputId);
@@ -598,13 +610,29 @@ public class ChannelDataManager implements Handler.Callback {
}
private void checkVersion() {
- String selection = TvContract.Channels.COLUMN_INTERNAL_PROVIDER_FLAG1 + "<>?";
- try (Cursor cursor = mContext.getContentResolver().query(mChannelsUri,
- CHANNEL_DATA_SELECTION_ARGS, selection,
- new String[] {Integer.toString(VERSION)}, null)) {
- if (cursor != null && cursor.moveToFirst()) {
- // The stored channel data seem outdated. Delete them all.
- clearChannels();
+ if (PermissionUtils.hasAccessAllEpg(mContext)) {
+ String selection = TvContract.Channels.COLUMN_INTERNAL_PROVIDER_FLAG1 + "<>?";
+ try (Cursor cursor = mContext.getContentResolver().query(mChannelsUri,
+ CHANNEL_DATA_SELECTION_ARGS, selection,
+ new String[] {Integer.toString(VERSION)}, null)) {
+ if (cursor != null && cursor.moveToFirst()) {
+ // The stored channel data seem outdated. Delete them all.
+ clearChannels();
+ }
+ }
+ } else {
+ try (Cursor cursor = mContext.getContentResolver().query(mChannelsUri,
+ new String[] { TvContract.Channels.COLUMN_INTERNAL_PROVIDER_FLAG1 },
+ null, null, null)) {
+ if (cursor != null) {
+ while (cursor.moveToNext()) {
+ int version = cursor.getInt(0);
+ if (version != VERSION) {
+ clearChannels();
+ break;
+ }
+ }
+ }
}
}
}
diff --git a/src/com/android/tv/tuner/tvinput/EventDetector.java b/src/com/android/tv/tuner/tvinput/EventDetector.java
index a132398f..dc99118a 100644
--- a/src/com/android/tv/tuner/tvinput/EventDetector.java
+++ b/src/com/android/tv/tuner/tvinput/EventDetector.java
@@ -21,12 +21,12 @@ import android.util.SparseArray;
import android.util.SparseBooleanArray;
import com.android.tv.tuner.TunerHal;
-import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
-import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
-import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.ts.TsParser;
import com.android.tv.tuner.data.PsiData;
import com.android.tv.tuner.data.PsipData;
+import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import java.util.ArrayList;
import java.util.HashSet;
@@ -48,10 +48,11 @@ public class EventDetector {
// To prevent channel duplication
private final Set<Integer> mVctProgramNumberSet = new HashSet<>();
+ private final Set<Integer> mSdtProgramNumberSet = new HashSet<>();
private final SparseArray<TunerChannel> mChannelMap = new SparseArray<>();
private final SparseBooleanArray mVctCaptionTracksFound = new SparseBooleanArray();
private final SparseBooleanArray mEitCaptionTracksFound = new SparseBooleanArray();
- private final EventListener mEventListener;
+ private final List<EventListener> mEventListeners = new ArrayList<>();
private int mFrequency;
private String mModulation;
private int mProgramNumber = ALL_PROGRAM_NUMBERS;
@@ -105,8 +106,10 @@ public class EventDetector {
item.setHasCaptionTrack();
}
}
- if (tunerChannel != null && mEventListener != null) {
- mEventListener.onEventDetected(tunerChannel, items);
+ if (tunerChannel != null && !mEventListeners.isEmpty()) {
+ for (EventListener eventListener : mEventListeners) {
+ eventListener.onEventDetected(tunerChannel, items);
+ }
}
}
@@ -117,8 +120,10 @@ public class EventDetector {
@Override
public void onAllVctItemsParsed() {
- if (mEventListener != null) {
- mEventListener.onChannelScanDone();
+ if (!mEventListeners.isEmpty()) {
+ for (EventListener eventListener : mEventListeners) {
+ eventListener.onChannelScanDone();
+ }
}
}
@@ -161,8 +166,47 @@ public class EventDetector {
if (!found) {
mVctProgramNumberSet.add(channelProgramNumber);
}
- if (mEventListener != null) {
- mEventListener.onChannelDetected(tunerChannel, !found);
+ if (!mEventListeners.isEmpty()) {
+ for (EventListener eventListener : mEventListeners) {
+ eventListener.onChannelDetected(tunerChannel, !found);
+ }
+ }
+ }
+
+ @Override
+ public void onSdtItemParsed(PsipData.SdtItem channel, List<PsiData.PmtItem> pmtItems) {
+ if (DEBUG) {
+ Log.d(TAG, "onSdtItemParsed SDT " + channel);
+ Log.d(TAG, " PMT " + pmtItems);
+ }
+
+ // Merges the audio and caption tracks located in PMT items into the tracks of the given
+ // tuner channel.
+ TunerChannel tunerChannel = new TunerChannel(channel, pmtItems);
+ List<AtscAudioTrack> audioTracks = new ArrayList<>();
+ List<AtscCaptionTrack> captionTracks = new ArrayList<>();
+ for (PsiData.PmtItem pmtItem : pmtItems) {
+ if (pmtItem.getAudioTracks() != null) {
+ audioTracks.addAll(pmtItem.getAudioTracks());
+ }
+ if (pmtItem.getCaptionTracks() != null) {
+ captionTracks.addAll(pmtItem.getCaptionTracks());
+ }
+ }
+ int channelProgramNumber = channel.getServiceId();
+ tunerChannel.setAudioTracks(audioTracks);
+ tunerChannel.setCaptionTracks(captionTracks);
+ tunerChannel.setFrequency(mFrequency);
+ tunerChannel.setModulation(mModulation);
+ mChannelMap.put(tunerChannel.getProgramNumber(), tunerChannel);
+ boolean found = mSdtProgramNumberSet.contains(channelProgramNumber);
+ if (!found) {
+ mSdtProgramNumberSet.add(channelProgramNumber);
+ }
+ if (!mEventListeners.isEmpty()) {
+ for (EventListener eventListener : mEventListeners) {
+ eventListener.onChannelDetected(tunerChannel, !found);
+ }
}
}
};
@@ -196,18 +240,23 @@ public class EventDetector {
/**
* Creates a detector for ATSC TV channles and program information.
+ *
* @param usbTunerInteface {@link TunerHal}
- * @param listener for ATSC TV channels and program information
*/
- public EventDetector(TunerHal usbTunerInteface, EventListener listener) {
+ public EventDetector(TunerHal usbTunerInteface) {
mTunerHal = usbTunerInteface;
- mEventListener = listener;
}
private void reset() {
- mTsParser = new TsParser(mTsOutputListener); // TODO: Use TsParser.reset()
+ // TODO: Use TsParser.reset()
+ int deliverySystemType = mTunerHal.getDeliverySystemType();
+ mTsParser =
+ new TsParser(
+ mTsOutputListener,
+ TunerHal.isDvbDeliverySystem(mTunerHal.getDeliverySystemType()));
mPidSet.clear();
mVctProgramNumberSet.clear();
+ mSdtProgramNumberSet.clear();
mVctCaptionTracksFound.clear();
mEitCaptionTracksFound.clear();
mChannelMap.clear();
@@ -258,4 +307,28 @@ public class EventDetector {
public List<TunerChannel> getMalFormedChannels() {
return mTsParser.getMalFormedChannels();
}
+
+ /**
+ * Registers an EventListener.
+ * @param eventListener the listener to be registered
+ */
+ public void registerListener(EventListener eventListener) {
+ if (mTsParser != null) {
+ // Resets the version numbers so that the new listener can receive the EIT items.
+ // Otherwise, each EIT session is handled only once unless there is a new version.
+ mTsParser.resetDataVersions();
+ }
+ mEventListeners.add(eventListener);
+ }
+
+ /**
+ * Unregisters an EventListener.
+ * @param eventListener the listener to be unregistered
+ */
+ public void unregisterListener(EventListener eventListener) {
+ boolean removed = mEventListeners.remove(eventListener);
+ if (!removed && DEBUG) {
+ Log.d(TAG, "Cannot unregister a non-registered listener!");
+ }
+ }
}
diff --git a/src/com/android/tv/tuner/tvinput/FileSourceEventDetector.java b/src/com/android/tv/tuner/tvinput/FileSourceEventDetector.java
index 61de24f4..99222bf8 100644
--- a/src/com/android/tv/tuner/tvinput/FileSourceEventDetector.java
+++ b/src/com/android/tv/tuner/tvinput/FileSourceEventDetector.java
@@ -23,10 +23,11 @@ import android.util.SparseBooleanArray;
import com.android.tv.tuner.data.PsiData.PatItem;
import com.android.tv.tuner.data.PsiData.PmtItem;
import com.android.tv.tuner.data.PsipData.EitItem;
+import com.android.tv.tuner.data.PsipData.SdtItem;
import com.android.tv.tuner.data.PsipData.VctItem;
+import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
-import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.source.FileTsStreamer;
import com.android.tv.tuner.ts.TsParser;
import com.android.tv.tuner.tvinput.EventDetector.EventListener;
@@ -49,15 +50,18 @@ public class FileSourceEventDetector {
private TsParser mTsParser;
private final Set<Integer> mVctProgramNumberSet = new HashSet<>();
+ private final Set<Integer> mSdtProgramNumberSet = new HashSet<>();
private final SparseArray<TunerChannel> mChannelMap = new SparseArray<>();
private final SparseBooleanArray mVctCaptionTracksFound = new SparseBooleanArray();
private final SparseBooleanArray mEitCaptionTracksFound = new SparseBooleanArray();
private final EventListener mEventListener;
+ private final boolean mEnableDvbSignal;
private FileTsStreamer.StreamProvider mStreamProvider;
private int mProgramNumber = ALL_PROGRAM_NUMBERS;
- public FileSourceEventDetector(EventDetector.EventListener listener) {
+ public FileSourceEventDetector(EventDetector.EventListener listener, boolean enableDvbSignal) {
mEventListener = listener;
+ mEnableDvbSignal = enableDvbSignal;
}
/**
@@ -74,9 +78,10 @@ public class FileSourceEventDetector {
}
private void reset() {
- mTsParser = new TsParser(mTsOutputListener); // TODO: Use TsParser.reset()
+ mTsParser = new TsParser(mTsOutputListener, mEnableDvbSignal); // TODO: Use TsParser.reset()
mStreamProvider.clearPidFilter();
mVctProgramNumberSet.clear();
+ mSdtProgramNumberSet.clear();
mVctCaptionTracksFound.clear();
mEitCaptionTracksFound.clear();
mChannelMap.clear();
@@ -206,5 +211,39 @@ public class FileSourceEventDetector {
mEventListener.onChannelDetected(tunerChannel, !found);
}
}
+
+ @Override
+ public void onSdtItemParsed(SdtItem channel, List<PmtItem> pmtItems) {
+ if (DEBUG) {
+ Log.d(TAG, "onSdtItemParsed SDT " + channel);
+ Log.d(TAG, " PMT " + pmtItems);
+ }
+
+ // Merges the audio and caption tracks located in PMT items into the tracks of the given
+ // tuner channel.
+ TunerChannel tunerChannel = TunerChannel.forDvbFile(channel, pmtItems);
+ List<AtscAudioTrack> audioTracks = new ArrayList<>();
+ List<AtscCaptionTrack> captionTracks = new ArrayList<>();
+ for (PmtItem pmtItem : pmtItems) {
+ if (pmtItem.getAudioTracks() != null) {
+ audioTracks.addAll(pmtItem.getAudioTracks());
+ }
+ if (pmtItem.getCaptionTracks() != null) {
+ captionTracks.addAll(pmtItem.getCaptionTracks());
+ }
+ }
+ int channelProgramNumber = channel.getServiceId();
+ tunerChannel.setFilepath(mStreamProvider.getFilepath());
+ tunerChannel.setAudioTracks(audioTracks);
+ tunerChannel.setCaptionTracks(captionTracks);
+ mChannelMap.put(tunerChannel.getProgramNumber(), tunerChannel);
+ boolean found = mSdtProgramNumberSet.contains(channelProgramNumber);
+ if (!found) {
+ mSdtProgramNumberSet.add(channelProgramNumber);
+ }
+ if (mEventListener != null) {
+ mEventListener.onChannelDetected(tunerChannel, !found);
+ }
+ }
};
}
diff --git a/src/com/android/tv/tuner/tvinput/TunerDebug.java b/src/com/android/tv/tuner/tvinput/TunerDebug.java
index a7a41ea7..2ddc946a 100644
--- a/src/com/android/tv/tuner/tvinput/TunerDebug.java
+++ b/src/com/android/tv/tuner/tvinput/TunerDebug.java
@@ -55,10 +55,10 @@ public class TunerDebug {
return LazyHolder.INSTANCE;
}
- public static void notifyVideoFrameDrop(long delta) {
+ public static void notifyVideoFrameDrop(int count, long delta) {
// TODO: provide timestamp mismatch information using delta
TunerDebug sTunerDebug = getInstance();
- sTunerDebug.mVideoFrameDrop++;
+ sTunerDebug.mVideoFrameDrop += count;
}
public static int getVideoFrameDrop() {
diff --git a/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java b/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
index 6ec55e4f..34013bf1 100644
--- a/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
+++ b/src/com/android/tv/tuner/tvinput/TunerRecordingSessionWorker.java
@@ -33,14 +33,18 @@ import android.support.annotation.MainThread;
import android.support.annotation.Nullable;
import android.util.Log;
+import android.util.Pair;
+import com.google.android.exoplayer.C;
import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.recording.RecordingCapability;
import com.android.tv.dvr.DvrStorageStatusManager;
-import com.android.tv.dvr.RecordedProgram;
+import com.android.tv.dvr.data.RecordedProgram;
import com.android.tv.tuner.DvbDeviceAccessor;
import com.android.tv.tuner.data.PsipData;
+import com.android.tv.tuner.data.PsipData.EitItem;
import com.android.tv.tuner.data.TunerChannel;
+import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.exoplayer.ExoPlayerSampleExtractor;
import com.android.tv.tuner.exoplayer.SampleExtractor;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
@@ -53,10 +57,10 @@ import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Random;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
@@ -71,6 +75,7 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
private static final String SORT_BY_TIME = TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS
+ ", " + TvContract.Programs.COLUMN_CHANNEL_ID + ", "
+ TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS;
+ private static final long TUNING_RETRY_INTERVAL_MS = TimeUnit.SECONDS.toMillis(4);
private static final long STORAGE_MONITOR_INTERVAL_MS = TimeUnit.SECONDS.toMillis(4);
private static final long MIN_PARTIAL_RECORDING_DURATION_MS = TimeUnit.SECONDS.toMillis(10);
private static final long PREPARE_RECORDER_POLL_MS = 50;
@@ -80,20 +85,23 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
private static final int MSG_STOP_RECORDING = 4;
private static final int MSG_MONITOR_STORAGE_STATUS = 5;
private static final int MSG_RELEASE = 6;
+ private static final int MSG_UPDATE_CC_INFO = 7;
private final RecordingCapability mCapabilities;
public RecordingCapability getCapabilities() {
return mCapabilities;
}
- @IntDef({STATE_IDLE, STATE_TUNED, STATE_RECORDING})
+ @IntDef({STATE_IDLE, STATE_TUNING, STATE_TUNED, STATE_RECORDING})
@Retention(RetentionPolicy.SOURCE)
public @interface DvrSessionState {}
private static final int STATE_IDLE = 1;
- private static final int STATE_TUNED = 2;
- private static final int STATE_RECORDING = 3;
+ private static final int STATE_TUNING = 2;
+ private static final int STATE_TUNED = 3;
+ private static final int STATE_RECORDING = 4;
private static final long CHANNEL_ID_NONE = -1;
+ private static final int MAX_TUNING_RETRY = 6;
private final Context mContext;
private final ChannelDataManager mChannelDataManager;
@@ -108,13 +116,16 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
private long mRecordStartTime;
private long mRecordEndTime;
private boolean mRecorderRunning;
- private BufferManager mBufferManager;
private SampleExtractor mRecorder;
private final TunerRecordingSession mSession;
@DvrSessionState private int mSessionState = STATE_IDLE;
private final String mInputId;
private Uri mProgramUri;
+ private PsipData.EitItem mCurrenProgram;
+ private List<AtscCaptionTrack> mCaptionTracks;
+ private DvrStorageManager mDvrStorageManager;
+
public TunerRecordingSessionWorker(Context context, String inputId,
ChannelDataManager dataManager, TunerRecordingSession session) {
mRandom.setSeed(System.nanoTime());
@@ -157,6 +168,7 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
if (mChannel == null || mChannel.compareTo(channel) != 0) {
return;
}
+ mHandler.obtainMessage(MSG_UPDATE_CC_INFO, new Pair<>(channel, items)).sendToTarget();
mChannelDataManager.notifyEventDetected(channel, items);
}
@@ -178,7 +190,7 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
@MainThread
public void tune(Uri channelUri) {
mHandler.removeCallbacksAndMessages(null);
- mHandler.obtainMessage(MSG_TUNE, channelUri).sendToTarget();
+ mHandler.obtainMessage(MSG_TUNE, 0, 0, channelUri).sendToTarget();
}
/**
@@ -211,11 +223,22 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
switch (msg.what) {
case MSG_TUNE: {
Uri channelUri = (Uri) msg.obj;
+ int retryCount = msg.arg1;
if (DEBUG) Log.d(TAG, "Tune to " + channelUri);
if (doTune(channelUri)) {
- mSession.onTuned(channelUri);
- } else {
- reset();
+ if (mSessionState == STATE_TUNED) {
+ mSession.onTuned(channelUri);
+ } else {
+ Log.w(TAG, "Tuner stream cannot be created due to resource shortage.");
+ if (retryCount < MAX_TUNING_RETRY) {
+ Message tuneMsg =
+ mHandler.obtainMessage(MSG_TUNE, retryCount + 1, 0, channelUri);
+ mHandler.sendMessageDelayed(tuneMsg, TUNING_RETRY_INTERVAL_MS);
+ } else {
+ mSession.onError(TvInputManager.RECORDING_ERROR_RESOURCE_BUSY);
+ reset();
+ }
+ }
}
return true;
}
@@ -281,6 +304,12 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
mHandler.getLooper().quitSafely();
return true;
}
+ case MSG_UPDATE_CC_INFO: {
+ Pair<TunerChannel, List<EitItem>> pair =
+ (Pair<TunerChannel, List<EitItem>>) msg.obj;
+ updateCaptionTracks(pair.first, pair.second);
+ return true;
+ }
}
return false;
}
@@ -310,20 +339,17 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
mRecorder.release();
mRecorder = null;
}
- if (mBufferManager != null) {
- mBufferManager.close();
- mBufferManager = null;
- }
if (mTunerSource != null) {
mSourceManager.releaseDataSource(mTunerSource);
mTunerSource = null;
}
+ mDvrStorageManager = null;
mSessionState = STATE_IDLE;
mRecorderRunning = false;
}
private boolean doTune(Uri channelUri) {
- if (mSessionState != STATE_IDLE) {
+ if (mSessionState != STATE_IDLE && mSessionState != STATE_TUNING) {
mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
Log.e(TAG, "Tuning was requested from wrong status.");
return false;
@@ -333,6 +359,10 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
Log.w(TAG, "Failed to start recording. Couldn't find the channel for " + mChannel);
return false;
+ } else if (mChannel.isRecordingProhibited()) {
+ mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
+ Log.w(TAG, "Failed to start recording. Not a recordable channel: " + mChannel);
+ return false;
}
if (!mDvrStorageStatusManager.isStorageSufficient()) {
mSession.onError(TvInputManager.RECORDING_ERROR_INSUFFICIENT_SPACE);
@@ -341,9 +371,9 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
}
mTunerSource = mSourceManager.createDataSource(mContext, mChannel, this);
if (mTunerSource == null) {
- mSession.onError(TvInputManager.RECORDING_ERROR_RESOURCE_BUSY);
- Log.w(TAG, "Tuner stream cannot be created due to resource shortage.");
- return false;
+ // Retry tuning in this case.
+ mSessionState = STATE_TUNING;
+ return true;
}
mSessionState = STATE_TUNED;
return true;
@@ -365,10 +395,10 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
}
// Since tuning might be happened a while ago, shifts the start position of tuned source.
mTunerSource.shiftStartPosition(mTunerSource.getBufferedPosition());
- mBufferManager = new BufferManager(new DvrStorageManager(mStorageDir, true));
mRecordStartTime = System.currentTimeMillis();
- mRecorder = new ExoPlayerSampleExtractor(Uri.EMPTY, mTunerSource, mBufferManager, this,
- true);
+ mDvrStorageManager = new DvrStorageManager(mStorageDir, true);
+ mRecorder = new ExoPlayerSampleExtractor(Uri.EMPTY, mTunerSource,
+ new BufferManager(mDvrStorageManager), this, true);
mRecorder.setOnCompletionListener(this, mHandler);
mProgramUri = programUri;
mSessionState = STATE_RECORDING;
@@ -392,6 +422,34 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
Log.i(TAG, "Recording stopped");
}
+ private void updateCaptionTracks(TunerChannel channel, List<PsipData.EitItem> items) {
+ if (mChannel == null || channel == null || mChannel.compareTo(channel) != 0
+ || items == null || items.isEmpty()) {
+ return;
+ }
+ PsipData.EitItem currentProgram = getCurrentProgram(items);
+ if (currentProgram == null || !currentProgram.hasCaptionTrack()
+ || mCurrenProgram != null && mCurrenProgram.compareTo(currentProgram) == 0) {
+ return;
+ }
+ mCurrenProgram = currentProgram;
+ mCaptionTracks = new ArrayList<>(currentProgram.getCaptionTracks());
+ if (DEBUG) {
+ Log.d(TAG, "updated " + mCaptionTracks.size() + " caption tracks for "
+ + currentProgram);
+ }
+ }
+
+ private PsipData.EitItem getCurrentProgram(List<PsipData.EitItem> items) {
+ for (PsipData.EitItem item : items) {
+ if (mRecordStartTime >= item.getStartTimeUtcMillis()
+ && mRecordStartTime < item.getEndTimeUtcMillis()) {
+ return item;
+ }
+ }
+ return null;
+ }
+
private static class Program {
private final long mChannelId;
private final String mTitle;
@@ -566,15 +624,25 @@ public class TunerRecordingSessionWorker implements PlaybackBufferListener,
return;
}
Log.i(TAG, "recording finished " + (success ? "completely" : "partially"));
- Uri uri = insertRecordedProgram(getRecordedProgram(), mChannel.getChannelId(),
- Uri.fromFile(mStorageDir).toString(), 1024 * 1024, mRecordStartTime,
- mRecordStartTime + TimeUnit.MICROSECONDS.toMillis(lastExtractedPositionUs));
+ long recordEndTime =
+ (lastExtractedPositionUs == C.UNKNOWN_TIME_US)
+ ? System.currentTimeMillis()
+ : mRecordStartTime + lastExtractedPositionUs / 1000;
+ Uri uri =
+ insertRecordedProgram(
+ getRecordedProgram(),
+ mChannel.getChannelId(),
+ Uri.fromFile(mStorageDir).toString(),
+ 1024 * 1024,
+ mRecordStartTime,
+ recordEndTime);
if (uri == null) {
new DeleteRecordingTask().execute(mStorageDir);
mSession.onError(TvInputManager.RECORDING_ERROR_UNKNOWN);
Log.e(TAG, "Inserting a recording to DB failed");
return;
}
+ mDvrStorageManager.writeCaptionInfoFiles(mCaptionTracks);
mSession.onRecordFinished(uri);
}
diff --git a/src/com/android/tv/tuner/tvinput/TunerSession.java b/src/com/android/tv/tuner/tvinput/TunerSession.java
index 5c61402e..44bae908 100644
--- a/src/com/android/tv/tuner/tvinput/TunerSession.java
+++ b/src/com/android/tv/tuner/tvinput/TunerSession.java
@@ -38,12 +38,12 @@ import android.widget.Toast;
import com.google.android.exoplayer.audio.AudioCapabilities;
import com.android.tv.tuner.R;
+import com.android.tv.tuner.TunerPreferences;
+import com.android.tv.tuner.TunerPreferences.TunerPreferencesChangedListener;
import com.android.tv.tuner.cc.CaptionLayout;
import com.android.tv.tuner.cc.CaptionTrackRenderer;
import com.android.tv.tuner.data.Cea708Data.CaptionEvent;
import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
-import com.android.tv.tuner.exoplayer.buffer.BufferManager;
-import com.android.tv.tuner.data.TunerChannel;
import com.android.tv.tuner.util.GlobalSettingsUtils;
import com.android.tv.tuner.util.StatusTextUtils;
import com.android.tv.tuner.util.SystemPropertiesProxy;
@@ -52,7 +52,8 @@ import com.android.tv.tuner.util.SystemPropertiesProxy;
* Provides a tuner TV input session. It handles Overlay UI works. Main tuner input functions
* are implemented in {@link TunerSessionWorker}.
*/
-public class TunerSession extends TvInputService.Session implements Handler.Callback {
+public class TunerSession extends TvInputService.Session implements
+ Handler.Callback, TunerPreferencesChangedListener {
private static final String TAG = "TunerSession";
private static final boolean DEBUG = false;
private static final String USBTUNER_SHOW_DEBUG = "persist.tv.tuner.show_debug";
@@ -65,8 +66,9 @@ public class TunerSession extends TvInputService.Session implements Handler.Call
public static final int MSG_UI_START_CAPTION_TRACK = 6;
public static final int MSG_UI_STOP_CAPTION_TRACK = 7;
public static final int MSG_UI_RESET_CAPTION_TRACK = 8;
- public static final int MSG_UI_SET_STATUS_TEXT = 9;
- public static final int MSG_UI_TOAST_RESCAN_NEEDED = 10;
+ public static final int MSG_UI_CLEAR_CAPTION_RENDERER = 9;
+ public static final int MSG_UI_SET_STATUS_TEXT = 10;
+ public static final int MSG_UI_TOAST_RESCAN_NEEDED = 11;
private final Context mContext;
private final Handler mUiHandler;
@@ -81,8 +83,7 @@ public class TunerSession extends TvInputService.Session implements Handler.Call
private boolean mPlayPaused;
private long mTuneStartTimestamp;
- public TunerSession(Context context, ChannelDataManager channelDataManager,
- BufferManager bufferManager) {
+ public TunerSession(Context context, ChannelDataManager channelDataManager) {
super(context);
mContext = context;
mUiHandler = new Handler(this);
@@ -97,12 +98,10 @@ public class TunerSession extends TvInputService.Session implements Handler.Call
mStatusView.setVisibility(showDebug ? View.VISIBLE : View.INVISIBLE);
mAudioStatusView = (TextView) mOverlayView.findViewById(R.id.audio_status);
mAudioStatusView.setVisibility(View.INVISIBLE);
- mAudioStatusView.setText(Html.fromHtml(StatusTextUtils.getAudioWarningInHTML(
- context.getString(R.string.ut_surround_sound_disabled))));
CaptionLayout captionLayout = (CaptionLayout) mOverlayView.findViewById(R.id.caption);
mCaptionTrackRenderer = new CaptionTrackRenderer(captionLayout);
- mSessionWorker = new TunerSessionWorker(context, channelDataManager,
- bufferManager, this);
+ mSessionWorker = new TunerSessionWorker(context, channelDataManager, this);
+ TunerPreferences.setTunerPreferencesChangedListener(this);
}
public boolean isReleased() {
@@ -214,6 +213,7 @@ public class TunerSession extends TvInputService.Session implements Handler.Call
mReleased = true;
mSessionWorker.release();
mUiHandler.removeCallbacksAndMessages(null);
+ TunerPreferences.setTunerPreferencesChangedListener(null);
}
/**
@@ -272,10 +272,13 @@ public class TunerSession extends TvInputService.Session implements Handler.Call
// setting is "never".
final int value = GlobalSettingsUtils.getEncodedSurroundOutputSettings(mContext);
if (value == GlobalSettingsUtils.ENCODED_SURROUND_OUTPUT_NEVER) {
- mAudioStatusView.setVisibility(View.VISIBLE);
+ mAudioStatusView.setText(Html.fromHtml(StatusTextUtils.getAudioWarningInHTML(
+ mContext.getString(R.string.ut_surround_sound_disabled))));
} else {
- Log.e(TAG, "Audio is unavailable, surround sound setting is " + value);
+ mAudioStatusView.setText(Html.fromHtml(StatusTextUtils.getAudioWarningInHTML(
+ mContext.getString(R.string.audio_passthrough_not_supported))));
}
+ mAudioStatusView.setVisibility(View.VISIBLE);
return true;
}
case MSG_UI_HIDE_AUDIO_UNPLAYABLE: {
@@ -298,6 +301,10 @@ public class TunerSession extends TvInputService.Session implements Handler.Call
mCaptionTrackRenderer.reset();
return true;
}
+ case MSG_UI_CLEAR_CAPTION_RENDERER: {
+ mCaptionTrackRenderer.clear();
+ return true;
+ }
case MSG_UI_SET_STATUS_TEXT: {
mStatusView.setText((CharSequence) msg.obj);
return true;
@@ -309,4 +316,9 @@ public class TunerSession extends TvInputService.Session implements Handler.Call
}
return false;
}
+
+ @Override
+ public void onTunerPreferencesChanged() {
+ mSessionWorker.sendMessage(TunerSessionWorker.MSG_TUNER_PREFERENCES_CHANGED);
+ }
}
diff --git a/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java b/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java
index 5230298e..e7eb017e 100644
--- a/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java
+++ b/src/com/android/tv/tuner/tvinput/TunerSessionWorker.java
@@ -27,6 +27,7 @@ import android.media.tv.TvContract;
import android.media.tv.TvInputManager;
import android.media.tv.TvTrackInfo;
import android.net.Uri;
+import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@@ -35,6 +36,7 @@ import android.support.annotation.AnyThread;
import android.support.annotation.MainThread;
import android.support.annotation.WorkerThread;
import android.text.Html;
+import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
@@ -45,7 +47,10 @@ import com.google.android.exoplayer.audio.AudioCapabilities;
import com.google.android.exoplayer.ExoPlayer;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.TvContentRatingCache;
+import com.android.tv.customization.TvCustomizationManager;
+import com.android.tv.customization.TvCustomizationManager.TRICKPLAY_MODE;
import com.android.tv.tuner.TunerPreferences;
+import com.android.tv.tuner.TunerPreferences.TrickplaySetting;
import com.android.tv.tuner.data.Cea708Data;
import com.android.tv.tuner.data.PsipData.EitItem;
import com.android.tv.tuner.data.PsipData.TvTracksInterface;
@@ -55,20 +60,23 @@ import com.android.tv.tuner.data.nano.Track.AtscAudioTrack;
import com.android.tv.tuner.data.nano.Track.AtscCaptionTrack;
import com.android.tv.tuner.exoplayer.MpegTsRendererBuilder;
import com.android.tv.tuner.exoplayer.buffer.BufferManager;
+import com.android.tv.tuner.exoplayer.buffer.BufferManager.StorageManager;
import com.android.tv.tuner.exoplayer.buffer.DvrStorageManager;
import com.android.tv.tuner.exoplayer.MpegTsPlayer;
+import com.android.tv.tuner.exoplayer.buffer.TrickplayStorageManager;
+import com.android.tv.tuner.exoplayer.ffmpeg.FfmpegDecoderClient;
import com.android.tv.tuner.source.TsDataSource;
import com.android.tv.tuner.source.TsDataSourceManager;
import com.android.tv.tuner.util.StatusTextUtils;
+import com.android.tv.tuner.util.SystemPropertiesProxy;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
-import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
/**
* {@link TunerSessionWorker} implements a handler thread which processes TV input jobs
@@ -82,6 +90,9 @@ public class TunerSessionWorker implements PlaybackBufferListener,
private static final boolean DEBUG = false;
private static final boolean ENABLE_PROFILER = true;
private static final String PLAY_FROM_CHANNEL = "channel";
+ private static final String MAX_BUFFER_SIZE_KEY = "tv.tuner.buffersize_mbytes";
+ private static final int MAX_BUFFER_SIZE_DEF = 2 * 1024; // 2GB
+ private static final int MIN_BUFFER_SIZE_DEF = 256; // 256MB
// Public messages
public static final int MSG_SELECT_TRACK = 1;
@@ -93,6 +104,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
public static final int MSG_TIMESHIFT_SET_PLAYBACKPARAMS = 7;
public static final int MSG_AUDIO_CAPABILITIES_CHANGED = 8;
public static final int MSG_UNBLOCKED_RATING = 9;
+ public static final int MSG_TUNER_PREFERENCES_CHANGED = 10;
// Private messages
private static final int MSG_TUNE = 1000;
@@ -147,10 +159,20 @@ public class TunerSessionWorker implements PlaybackBufferListener,
private static final int EXPECTED_KEY_FRAME_INTERVAL_MS = 500;
private static final int MIN_TRICKPLAY_SEEK_INTERVAL_MS = 20;
private static final int TRICKPLAY_MONITOR_INTERVAL_MS = 250;
+ private static final int RELEASE_WAIT_INTERVAL_MS = 50;
+ private static final long TRICKPLAY_OFF_DURATION_MS = TimeUnit.DAYS.toMillis(14);
+
+ // Since release() is done asynchronously, synchronization between multiple TunerSessionWorker
+ // creation/release is required.
+ // This is used to guarantee that at most one active TunerSessionWorker exists at any give time.
+ private static Semaphore sActiveSessionSemaphore = new Semaphore(1);
private final Context mContext;
private final ChannelDataManager mChannelDataManager;
private final TsDataSourceManager mSourceManager;
+ private final int mMaxTrickplayBufferSizeMb;
+ private final File mTrickplayBufferDir;
+ private final @TRICKPLAY_MODE int mTrickplayModeCustomization;
private volatile Surface mSurface;
private volatile float mVolume = 1.0f;
private volatile boolean mCaptionEnabled;
@@ -159,6 +181,9 @@ public class TunerSessionWorker implements PlaybackBufferListener,
private volatile Long mRecordingDuration;
private volatile long mRecordStartTimeMs;
private volatile long mBufferStartTimeMs;
+ private volatile boolean mTrickplayDisabledByStorageIssue;
+ private @TrickplaySetting int mTrickplaySetting;
+ private long mTrickplayExpiredMs;
private String mRecordingId;
private final Handler mHandler;
private int mRetryCount;
@@ -177,19 +202,20 @@ public class TunerSessionWorker implements PlaybackBufferListener,
private TvContentRating mUnblockedContentRating;
private long mLastPositionMs;
private AudioCapabilities mAudioCapabilities;
- private final CountDownLatch mReleaseLatch = new CountDownLatch(1);
private long mLastLimitInBytes;
- private long mLastPositionInBytes;
- private final BufferManager mBufferManager;
private final TvContentRatingCache mTvContentRatingCache = TvContentRatingCache.getInstance();
private final TunerSession mSession;
+ private final boolean mHasSoftwareAudioDecoder;
private int mPlayerState = ExoPlayer.STATE_IDLE;
private long mPreparingStartTimeMs;
private long mBufferingStartTimeMs;
private long mReadyStartTimeMs;
+ private boolean mIsActiveSession;
+ private boolean mReleaseRequested; // Guarded by mReleaseLock
+ private final Object mReleaseLock = new Object();
public TunerSessionWorker(Context context, ChannelDataManager channelDataManager,
- BufferManager bufferManager, TunerSession tunerSession) {
+ TunerSession tunerSession) {
if (DEBUG) Log.d(TAG, "TunerSessionWorker created");
mContext = context;
@@ -211,10 +237,39 @@ public class TunerSessionWorker implements PlaybackBufferListener,
(CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
mCaptionEnabled = captioningManager.isEnabled();
mPlaybackParams.setSpeed(1.0f);
- mBufferManager = bufferManager;
+ mMaxTrickplayBufferSizeMb =
+ SystemPropertiesProxy.getInt(MAX_BUFFER_SIZE_KEY, MAX_BUFFER_SIZE_DEF);
+ mTrickplayModeCustomization = TvCustomizationManager.getTrickplayMode(context);
+ if (mTrickplayModeCustomization ==
+ TvCustomizationManager.TRICKPLAY_MODE_USE_EXTERNAL_STORAGE) {
+ boolean useExternalStorage =
+ Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) &&
+ Environment.isExternalStorageRemovable();
+ mTrickplayBufferDir = useExternalStorage ? context.getExternalCacheDir() : null;
+ } else if (mTrickplayModeCustomization == TvCustomizationManager.TRICKPLAY_MODE_ENABLED) {
+ mTrickplayBufferDir = context.getCacheDir();
+ } else {
+ mTrickplayBufferDir = null;
+ }
+ mTrickplayDisabledByStorageIssue = mTrickplayBufferDir == null;
+ mTrickplaySetting = TunerPreferences.getTrickplaySetting(context);
+ if (mTrickplaySetting != TunerPreferences.TRICKPLAY_SETTING_NOT_SET
+ && mTrickplayModeCustomization
+ == TvCustomizationManager.TRICKPLAY_MODE_USE_EXTERNAL_STORAGE) {
+ // Consider the case of Customization package updates the value of trickplay mode
+ // to TRICKPLAY_MODE_USE_EXTERNAL_STORAGE after install.
+ mTrickplaySetting = TunerPreferences.TRICKPLAY_SETTING_NOT_SET;
+ TunerPreferences.setTrickplaySetting(context, mTrickplaySetting);
+ TunerPreferences.setTrickplayExpiredMs(context, 0);
+ }
+ mTrickplayExpiredMs = TunerPreferences.getTrickplayExpiredMs(context);
mPreparingStartTimeMs = INVALID_TIME;
mBufferingStartTimeMs = INVALID_TIME;
mReadyStartTimeMs = INVALID_TIME;
+ // NOTE: We assume that TunerSessionWorker instance will be at most one.
+ // Only one TunerSessionWorker can be connected to FfmpegDecoderClient at any given time.
+ // connect() will return false, if there is a connected TunerSessionWorker already.
+ mHasSoftwareAudioDecoder = FfmpegDecoderClient.connect(context);
}
// Public methods
@@ -285,24 +340,21 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
private Long getDurationForRecording(String recordingId) {
- try {
- DvrStorageManager storageManager =
+ DvrStorageManager storageManager =
new DvrStorageManager(new File(getRecordingPath()), false);
- Pair<String, MediaFormat> trackInfo = null;
- try {
- trackInfo = storageManager.readTrackInfoFile(false);
- } catch (FileNotFoundException e) {
- }
- if (trackInfo == null) {
- trackInfo = storageManager.readTrackInfoFile(true);
- }
- Long durationUs = trackInfo.second.getLong(MediaFormat.KEY_DURATION);
+ List<BufferManager.TrackFormat> trackFormatList =
+ storageManager.readTrackInfoFiles(false);
+ if (trackFormatList.isEmpty()) {
+ trackFormatList = storageManager.readTrackInfoFiles(true);
+ }
+ if (!trackFormatList.isEmpty()) {
+ BufferManager.TrackFormat trackFormat = trackFormatList.get(0);
+ Long durationUs = trackFormat.format.getLong(MediaFormat.KEY_DURATION);
// we need duration by milli for trickplay notification.
return durationUs != null ? durationUs / 1000 : null;
- } catch (IOException e) {
- Log.e(TAG, "meta file for recording was not found: " + recordingId);
- return null;
}
+ Log.e(TAG, "meta file for recording was not found: " + recordingId);
+ return null;
}
@MainThread
@@ -341,16 +393,15 @@ public class TunerSessionWorker implements PlaybackBufferListener,
@MainThread
public void release() {
if (DEBUG) Log.d(TAG, "release()");
+ synchronized (mReleaseLock) {
+ mReleaseRequested = true;
+ }
+ if (mHasSoftwareAudioDecoder) {
+ FfmpegDecoderClient.disconnect(mContext);
+ }
mChannelDataManager.setListener(null);
mHandler.removeCallbacksAndMessages(null);
mHandler.sendEmptyMessage(MSG_RELEASE);
- try {
- mReleaseLatch.await();
- } catch (InterruptedException e) {
- Log.e(TAG, "Couldn't wait for finish of MSG_RELEASE", e);
- } finally {
- mHandler.getLooper().quitSafely();
- }
}
// MpegTsPlayer.Listener
@@ -367,7 +418,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
if (playbackState == ExoPlayer.STATE_READY) {
if (DEBUG) Log.d(TAG, "ExoPlayer ready");
if (!mPlayerStarted) {
- sendMessage(MSG_START_PLAYBACK, mPlayer);
+ sendMessage(MSG_START_PLAYBACK, System.identityHashCode(mPlayer));
}
mReadyStartTimeMs = SystemClock.elapsedRealtime();
} else if (playbackState == ExoPlayer.STATE_PREPARING) {
@@ -379,7 +430,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
// notification of STATE_ENDED from MpegTsPlayer will be ignored afterwards.
Log.i(TAG, "Player ended: end of stream");
if (mChannel != null) {
- sendMessage(MSG_RETRY_PLAYBACK, mPlayer);
+ sendMessage(MSG_RETRY_PLAYBACK, System.identityHashCode(mPlayer));
}
}
mPlayerState = playbackState;
@@ -397,7 +448,8 @@ public class TunerSessionWorker implements PlaybackBufferListener,
// If we are playing live stream, retrying playback maybe helpful. But for recorded stream,
// retrying playback is not helpful.
if (mChannel != null) {
- mHandler.obtainMessage(MSG_RETRY_PLAYBACK, mPlayer).sendToTarget();
+ mHandler.obtainMessage(MSG_RETRY_PLAYBACK, System.identityHashCode(mPlayer))
+ .sendToTarget();
}
}
@@ -415,8 +467,12 @@ public class TunerSessionWorker implements PlaybackBufferListener,
public void onDrawnToSurface(MpegTsPlayer player, Surface surface) {
if (mSurface != null && mPlayerStarted) {
if (DEBUG) Log.d(TAG, "MSG_DRAWN_TO_SURFACE");
- mBufferStartTimeMs = mRecordStartTimeMs =
- (mRecordingId != null) ? 0 : System.currentTimeMillis();
+ if (mRecordingId != null) {
+ // Workaround of b/33298048: set it to 1 instead of 0.
+ mBufferStartTimeMs = mRecordStartTimeMs = 1;
+ } else {
+ mBufferStartTimeMs = mRecordStartTimeMs = System.currentTimeMillis();
+ }
notifyVideoAvailable();
mReportedDrawnToSurface = true;
@@ -461,6 +517,11 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
@Override
+ public void onClearCaptionEvent() {
+ mSession.sendUiMessage(TunerSession.MSG_UI_CLEAR_CAPTION_RENDERER);
+ }
+
+ @Override
public void onDiscoverCaptionServiceNumber(int serviceNumber) {
sendMessage(MSG_DISCOVER_CAPTION_SERVICE_NUMBER, serviceNumber);
}
@@ -499,7 +560,8 @@ public class TunerSessionWorker implements PlaybackBufferListener,
@Override
public void onDiskTooSlow() {
- sendMessage(MSG_RETRY_PLAYBACK, mPlayer);
+ mTrickplayDisabledByStorageIssue = true;
+ sendMessage(MSG_RETRY_PLAYBACK, System.identityHashCode(mPlayer));
}
// EventDetector.EventListener
@@ -602,6 +664,28 @@ public class TunerSessionWorker implements PlaybackBufferListener,
return true;
}
notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING);
+ if (!mIsActiveSession) {
+ // Wait until release is finished if there is a pending release.
+ try {
+ while (!sActiveSessionSemaphore.tryAcquire(
+ RELEASE_WAIT_INTERVAL_MS, TimeUnit.MILLISECONDS)) {
+ synchronized (mReleaseLock) {
+ if (mReleaseRequested) {
+ return true;
+ }
+ }
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ synchronized (mReleaseLock) {
+ if (mReleaseRequested) {
+ sActiveSessionSemaphore.release();
+ return true;
+ }
+ }
+ mIsActiveSession = true;
+ }
Uri channelUri = (Uri) msg.obj;
String recording = null;
long channelId = parseChannel(channelUri);
@@ -616,7 +700,8 @@ public class TunerSessionWorker implements PlaybackBufferListener,
notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN);
return true;
}
- mHandler.removeCallbacksAndMessages(null);
+ clearCallbacksAndMessagesSafely();
+ mChannelDataManager.removeAllCallbacksAndMessages();
if (channel != null) {
mChannelDataManager.requestProgramsData(channel);
}
@@ -624,8 +709,8 @@ public class TunerSessionWorker implements PlaybackBufferListener,
// TODO: Need to refactor. notifyContentAllowed() should not be called if parental
// control is turned on.
mSession.notifyContentAllowed();
- resetPlayback();
resetTvTracks();
+ resetPlayback();
mHandler.sendEmptyMessageDelayed(MSG_RESCHEDULE_PROGRAMS,
RESCHEDULE_PROGRAMS_INITIAL_DELAY_MS);
return true;
@@ -633,7 +718,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
case MSG_STOP_TUNE: {
if (DEBUG) Log.d(TAG, "MSG_STOP_TUNE");
mChannel = null;
- stopPlayback();
+ stopPlayback(true);
stopCaptionTrack();
resetTvTracks();
notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN);
@@ -642,14 +727,17 @@ public class TunerSessionWorker implements PlaybackBufferListener,
case MSG_RELEASE: {
if (DEBUG) Log.d(TAG, "MSG_RELEASE");
mHandler.removeCallbacksAndMessages(null);
- stopPlayback();
+ stopPlayback(true);
stopCaptionTrack();
mSourceManager.release();
- mReleaseLatch.countDown();
+ mHandler.getLooper().quitSafely();
+ if (mIsActiveSession) {
+ sActiveSessionSemaphore.release();
+ }
return true;
}
case MSG_RETRY_PLAYBACK: {
- if (mPlayer == msg.obj) {
+ if (System.identityHashCode(mPlayer) == (int) msg.obj) {
Log.i(TAG, "Retrying the playback for channel: " + mChannel);
mHandler.removeMessages(MSG_RETRY_PLAYBACK);
// When there is a request of retrying playback, don't reuse TunerHal.
@@ -658,16 +746,18 @@ public class TunerSessionWorker implements PlaybackBufferListener,
if (DEBUG) {
Log.d(TAG, "MSG_RETRY_PLAYBACK " + mRetryCount);
}
+ mChannelDataManager.removeAllCallbacksAndMessages();
if (mRetryCount <= MAX_IMMEDIATE_RETRY_COUNT) {
resetPlayback();
} else {
// When it reaches this point, it may be due to an error that occurred in
// the tuner device. Calling stopPlayback() resets the tuner device
// to recover from the error.
- stopPlayback();
+ stopPlayback(false);
stopCaptionTrack();
notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL);
+ Log.i(TAG, "Notify weak signal since fail to retry playback");
// After MAX_IMMEDIATE_RETRY_COUNT, give some delay of an empirically chosen
// value before recovering the playback.
@@ -679,13 +769,14 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
case MSG_RESET_PLAYBACK: {
if (DEBUG) Log.d(TAG, "MSG_RESET_PLAYBACK");
+ mChannelDataManager.removeAllCallbacksAndMessages();
resetPlayback();
return true;
}
case MSG_START_PLAYBACK: {
if (DEBUG) Log.d(TAG, "MSG_START_PLAYBACK");
if (mChannel != null || mRecordingId != null) {
- startPlayback(msg.obj);
+ startPlayback((int) msg.obj);
}
return true;
}
@@ -790,7 +881,11 @@ public class TunerSessionWorker implements PlaybackBufferListener,
return true;
}
case MSG_RESCHEDULE_PROGRAMS: {
- doReschedulePrograms();
+ if (mHandler.hasMessages(MSG_SCHEDULE_OF_PROGRAMS)) {
+ mHandler.sendEmptyMessage(MSG_RESCHEDULE_PROGRAMS);
+ } else {
+ doReschedulePrograms();
+ }
return true;
}
case MSG_PARENTAL_CONTROLS: {
@@ -814,11 +909,8 @@ public class TunerSessionWorker implements PlaybackBufferListener,
return true;
}
case MSG_SELECT_TRACK: {
- if (mChannel != null) {
+ if (mChannel != null || mRecordingId != null) {
doSelectTrack(msg.arg1, (String) msg.obj);
- } else if (mRecordingId != null) {
- // TODO : mChannel == null && mRecordingId != null
- Log.d(TAG, "track selected for recording");
}
return true;
}
@@ -835,6 +927,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
if (mPlayer == null) {
return true;
}
+ setTrickplayEnabledIfNeeded();
doTimeShiftPause();
return true;
}
@@ -843,6 +936,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
if (mPlayer == null) {
return true;
}
+ setTrickplayEnabledIfNeeded();
doTimeShiftResume();
return true;
}
@@ -852,6 +946,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
if (mPlayer == null) {
return true;
}
+ setTrickplayEnabledIfNeeded();
doTimeShiftSeekTo(position);
return true;
}
@@ -859,6 +954,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
if (mPlayer == null) {
return true;
}
+ setTrickplayEnabledIfNeeded();
doTimeShiftSetPlaybackParams((PlaybackParams) msg.obj);
return true;
}
@@ -883,6 +979,22 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
return true;
}
+ case MSG_TUNER_PREFERENCES_CHANGED: {
+ mHandler.removeMessages(MSG_TUNER_PREFERENCES_CHANGED);
+ @TrickplaySetting int trickplaySetting =
+ TunerPreferences.getTrickplaySetting(mContext);
+ if (trickplaySetting != mTrickplaySetting) {
+ boolean wasTrcikplayEnabled =
+ mTrickplaySetting != TunerPreferences.TRICKPLAY_SETTING_DISABLED;
+ boolean isTrickplayEnabled =
+ trickplaySetting != TunerPreferences.TRICKPLAY_SETTING_DISABLED;
+ mTrickplaySetting = trickplaySetting;
+ if (isTrickplayEnabled != wasTrcikplayEnabled) {
+ sendMessage(MSG_RESET_PLAYBACK, System.identityHashCode(mPlayer));
+ }
+ }
+ return true;
+ }
case MSG_BUFFER_START_TIME_CHANGED: {
if (mPlayer == null) {
return true;
@@ -891,7 +1003,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
if (!hasEnoughBackwardBuffer()
&& (!mPlayer.isPlaying() || mPlaybackParams.getSpeed() < 1.0f)) {
mPlayer.setPlayWhenReady(true);
- mPlayer.setAudioTrack(true);
+ mPlayer.setAudioTrackAndClosedCaption(true);
mPlaybackParams.setSpeed(1.0f);
}
return true;
@@ -909,7 +1021,6 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
TsDataSource source = mPlayer.getDataSource();
long limitInBytes = source != null ? source.getBufferedPosition() : 0L;
- long positionInBytes = source != null ? source.getLastReadPosition() : 0L;
if (TunerDebug.ENABLED) {
TunerDebug.calculateDiff();
mSession.sendUiMessage(TunerSession.MSG_UI_SET_STATUS_TEXT,
@@ -927,32 +1038,36 @@ public class TunerSessionWorker implements PlaybackBufferListener,
TunerDebug.getVideoPtsUsRate()
)));
}
- if (DEBUG) {
- Log.d(TAG, String.format("MSG_CHECK_SIGNAL position: %d, limit: %d",
- positionInBytes, limitInBytes));
- }
mSession.sendUiMessage(TunerSession.MSG_UI_HIDE_MESSAGE);
long currentTime = SystemClock.elapsedRealtime();
- boolean noBufferRead = positionInBytes == mLastPositionInBytes
- && limitInBytes == mLastLimitInBytes;
- boolean isBufferingTooLong = mBufferingStartTimeMs != INVALID_TIME
- && currentTime - mBufferingStartTimeMs
- > PLAYBACK_STATE_CHANGED_WAITING_THRESHOLD_MS;
- boolean isPreparingTooLong = mPreparingStartTimeMs != INVALID_TIME
- && currentTime - mPreparingStartTimeMs
- > PLAYBACK_STATE_CHANGED_WAITING_THRESHOLD_MS;
+ long bufferingTimeMs = mBufferingStartTimeMs != INVALID_TIME
+ ? currentTime - mBufferingStartTimeMs : mBufferingStartTimeMs;
+ long preparingTimeMs = mPreparingStartTimeMs != INVALID_TIME
+ ? currentTime - mPreparingStartTimeMs : mPreparingStartTimeMs;
+ boolean isBufferingTooLong =
+ bufferingTimeMs > PLAYBACK_STATE_CHANGED_WAITING_THRESHOLD_MS;
+ boolean isPreparingTooLong =
+ preparingTimeMs > PLAYBACK_STATE_CHANGED_WAITING_THRESHOLD_MS;
boolean isWeakSignal = source != null
- && mChannel.getType() == Channel.TYPE_TUNER
- && (noBufferRead || isBufferingTooLong || isPreparingTooLong);
+ && mChannel.getType() != Channel.TYPE_FILE
+ && (isBufferingTooLong || isPreparingTooLong);
if (isWeakSignal && !mReportedWeakSignal) {
if (!mHandler.hasMessages(MSG_RETRY_PLAYBACK)) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(
- MSG_RETRY_PLAYBACK, mPlayer), PLAYBACK_RETRY_DELAY_MS);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RETRY_PLAYBACK,
+ System.identityHashCode(mPlayer)), PLAYBACK_RETRY_DELAY_MS);
}
if (mPlayer != null) {
- mPlayer.setAudioTrack(false);
+ mPlayer.setAudioTrackAndClosedCaption(false);
}
notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL);
+ Log.i(TAG, "Notify weak signal due to signal check, " + String.format(
+ "packetsPerSec:%d, bufferingTimeMs:%d, preparingTimeMs:%d, " +
+ "videoFrameDrop:%d",
+ (limitInBytes - mLastLimitInBytes) / TS_PACKET_SIZE,
+ bufferingTimeMs,
+ preparingTimeMs,
+ TunerDebug.getVideoFrameDrop()
+ ));
} else if (!isWeakSignal && mReportedWeakSignal) {
boolean isPlaybackStable = mReadyStartTimeMs != INVALID_TIME
&& currentTime - mReadyStartTimeMs
@@ -962,11 +1077,10 @@ public class TunerSessionWorker implements PlaybackBufferListener,
} else if (mReportedDrawnToSurface) {
mHandler.removeMessages(MSG_RETRY_PLAYBACK);
notifyVideoAvailable();
- mPlayer.setAudioTrack(true);
+ mPlayer.setAudioTrackAndClosedCaption(true);
}
}
mLastLimitInBytes = limitInBytes;
- mLastPositionInBytes = positionInBytes;
mHandler.sendEmptyMessageDelayed(MSG_CHECK_SIGNAL, CHECK_NO_SIGNAL_PERIOD_MS);
return true;
}
@@ -999,15 +1113,8 @@ public class TunerSessionWorker implements PlaybackBufferListener,
if (trackId == null) {
return;
}
- AtscAudioTrack audioTrack = mAudioTrackMap.get(numTrackId);
- if (audioTrack == null) {
- return;
- }
- int oldAudioPid = mChannel.getAudioPid();
- mChannel.selectAudioTrack(audioTrack.index);
- int newAudioPid = mChannel.getAudioPid();
- if (oldAudioPid != newAudioPid) {
- mPlayer.setSelectedTrack(MpegTsPlayer.TRACK_TYPE_AUDIO, audioTrack.index);
+ if (numTrackId != mPlayer.getSelectedTrack(MpegTsPlayer.TRACK_TYPE_AUDIO)) {
+ mPlayer.setSelectedTrack(MpegTsPlayer.TRACK_TYPE_AUDIO, numTrackId);
}
mSession.notifyTrackSelected(type, trackId);
} else if (type == TvTrackInfo.TYPE_SUBTITLE) {
@@ -1030,11 +1137,49 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
}
- private MpegTsPlayer createPlayer(AudioCapabilities capabilities, BufferManager bufferManager) {
+ private void setTrickplayEnabledIfNeeded() {
+ if (mChannel == null ||
+ mTrickplayModeCustomization != TvCustomizationManager.TRICKPLAY_MODE_ENABLED) {
+ return;
+ }
+ if (mTrickplaySetting == TunerPreferences.TRICKPLAY_SETTING_NOT_SET) {
+ mTrickplaySetting = TunerPreferences.TRICKPLAY_SETTING_ENABLED;
+ TunerPreferences.setTrickplaySetting(
+ mContext, mTrickplaySetting);
+ }
+ }
+
+ private MpegTsPlayer createPlayer(AudioCapabilities capabilities) {
if (capabilities == null) {
Log.w(TAG, "No Audio Capabilities");
}
-
+ long now = System.currentTimeMillis();
+ if (mTrickplayModeCustomization == TvCustomizationManager.TRICKPLAY_MODE_ENABLED
+ && mTrickplaySetting == TunerPreferences.TRICKPLAY_SETTING_NOT_SET) {
+ if (mTrickplayExpiredMs == 0) {
+ mTrickplayExpiredMs = now + TRICKPLAY_OFF_DURATION_MS;
+ TunerPreferences.setTrickplayExpiredMs(mContext, mTrickplayExpiredMs);
+ } else {
+ if (mTrickplayExpiredMs < now) {
+ mTrickplaySetting = TunerPreferences.TRICKPLAY_SETTING_DISABLED;
+ TunerPreferences.setTrickplaySetting(mContext, mTrickplaySetting);
+ }
+ }
+ }
+ BufferManager bufferManager = null;
+ if (mRecordingId != null) {
+ StorageManager storageManager =
+ new DvrStorageManager(new File(getRecordingPath()), false);
+ bufferManager = new BufferManager(storageManager);
+ updateCaptionTracks(((DvrStorageManager)storageManager).readCaptionInfoFiles());
+ } else if (!mTrickplayDisabledByStorageIssue
+ && mTrickplaySetting != TunerPreferences.TRICKPLAY_SETTING_DISABLED
+ && mMaxTrickplayBufferSizeMb >= MIN_BUFFER_SIZE_DEF) {
+ bufferManager = new BufferManager(new TrickplayStorageManager(mContext,
+ mTrickplayBufferDir, 1024L * 1024 * mMaxTrickplayBufferSizeMb));
+ } else {
+ Log.w(TAG, "Trickplay is disabled.");
+ }
MpegTsPlayer player = new MpegTsPlayer(
new MpegTsRendererBuilder(mContext, bufferManager, this),
mHandler, mSourceManager, capabilities, this);
@@ -1069,24 +1214,26 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
private void updateTvTracks(TvTracksInterface tvTracksInterface, boolean fromPmt) {
- if (DEBUG) {
- Log.d(TAG, "UpdateTvTracks " + tvTracksInterface);
- }
- List<AtscAudioTrack> audioTracks = tvTracksInterface.getAudioTracks();
- List<AtscCaptionTrack> captionTracks = tvTracksInterface.getCaptionTracks();
- // According to ATSC A/69 chapter 6.9, both PMT and EIT should have descriptors for audio
- // tracks, but in real world, we see some bogus audio track info in EIT, so, we trust audio
- // track info in PMT more and use info in EIT only when we have nothing.
- if (audioTracks != null && !audioTracks.isEmpty()
- && (mChannel.getAudioTracks() == null || fromPmt)) {
- updateAudioTracks(audioTracks);
- }
- if (captionTracks == null || captionTracks.isEmpty()) {
- if (tvTracksInterface.hasCaptionTrack()) {
+ synchronized (tvTracksInterface) {
+ if (DEBUG) {
+ Log.d(TAG, "UpdateTvTracks " + tvTracksInterface);
+ }
+ List<AtscAudioTrack> audioTracks = tvTracksInterface.getAudioTracks();
+ List<AtscCaptionTrack> captionTracks = tvTracksInterface.getCaptionTracks();
+ // According to ATSC A/69 chapter 6.9, both PMT and EIT should have descriptors for audio
+ // tracks, but in real world, we see some bogus audio track info in EIT, so, we trust audio
+ // track info in PMT more and use info in EIT only when we have nothing.
+ if (audioTracks != null && !audioTracks.isEmpty()
+ && (mChannel == null || mChannel.getAudioTracks() == null || fromPmt)) {
+ updateAudioTracks(audioTracks);
+ }
+ if (captionTracks == null || captionTracks.isEmpty()) {
+ if (tvTracksInterface.hasCaptionTrack()) {
+ updateCaptionTracks(captionTracks);
+ }
+ } else {
updateCaptionTracks(captionTracks);
}
- } else {
- updateCaptionTracks(captionTracks);
}
}
@@ -1132,25 +1279,24 @@ public class TunerSessionWorker implements PlaybackBufferListener,
int audioTrackCount = mPlayer.getTrackCount(MpegTsPlayer.TRACK_TYPE_AUDIO);
removeTvTracks(TvTrackInfo.TYPE_AUDIO);
for (int i = 0; i < audioTrackCount; i++) {
- AtscAudioTrack audioTrack = mAudioTrackMap.get(i);
- if (audioTrack == null) {
- continue;
- }
- String language = audioTrack.language;
- if (language == null && mChannel.getAudioTracks() != null
- && mChannel.getAudioTracks().size() == mAudioTrackMap.size()) {
- // If a language is not present, use a language field in PMT section parsed.
- language = mChannel.getAudioTracks().get(i).language;
- }
- // Save the index to the audio track.
- // Later, when an audio track is selected, both the audio pid and its audio stream
- // type reside in the selected index position of the tuner channel's audio data.
- audioTrack.index = i;
+ // We use language information from EIT/VCT only when the player does not provide
+ // languages.
+ com.google.android.exoplayer.MediaFormat infoFromPlayer =
+ mPlayer.getTrackFormat(MpegTsPlayer.TRACK_TYPE_AUDIO, i);
+ AtscAudioTrack infoFromEit = mAudioTrackMap.get(i);
+ AtscAudioTrack infoFromVct = (mChannel != null
+ && mChannel.getAudioTracks().size() == mAudioTrackMap.size()
+ && i < mChannel.getAudioTracks().size())
+ ? mChannel.getAudioTracks().get(i) : null;
+ String language = !TextUtils.isEmpty(infoFromPlayer.language) ? infoFromPlayer.language
+ : (infoFromEit != null && infoFromEit.language != null) ? infoFromEit.language
+ : (infoFromVct != null && infoFromVct.language != null)
+ ? infoFromVct.language : null;
TvTrackInfo.Builder builder = new TvTrackInfo.Builder(
TvTrackInfo.TYPE_AUDIO, AUDIO_TRACK_PREFIX + i);
builder.setLanguage(language);
- builder.setAudioChannelCount(audioTrack.channelCount);
- builder.setAudioSampleRate(audioTrack.sampleRate);
+ builder.setAudioChannelCount(infoFromPlayer.channelCount);
+ builder.setAudioSampleRate(infoFromPlayer.sampleRate);
TvTrackInfo track = builder.build();
mTvTracks.add(track);
}
@@ -1226,8 +1372,10 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
}
- private void stopPlayback() {
- mChannelDataManager.removeAllCallbacksAndMessages();
+ private void stopPlayback(boolean removeChannelDataCallbacks) {
+ if (removeChannelDataCallbacks) {
+ mChannelDataManager.removeAllCallbacksAndMessages();
+ }
if (mPlayer != null) {
mPlayer.setPlayWhenReady(false);
mPlayer.release();
@@ -1239,14 +1387,15 @@ public class TunerSessionWorker implements PlaybackBufferListener,
mPreparingStartTimeMs = INVALID_TIME;
mBufferingStartTimeMs = INVALID_TIME;
mReadyStartTimeMs = INVALID_TIME;
+ mLastLimitInBytes = 0L;
mSession.sendUiMessage(TunerSession.MSG_UI_HIDE_AUDIO_UNPLAYABLE);
mSession.notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_UNAVAILABLE);
}
}
- private void startPlayback(Object playerObj) {
+ private void startPlayback(int playerHashCode) {
// TODO: provide hasAudio()/hasVideo() for play recordings.
- if (mPlayer == null || mPlayer != playerObj) {
+ if (mPlayer == null || System.identityHashCode(mPlayer) != playerHashCode) {
return;
}
if (mChannel != null && !mChannel.hasAudio()) {
@@ -1257,9 +1406,12 @@ public class TunerSessionWorker implements PlaybackBufferListener,
return;
}
if (mChannel != null && ((mChannel.hasAudio() && !mPlayer.hasAudio())
- || (mChannel.hasVideo() && !mPlayer.hasVideo()))) {
- // Tracks haven't been detected in the extractor. Try again.
- sendMessage(MSG_RETRY_PLAYBACK, mPlayer);
+ || (mChannel.hasVideo() && !mPlayer.hasVideo()))
+ && mChannel.getType() != Channel.TYPE_NETWORK) {
+ // If the channel is from network, skip this part since the video and audio tracks
+ // information for channels from network are more reliable in the extractor. Otherwise,
+ // tracks haven't been detected in the extractor. Try again.
+ sendMessage(MSG_RETRY_PLAYBACK, System.identityHashCode(mPlayer));
return;
}
// Since mSurface is volatile, we define a local variable surface to keep the same value
@@ -1269,7 +1421,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
mPlayer.setSurface(surface);
mPlayer.setPlayWhenReady(true);
mPlayer.setVolume(mVolume);
- if (mChannel != null && !mChannel.hasVideo() && mChannel.hasAudio()) {
+ if (mChannel != null && mPlayer.hasAudio() && !mPlayer.hasVideo()) {
notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY);
} else if (!mReportedWeakSignal) {
// Doesn't show buffering during weak signal.
@@ -1286,22 +1438,21 @@ public class TunerSessionWorker implements PlaybackBufferListener,
return;
}
mSourceManager.setKeepTuneStatus(true);
- BufferManager bufferManager = mChannel != null ? mBufferManager : new BufferManager(
- new DvrStorageManager(new File(getRecordingPath()), false));
- MpegTsPlayer player = createPlayer(mAudioCapabilities, bufferManager);
+ MpegTsPlayer player = createPlayer(mAudioCapabilities);
player.setCaptionServiceNumber(Cea708Data.EMPTY_SERVICE_NUMBER);
player.setVideoEventListener(this);
player.setCaptionServiceNumber(mCaptionTrack != null ?
mCaptionTrack.serviceNumber : Cea708Data.EMPTY_SERVICE_NUMBER);
- if (!player.prepare(mContext, mChannel, this)) {
+ if (!player.prepare(mContext, mChannel, mHasSoftwareAudioDecoder, this)) {
mSourceManager.setKeepTuneStatus(false);
player.release();
if (!mHandler.hasMessages(MSG_TUNE)) {
// When prepare failed, there may be some errors related to hardware. In that
// case, retry playback immediately may not help.
notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL);
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RETRY_PLAYBACK, mPlayer),
- PLAYBACK_RETRY_DELAY_MS);
+ Log.i(TAG, "Notify weak signal due to player preparation failure");
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RETRY_PLAYBACK,
+ System.identityHashCode(mPlayer)), PLAYBACK_RETRY_DELAY_MS);
}
} else {
mPlayer = player;
@@ -1314,7 +1465,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
private void resetPlayback() {
long timestamp, oldTimestamp;
timestamp = SystemClock.elapsedRealtime();
- stopPlayback();
+ stopPlayback(false);
stopCaptionTrack();
if (ENABLE_PROFILER) {
oldTimestamp = timestamp;
@@ -1336,8 +1487,12 @@ public class TunerSessionWorker implements PlaybackBufferListener,
mRecordingDuration = recording != null ? getDurationForRecording(recording) : null;
mProgram = null;
mPrograms = null;
- mBufferStartTimeMs = mRecordStartTimeMs =
- (mRecordingId != null) ? 0 : System.currentTimeMillis();
+ if (mRecordingId != null) {
+ // Workaround of b/33298048: set it to 1 instead of 0.
+ mBufferStartTimeMs = mRecordStartTimeMs = 1;
+ } else {
+ mBufferStartTimeMs = mRecordStartTimeMs = System.currentTimeMillis();
+ }
mLastPositionMs = 0;
mCaptionTrack = null;
mHandler.sendEmptyMessage(MSG_PARENTAL_CONTROLS);
@@ -1385,14 +1540,19 @@ public class TunerSessionWorker implements PlaybackBufferListener,
} else {
mPlayer.seekTo(mBufferStartTimeMs - mRecordStartTimeMs);
mPlaybackParams.setSpeed(1.0f);
- mPlayer.setAudioTrack(true);
+ mPlayer.setAudioTrackAndClosedCaption(true);
return;
}
} else if (seekPositionMs > System.currentTimeMillis() - mRecordStartTimeMs) {
- mPlayer.seekTo(System.currentTimeMillis() - mRecordStartTimeMs);
- mPlaybackParams.setSpeed(1.0f);
- mPlayer.setAudioTrack(true);
- return;
+ // Stops trickplay when FF requested the position later than current position.
+ // If RW trickplay requested the position later than current position,
+ // continue trickplay.
+ if (mPlaybackParams.getSpeed() > 0.0f) {
+ mPlayer.seekTo(System.currentTimeMillis() - mRecordStartTimeMs);
+ mPlaybackParams.setSpeed(1.0f);
+ mPlayer.setAudioTrackAndClosedCaption(true);
+ return;
+ }
}
long delayForNextSeek = getTrickPlaySeekIntervalMs();
@@ -1414,7 +1574,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
mPlaybackParams.setSpeed(1.0f);
mPlayer.setPlayWhenReady(false);
- mPlayer.setAudioTrack(true);
+ mPlayer.setAudioTrackAndClosedCaption(true);
}
private void doTimeShiftResume() {
@@ -1422,7 +1582,7 @@ public class TunerSessionWorker implements PlaybackBufferListener,
mHandler.removeMessages(MSG_TRICKPLAY_BY_SEEK);
mPlaybackParams.setSpeed(1.0f);
mPlayer.setPlayWhenReady(true);
- mPlayer.setAudioTrack(true);
+ mPlayer.setAudioTrackAndClosedCaption(true);
}
private void doTimeShiftSeekTo(long timeMs) {
@@ -1443,14 +1603,14 @@ public class TunerSessionWorker implements PlaybackBufferListener,
doTimeShiftResume();
} else if (mPlayer.supportSmoothTrickPlay(speed)) {
mHandler.removeMessages(MSG_TRICKPLAY_BY_SEEK);
- mPlayer.setAudioTrack(false);
+ mPlayer.setAudioTrackAndClosedCaption(false);
mPlayer.startSmoothTrickplay(mPlaybackParams);
mHandler.sendEmptyMessageDelayed(MSG_SMOOTH_TRICKPLAY_MONITOR,
TRICKPLAY_MONITOR_INTERVAL_MS);
} else {
mHandler.removeMessages(MSG_SMOOTH_TRICKPLAY_MONITOR);
if (!mHandler.hasMessages(MSG_TRICKPLAY_BY_SEEK)) {
- mPlayer.setAudioTrack(false);
+ mPlayer.setAudioTrackAndClosedCaption(false);
mPlayer.setPlayWhenReady(false);
// Initiate trickplay
mHandler.sendMessage(mHandler.obtainMessage(MSG_TRICKPLAY_BY_SEEK,
@@ -1525,8 +1685,8 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
TvContentRating[] ratings = mTvContentRatingCache
.getRatings(currentProgram.getContentRating());
- if (ratings == null) {
- return null;
+ if (ratings == null || ratings.length == 0) {
+ ratings = new TvContentRating[] {TvContentRating.UNRATED};
}
for (TvContentRating rating : ratings) {
if (!Objects.equals(mUnblockedContentRating, rating) && mTvInputManager
@@ -1544,15 +1704,15 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
mChannelBlocked = channelBlocked;
if (mChannelBlocked) {
- mHandler.removeCallbacksAndMessages(null);
- stopPlayback();
+ clearCallbacksAndMessagesSafely();
+ stopPlayback(true);
resetTvTracks();
if (contentRating != null) {
mSession.notifyContentBlocked(contentRating);
}
mHandler.sendEmptyMessageDelayed(MSG_PARENTAL_CONTROLS, PARENTAL_CONTROLS_INTERVAL_MS);
} else {
- mHandler.removeCallbacksAndMessages(null);
+ clearCallbacksAndMessagesSafely();
resetPlayback();
mSession.notifyContentAllowed();
mHandler.sendEmptyMessageDelayed(MSG_RESCHEDULE_PROGRAMS,
@@ -1562,6 +1722,17 @@ public class TunerSessionWorker implements PlaybackBufferListener,
}
}
+ @WorkerThread
+ private void clearCallbacksAndMessagesSafely() {
+ // If MSG_RELEASE is removed, TunerSessionWorker will hang forever.
+ // Do not remove messages, after release is requested from MainThread.
+ synchronized (mReleaseLock) {
+ if (!mReleaseRequested) {
+ mHandler.removeCallbacksAndMessages(null);
+ }
+ }
+ }
+
private boolean hasEnoughBackwardBuffer() {
return mPlayer.getCurrentPosition() + BUFFER_UNDERFLOW_BUFFER_MS
>= mBufferStartTimeMs - mRecordStartTimeMs;
diff --git a/src/com/android/tv/tuner/tvinput/TunerStorageCleanUpService.java b/src/com/android/tv/tuner/tvinput/TunerStorageCleanUpService.java
index e734b779..6ad00daa 100644
--- a/src/com/android/tv/tuner/tvinput/TunerStorageCleanUpService.java
+++ b/src/com/android/tv/tuner/tvinput/TunerStorageCleanUpService.java
@@ -24,6 +24,7 @@ import android.database.Cursor;
import android.media.tv.TvContract;
import android.net.Uri;
import android.os.AsyncTask;
+import android.util.Log;
import com.android.tv.TvApplication;
import com.android.tv.dvr.DvrStorageStatusManager;
@@ -40,10 +41,17 @@ import java.util.concurrent.TimeUnit;
* from database.
*/
public class TunerStorageCleanUpService extends JobService {
+ private static final String TAG = "TunerStorageCleanUpService";
+
private CleanUpStorageTask mTask;
@Override
public void onCreate() {
+ if (!TvApplication.getSingletons(this).getTvInputManagerHelper().hasTvInputManager()) {
+ Log.wtf(TAG, "Stopping because device does not have a TvInputManager");
+ this.stopSelf();
+ return;
+ }
TvApplication.setCurrentRunningProcess(this, false);
super.onCreate();
mTask = new CleanUpStorageTask(this, this);
diff --git a/src/com/android/tv/tuner/tvinput/TunerTvInputService.java b/src/com/android/tv/tuner/tvinput/TunerTvInputService.java
index 684ebdbd..2725ddfc 100644
--- a/src/com/android/tv/tuner/tvinput/TunerTvInputService.java
+++ b/src/com/android/tv/tuner/tvinput/TunerTvInputService.java
@@ -28,9 +28,6 @@ import com.google.android.exoplayer.audio.AudioCapabilities;
import com.google.android.exoplayer.audio.AudioCapabilitiesReceiver;
import com.android.tv.TvApplication;
import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.tuner.exoplayer.buffer.BufferManager;
-import com.android.tv.tuner.exoplayer.buffer.TrickplayStorageManager;
-import com.android.tv.tuner.util.SystemPropertiesProxy;
import java.util.Collections;
import java.util.Set;
@@ -45,9 +42,6 @@ public class TunerTvInputService extends TvInputService
private static final String TAG = "TunerTvInputService";
private static final boolean DEBUG = false;
- private static final String MAX_BUFFER_SIZE_KEY = "tv.tuner.buffersize_mbytes";
- private static final int MAX_BUFFER_SIZE_DEF = 2 * 1024; // 2GB
- private static final int MIN_BUFFER_SIZE_DEF = 256; // 256MB
private static final int DVR_STORAGE_CLEANUP_JOB_ID = 100;
// WeakContainer for {@link TvInputSessionImpl}
@@ -55,17 +49,20 @@ public class TunerTvInputService extends TvInputService
private ChannelDataManager mChannelDataManager;
private AudioCapabilitiesReceiver mAudioCapabilitiesReceiver;
private AudioCapabilities mAudioCapabilities;
- private BufferManager mBufferManager;
@Override
public void onCreate() {
+ if (!TvApplication.getSingletons(this).getTvInputManagerHelper().hasTvInputManager()) {
+ Log.wtf(TAG, "Stopping because device does not have a TvInputManager");
+ this.stopSelf();
+ return;
+ }
TvApplication.setCurrentRunningProcess(this, false);
super.onCreate();
if (DEBUG) Log.d(TAG, "onCreate");
mChannelDataManager = new ChannelDataManager(getApplicationContext());
mAudioCapabilitiesReceiver = new AudioCapabilitiesReceiver(getApplicationContext(), this);
mAudioCapabilitiesReceiver.register();
- mBufferManager = createBufferManager();
if (CommonFeatures.DVR.isEnabled(this)) {
JobScheduler jobScheduler =
(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
@@ -79,11 +76,6 @@ public class TunerTvInputService extends TvInputService
jobScheduler.schedule(job);
}
}
- if (mBufferManager == null) {
- Log.i(TAG, "Trickplay is disabled");
- } else {
- Log.i(TAG, "Trickplay is enabled");
- }
}
@Override
@@ -92,9 +84,6 @@ public class TunerTvInputService extends TvInputService
super.onDestroy();
mChannelDataManager.release();
mAudioCapabilitiesReceiver.unregister();
- if (mBufferManager != null) {
- mBufferManager.close();
- }
}
@Override
@@ -106,8 +95,7 @@ public class TunerTvInputService extends TvInputService
public Session onCreateSession(String inputId) {
if (DEBUG) Log.d(TAG, "onCreateSession");
try {
- final TunerSession session = new TunerSession(
- this, mChannelDataManager, mBufferManager);
+ final TunerSession session = new TunerSession(this, mChannelDataManager);
mTunerSessions.add(session);
session.setAudioCapabilities(mAudioCapabilities);
session.setOverlayViewEnabled(true);
@@ -129,17 +117,6 @@ public class TunerTvInputService extends TvInputService
}
}
- private BufferManager createBufferManager() {
- int maxBufferSizeMb =
- SystemPropertiesProxy.getInt(MAX_BUFFER_SIZE_KEY, MAX_BUFFER_SIZE_DEF);
- if (maxBufferSizeMb >= MIN_BUFFER_SIZE_DEF) {
- return new BufferManager(
- new TrickplayStorageManager(getApplicationContext(), getCacheDir(),
- 1024L * 1024 * maxBufferSizeMb));
- }
- return null;
- }
-
public static String getInputId(Context context) {
return TvContract.buildInputId(new ComponentName(context, TunerTvInputService.class));
}
diff --git a/src/com/android/tv/tuner/util/PostalCodeUtils.java b/src/com/android/tv/tuner/util/PostalCodeUtils.java
new file mode 100644
index 00000000..9eb689a7
--- /dev/null
+++ b/src/com/android/tv/tuner/util/PostalCodeUtils.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2017 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.tv.tuner.util;
+
+import android.content.Context;
+import android.location.Address;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Log;
+import com.android.tv.tuner.TunerPreferences;
+import com.android.tv.util.LocationUtils;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * A utility class to update, get, and set the last known postal or zip code.
+ */
+public class PostalCodeUtils {
+ private static final String TAG = "PostalCodeUtils";
+
+ // Postcode formats, where A signifies a letter and 9 a digit:
+ // US zip code format: 99999
+ private static final String POSTCODE_REGEX_US = "^(\\d{5})";
+ // UK postcode district formats: A9, A99, AA9, AA99
+ // Full UK postcode format: Postcode District + space + 9AA
+ // Should be able to handle both postcode district and full postcode
+ private static final String POSTCODE_REGEX_GB =
+ "^([A-Z][A-Z]?[0-9][0-9A-Z]?)( ?[0-9][A-Z]{2})?$";
+ private static final String POSTCODE_REGEX_GB_GIR = "^GIR( ?0AA)?$"; // special UK postcode
+
+ private static final Map<String, Pattern> REGION_PATTERN = new HashMap<>();
+ private static final Map<String, Integer> REGION_MAX_LENGTH = new HashMap<>();
+
+ static {
+ REGION_PATTERN.put(Locale.US.getCountry(), Pattern.compile(POSTCODE_REGEX_US));
+ REGION_PATTERN.put(
+ Locale.UK.getCountry(),
+ Pattern.compile(POSTCODE_REGEX_GB + "|" + POSTCODE_REGEX_GB_GIR));
+ REGION_MAX_LENGTH.put(Locale.US.getCountry(), 5);
+ REGION_MAX_LENGTH.put(Locale.UK.getCountry(), 8);
+ }
+
+ // The longest postcode number is 10-character-long.
+ // Use a larger number to accommodate future changes.
+ private static final int DEFAULT_MAX_LENGTH = 16;
+
+ /** Returns {@code true} if postal code has been changed */
+ public static boolean updatePostalCode(Context context)
+ throws IOException, SecurityException, NoPostalCodeException {
+ String postalCode = getPostalCode(context);
+ String lastPostalCode = getLastPostalCode(context);
+ if (TextUtils.isEmpty(postalCode)) {
+ if (TextUtils.isEmpty(lastPostalCode)) {
+ throw new NoPostalCodeException();
+ }
+ } else if (!TextUtils.equals(postalCode, lastPostalCode)) {
+ setLastPostalCode(context, postalCode);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Gets the last stored postal or zip code, which might be decided by {@link LocationUtils} or
+ * input by users.
+ */
+ public static String getLastPostalCode(Context context) {
+ return TunerPreferences.getLastPostalCode(context);
+ }
+
+ /**
+ * Sets the last stored postal or zip code. This method will overwrite the value written by
+ * calling {@link #updatePostalCode(Context)}.
+ */
+ public static void setLastPostalCode(Context context, String postalCode) {
+ Log.i(TAG, "Set Postal Code:" + postalCode);
+ TunerPreferences.setLastPostalCode(context, postalCode);
+ }
+
+ @Nullable
+ private static String getPostalCode(Context context) throws IOException, SecurityException {
+ Address address = LocationUtils.getCurrentAddress(context);
+ if (address != null) {
+ Log.i(TAG, "Current country and postal code is " + address.getCountryName() + ", "
+ + address.getPostalCode());
+ return address.getPostalCode();
+ }
+ return null;
+ }
+
+ /** An {@link java.lang.Exception} class to notify no valid postal or zip code is available. */
+ public static class NoPostalCodeException extends Exception {
+ public NoPostalCodeException() {
+ }
+ }
+
+ /**
+ * Checks whether a postcode matches the format of the specific region.
+ *
+ * @return {@code false} if the region is supported and the postcode doesn't match; {@code true}
+ * otherwise
+ */
+ public static boolean matches(@NonNull CharSequence postcode, @NonNull String region) {
+ Pattern pattern = REGION_PATTERN.get(region.toUpperCase());
+ return pattern == null || pattern.matcher(postcode).matches();
+ }
+
+ /**
+ * Gets the largest possible postcode length in the region.
+ *
+ * @return maximum postcode length if the region is supported; {@link #DEFAULT_MAX_LENGTH}
+ * otherwise
+ */
+ public static int getRegionMaxLength(Context context) {
+ Integer maxLength =
+ REGION_MAX_LENGTH.get(LocationUtils.getCurrentCountry(context).toUpperCase());
+ return maxLength == null ? DEFAULT_MAX_LENGTH : maxLength;
+ }
+} \ No newline at end of file
diff --git a/src/com/android/tv/tuner/util/StringUtils.java b/src/com/android/tv/tuner/util/StringUtils.java
deleted file mode 100644
index 15571e75..00000000
--- a/src/com/android/tv/tuner/util/StringUtils.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.tuner.util;
-
-/**
- * Utility class for handling {@link String}.
- */
-public final class StringUtils {
-
- private StringUtils() { }
-
- /**
- * Returns compares two strings lexicographically and handles null values quietly.
- */
- public static int compare(String a, String b) {
- if (a == null) {
- return b == null ? 0 : -1;
- }
- if (b == null) {
- return 1;
- }
- return a.compareTo(b);
- }
-}
diff --git a/src/com/android/tv/tuner/util/SystemPropertiesProxy.java b/src/com/android/tv/tuner/util/SystemPropertiesProxy.java
index 62a64361..2817ccbf 100644
--- a/src/com/android/tv/tuner/util/SystemPropertiesProxy.java
+++ b/src/com/android/tv/tuner/util/SystemPropertiesProxy.java
@@ -58,4 +58,20 @@ public class SystemPropertiesProxy {
}
return def;
}
+
+ public static String getString(String key, String def) throws IllegalArgumentException {
+ try {
+ Class SystemPropertiesClass = Class.forName("android.os.SystemProperties");
+ Method getIntMethod =
+ SystemPropertiesClass.getDeclaredMethod("get", String.class, String.class);
+ getIntMethod.setAccessible(true);
+ return (String) getIntMethod.invoke(SystemPropertiesClass, key, def);
+ } catch (InvocationTargetException
+ | IllegalAccessException
+ | NoSuchMethodException
+ | ClassNotFoundException e) {
+ Log.e(TAG, "Failed to invoke SystemProperties.get()", e);
+ }
+ return def;
+ }
}
diff --git a/src/com/android/tv/tuner/util/TunerInputInfoUtils.java b/src/com/android/tv/tuner/util/TunerInputInfoUtils.java
index 5c411f64..f421bf1a 100644
--- a/src/com/android/tv/tuner/util/TunerInputInfoUtils.java
+++ b/src/com/android/tv/tuner/util/TunerInputInfoUtils.java
@@ -21,10 +21,11 @@ import android.content.ComponentName;
import android.content.Context;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
+import android.os.AsyncTask;
import android.os.Build;
import android.support.annotation.Nullable;
-import android.support.v4.os.BuildCompat;
import android.util.Log;
+import android.util.Pair;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.tuner.R;
@@ -43,23 +44,31 @@ public class TunerInputInfoUtils {
*/
@Nullable
@TargetApi(Build.VERSION_CODES.N)
- public static TvInputInfo buildTunerInputInfo(Context context, boolean fromBuiltInTuner) {
- int numOfDevices = TunerHal.getTunerCount(context);
- if (numOfDevices == 0) {
+ public static TvInputInfo buildTunerInputInfo(Context context) {
+ Pair<Integer, Integer> tunerTypeAndCount = TunerHal.getTunerTypeAndCount(context);
+ if (tunerTypeAndCount.first == null || tunerTypeAndCount.second == 0) {
return null;
}
- TvInputInfo.Builder builder = new TvInputInfo.Builder(context, new ComponentName(context,
- TunerTvInputService.class));
- if (fromBuiltInTuner) {
- builder.setLabel(R.string.bt_app_name);
- } else {
- builder.setLabel(R.string.ut_app_name);
+ int inputLabelId = 0;
+ switch (tunerTypeAndCount.first) {
+ case TunerHal.TUNER_TYPE_BUILT_IN:
+ inputLabelId = R.string.bt_app_name;
+ break;
+ case TunerHal.TUNER_TYPE_USB:
+ inputLabelId = R.string.ut_app_name;
+ break;
+ case TunerHal.TUNER_TYPE_NETWORK:
+ inputLabelId = R.string.nt_app_name;
+ break;
}
try {
- return builder.setCanRecord(CommonFeatures.DVR.isEnabled(context))
- .setTunerCount(numOfDevices)
+ TvInputInfo.Builder builder = new TvInputInfo.Builder(context,
+ new ComponentName(context, TunerTvInputService.class));
+ return builder.setLabel(inputLabelId)
+ .setCanRecord(CommonFeatures.DVR.isEnabled(context))
+ .setTunerCount(tunerTypeAndCount.second)
.build();
- } catch (NullPointerException e) {
+ } catch (IllegalArgumentException | NullPointerException e) {
// TunerTvInputService is not enabled.
return null;
}
@@ -71,30 +80,36 @@ public class TunerInputInfoUtils {
* @param context {@link Context} instance
*/
public static void updateTunerInputInfo(Context context) {
- if (BuildCompat.isAtLeastN()) {
- if (DEBUG) Log.d(TAG, "updateTunerInputInfo()");
- TvInputInfo info = buildTunerInputInfo(context, isBuiltInTuner(context));
- if (info != null) {
- ((TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE))
- .updateTvInputInfo(info);
- if (DEBUG) {
- Log.d(TAG, "TvInputInfo [" + info.loadLabel(context)
- + "] updated: " + info.toString());
+ final Context appContext = context.getApplicationContext();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ new AsyncTask<Void, Void, TvInputInfo>() {
+ @Override
+ protected TvInputInfo doInBackground(Void... params) {
+ if (DEBUG) Log.d(TAG, "updateTunerInputInfo()");
+ return buildTunerInputInfo(appContext);
}
- } else {
- if (DEBUG) {
- Log.d(TAG, "Updating tuner input's info failed. Input is not ready yet.");
+
+ @Override
+ @TargetApi(Build.VERSION_CODES.N)
+ protected void onPostExecute(TvInputInfo info) {
+ if (info != null) {
+ ((TvInputManager) appContext.getSystemService(Context.TV_INPUT_SERVICE))
+ .updateTvInputInfo(info);
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "TvInputInfo ["
+ + info.loadLabel(appContext)
+ + "] updated: "
+ + info.toString());
+ }
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "Updating tuner input info failed. Input is not ready yet.");
+ }
+ }
}
- }
+ }.execute();
}
}
-
- /**
- * Returns if the current tuner service is for a built-in tuner.
- *
- * @param context {@link Context} instance
- */
- public static boolean isBuiltInTuner(Context context) {
- return TunerHal.getTunerType(context) == TunerHal.TUNER_TYPE_BUILT_IN;
- }
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/ui/AppLayerTvView.java b/src/com/android/tv/ui/AppLayerTvView.java
index 09acb36b..625014ea 100644
--- a/src/com/android/tv/ui/AppLayerTvView.java
+++ b/src/com/android/tv/ui/AppLayerTvView.java
@@ -22,7 +22,8 @@ import android.util.AttributeSet;
import android.view.SurfaceView;
import android.view.View;
-import com.android.tv.experiments.Experiments;
+import com.android.tv.util.Debug;
+import com.android.tv.util.Utils;
/**
* A TvView class for application layer when multiple windows are being used in the app.
@@ -55,8 +56,17 @@ public class AppLayerTvView extends TvView {
public void onViewAdded(View child) {
if (child instanceof SurfaceView) {
// Note: See b/29118070 for detail.
- ((SurfaceView) child).setSecure(!Experiments.ENABLE_DEVELOPER_FEATURES.get());
+ ((SurfaceView) child).setSecure(!Utils.isDeveloper());
}
super.onViewAdded(child);
}
+
+ @Override
+ public void getLocationOnScreen(int[] outLocation) {
+ super.getLocationOnScreen(outLocation);
+
+ // The TvView.MySessionCallback.onSessionCreated() will call this method indirectly.
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
+ "AppLayerTvView.getLocationOnScreen, session created");
+ }
}
diff --git a/src/com/android/tv/ui/BlockScreenView.java b/src/com/android/tv/ui/BlockScreenView.java
index 52b9389d..09c167ca 100644
--- a/src/com/android/tv/ui/BlockScreenView.java
+++ b/src/com/android/tv/ui/BlockScreenView.java
@@ -21,32 +21,37 @@ import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
-import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.tv.R;
import com.android.tv.ui.TunableTvView.BlockScreenType;
-public class BlockScreenView extends LinearLayout {
+public class BlockScreenView extends FrameLayout {
private View mContainerView;
private View mImageContainer;
- private ImageView mNormalImageView;
- private ImageView mShrunkenImageView;
+ private ImageView mNormalLockIconView;
+ private ImageView mShrunkenLockIconView;
private View mSpace;
- private TextView mTextView;
+ private TextView mBlockingInfoTextView;
+ private ImageView mBackgroundImageView;
private final int mSpacingNormal;
private final int mSpacingShrunken;
- // Animators used for fade in/out of block screen icon.
- private Animator mFadeIn;
+ // Animator used to fade out the whole block screen.
private Animator mFadeOut;
+ // Animators used to fade in/out the block screen icon and info text.
+ private Animator mInfoFadeIn;
+ private Animator mInfoFadeOut;
+
public BlockScreenView(Context context) {
this(context, null, 0);
}
@@ -68,21 +73,32 @@ public class BlockScreenView extends LinearLayout {
super.onFinishInflate();
mContainerView = findViewById(R.id.block_screen_container);
mImageContainer = findViewById(R.id.image_container);
- mNormalImageView = (ImageView) findViewById(R.id.block_screen_icon);
- mShrunkenImageView = (ImageView) findViewById(R.id.block_screen_shrunken_icon);
+ mNormalLockIconView = (ImageView) findViewById(R.id.block_screen_icon);
+ mShrunkenLockIconView = (ImageView) findViewById(R.id.block_screen_shrunken_icon);
mSpace = findViewById(R.id.space);
- mTextView = (TextView) findViewById(R.id.block_screen_text);
- mFadeIn = AnimatorInflater.loadAnimator(getContext(),
- R.animator.tvview_block_screen_fade_in);
- mFadeIn.setTarget(mContainerView);
+ mBlockingInfoTextView = (TextView) findViewById(R.id.block_screen_text);
+ mBackgroundImageView = (ImageView) findViewById(R.id.background_image);
mFadeOut = AnimatorInflater.loadAnimator(getContext(),
R.animator.tvview_block_screen_fade_out);
- mFadeOut.setTarget(mContainerView);
+ mFadeOut.setTarget(this);
mFadeOut.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
+ setVisibility(GONE);
+ setBackgroundImage(null);
+ setAlpha(1.0f);
+ }
+ });
+ mInfoFadeIn = AnimatorInflater.loadAnimator(getContext(),
+ R.animator.tvview_block_screen_fade_in);
+ mInfoFadeIn.setTarget(mContainerView);
+ mInfoFadeOut = AnimatorInflater.loadAnimator(getContext(),
+ R.animator.tvview_block_screen_fade_out);
+ mInfoFadeOut.setTarget(mContainerView);
+ mInfoFadeOut.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
mContainerView.setVisibility(GONE);
- mContainerView.setAlpha(1f);
}
});
}
@@ -90,53 +106,54 @@ public class BlockScreenView extends LinearLayout {
/**
* Sets the normal image.
*/
- public void setImage(int resId) {
- mNormalImageView.setImageResource(resId);
+ public void setIconImage(int resId) {
+ mNormalLockIconView.setImageResource(resId);
updateSpaceVisibility();
}
/**
* Sets the scale type of the normal image.
*/
- public void setScaleType(ScaleType scaleType) {
- mNormalImageView.setScaleType(scaleType);
+ public void setIconScaleType(ScaleType scaleType) {
+ mNormalLockIconView.setScaleType(scaleType);
updateSpaceVisibility();
}
/**
- * Sets the shrunken image.
+ * Show or hide the image of this view.
*/
- public void setShrunkenImage(int resId) {
- mShrunkenImageView.setImageResource(resId);
+ public void setIconVisibility(boolean visible) {
+ mImageContainer.setVisibility(visible ? VISIBLE : GONE);
updateSpaceVisibility();
}
/**
- * Show or hide the image of this view.
+ * Sets the text message.
*/
- public void setImageVisibility(boolean visible) {
- mImageContainer.setVisibility(visible ? VISIBLE : GONE);
+ public void setInfoText(int resId) {
+ mBlockingInfoTextView.setText(resId);
updateSpaceVisibility();
}
/**
* Sets the text message.
*/
- public void setText(int resId) {
- mTextView.setText(resId);
+ public void setInfoText(String text) {
+ mBlockingInfoTextView.setText(text);
updateSpaceVisibility();
}
/**
- * Sets the text message.
+ * Sets the background image should be displayed in the block screen view. Passes {@code null}
+ * to remove the currently displayed background image.
*/
- public void setText(String text) {
- mTextView.setText(text);
- updateSpaceVisibility();
+ public void setBackgroundImage(Drawable backgroundImage) {
+ mBackgroundImageView.setVisibility(backgroundImage == null ? GONE : VISIBLE);
+ mBackgroundImageView.setImageDrawable(backgroundImage);
}
private void updateSpaceVisibility() {
- if (isImageViewVisible() && isTextViewVisible(mTextView)) {
+ if (isImageViewVisible() && isTextViewVisible(mBlockingInfoTextView)) {
mSpace.setVisibility(VISIBLE);
} else {
mSpace.setVisibility(GONE);
@@ -145,7 +162,8 @@ public class BlockScreenView extends LinearLayout {
private boolean isImageViewVisible() {
return mImageContainer.getVisibility() == VISIBLE
- && (isImageViewVisible(mNormalImageView) || isImageViewVisible(mShrunkenImageView));
+ && (isImageViewVisible(mNormalLockIconView)
+ || isImageViewVisible(mShrunkenLockIconView));
}
private static boolean isImageViewVisible(ImageView imageView) {
@@ -177,37 +195,39 @@ public class BlockScreenView extends LinearLayout {
mContainerView.setVisibility(GONE);
break;
case TunableTvView.BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW:
- mNormalImageView.setVisibility(GONE);
- mShrunkenImageView.setVisibility(VISIBLE);
+ mNormalLockIconView.setVisibility(GONE);
+ mShrunkenLockIconView.setVisibility(VISIBLE);
mContainerView.setVisibility(VISIBLE);
+ mContainerView.setAlpha(1.0f);
break;
case TunableTvView.BLOCK_SCREEN_TYPE_NORMAL:
- mNormalImageView.setVisibility(VISIBLE);
- mShrunkenImageView.setVisibility(GONE);
+ mNormalLockIconView.setVisibility(VISIBLE);
+ mShrunkenLockIconView.setVisibility(GONE);
mContainerView.setVisibility(VISIBLE);
+ mContainerView.setAlpha(1.0f);
break;
}
} else {
switch (blockScreenType) {
case TunableTvView.BLOCK_SCREEN_TYPE_NO_UI:
if (mContainerView.getVisibility() == VISIBLE) {
- mFadeOut.start();
+ mInfoFadeOut.start();
}
break;
case TunableTvView.BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW:
- mNormalImageView.setVisibility(GONE);
- mShrunkenImageView.setVisibility(VISIBLE);
- mContainerView.setVisibility(VISIBLE);
+ mNormalLockIconView.setVisibility(GONE);
+ mShrunkenLockIconView.setVisibility(VISIBLE);
if (mContainerView.getVisibility() == GONE) {
- mFadeIn.start();
+ mContainerView.setVisibility(VISIBLE);
+ mInfoFadeIn.start();
}
break;
case TunableTvView.BLOCK_SCREEN_TYPE_NORMAL:
- mNormalImageView.setVisibility(VISIBLE);
- mShrunkenImageView.setVisibility(GONE);
- mContainerView.setVisibility(VISIBLE);
+ mNormalLockIconView.setVisibility(VISIBLE);
+ mShrunkenLockIconView.setVisibility(GONE);
if (mContainerView.getVisibility() == GONE) {
- mFadeIn.start();
+ mContainerView.setVisibility(VISIBLE);
+ mInfoFadeIn.start();
}
break;
}
@@ -216,26 +236,33 @@ public class BlockScreenView extends LinearLayout {
}
/**
- * Scales the contents view by the given {@code scale}.
+ * Adds a listener to the fade-in animation of info text and icons of the block screen.
*/
- public void scaleContainerView(float scale) {
- mContainerView.setScaleX(scale);
- mContainerView.setScaleY(scale);
+ public void addInfoFadeInAnimationListener(AnimatorListener listener) {
+ mInfoFadeIn.addListener(listener);
}
- public void addFadeOutAnimationListener(AnimatorListener listener) {
- mFadeOut.addListener(listener);
+ /**
+ * Fades out the block screen.
+ */
+ public void fadeOut() {
+ if (getVisibility() == VISIBLE && !mFadeOut.isStarted()) {
+ mFadeOut.start();
+ }
}
/**
* Ends the currently running animations.
*/
public void endAnimations() {
- if (mFadeIn != null && mFadeIn.isRunning()) {
- mFadeIn.end();
- }
if (mFadeOut != null && mFadeOut.isRunning()) {
mFadeOut.end();
}
+ if (mInfoFadeIn != null && mInfoFadeIn.isRunning()) {
+ mInfoFadeIn.end();
+ }
+ if (mInfoFadeOut != null && mInfoFadeOut.isRunning()) {
+ mInfoFadeOut.end();
+ }
}
}
diff --git a/src/com/android/tv/ui/ChannelBannerView.java b/src/com/android/tv/ui/ChannelBannerView.java
index 3cf4de83..a5d897f2 100644
--- a/src/com/android/tv/ui/ChannelBannerView.java
+++ b/src/com/android/tv/ui/ChannelBannerView.java
@@ -23,12 +23,9 @@ import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
-import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.media.tv.TvContentRating;
-import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
-import android.net.Uri;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.text.Spannable;
@@ -52,12 +49,13 @@ import android.widget.TextView;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvApplication;
+import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
import com.android.tv.data.StreamInfo;
import com.android.tv.dvr.DvrManager;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.util.ImageCache;
import com.android.tv.util.ImageLoader;
@@ -65,10 +63,6 @@ import com.android.tv.util.ImageLoader.ImageLoaderCallback;
import com.android.tv.util.ImageLoader.LoadTvInputLogoTask;
import com.android.tv.util.Utils;
-import junit.framework.Assert;
-
-import java.util.Objects;
-
/**
* A view to render channel banner.
*/
@@ -98,8 +92,8 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
private static final String EMPTY_STRING = "";
- private static Program sNoProgram;
- private static Program sLockedChannelProgram;
+ private Program mNoProgram;
+ private Program mLockedChannelProgram;
private static String sClosedCaptionMark;
private final MainActivity mMainActivity;
@@ -123,6 +117,7 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
private String mProgramDescriptionText;
private View mAnchorView;
private Channel mCurrentChannel;
+ private boolean mCurrentChannelLogoExists;
private Program mLastUpdatedProgram;
private final Handler mHandler = new Handler();
private final DvrManager mDvrManager;
@@ -130,6 +125,7 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
private TvContentRating mBlockingContentRating;
private int mLockType;
+ private boolean mUpdateOnTune;
private Animator mResizeAnimator;
private int mCurrentHeight;
@@ -178,24 +174,6 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
}
};
- private final ContentObserver mProgramUpdateObserver = new ContentObserver(mHandler) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- // TODO: This {@code uri} argument may be a program which is not related to this
- // channel. Consider adding channel id as a parameter of program URI to avoid
- // unnecessary update.
- mHandler.post(mProgramUpdateRunnable);
- }
- };
-
- private final Runnable mProgramUpdateRunnable = new Runnable() {
- @Override
- public void run() {
- removeCallbacks(this);
- updateViews(null);
- }
- };
-
public ChannelBannerView(Context context) {
this(context, null);
}
@@ -243,39 +221,20 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
mContentRatingsManager = TvApplication.getSingletons(getContext())
.getTvInputManagerHelper().getContentRatingsManager();
- if (sNoProgram == null) {
- sNoProgram = new Program.Builder()
- .setTitle(context.getString(R.string.channel_banner_no_title))
- .setDescription(EMPTY_STRING)
- .build();
- }
- if (sLockedChannelProgram == null){
- sLockedChannelProgram = new Program.Builder()
- .setTitle(context.getString(R.string.channel_banner_locked_channel_title))
- .setDescription(EMPTY_STRING)
- .build();
- }
+ mNoProgram = new Program.Builder()
+ .setTitle(context.getString(R.string.channel_banner_no_title))
+ .setDescription(EMPTY_STRING)
+ .build();
+ mLockedChannelProgram = new Program.Builder()
+ .setTitle(context.getString(R.string.channel_banner_locked_channel_title))
+ .setDescription(EMPTY_STRING)
+ .build();
if (sClosedCaptionMark == null) {
sClosedCaptionMark = context.getString(R.string.closed_caption);
}
}
@Override
- protected void onAttachedToWindow() {
- if (DEBUG) Log.d(TAG, "onAttachedToWindow");
- super.onAttachedToWindow();
- getContext().getContentResolver().registerContentObserver(TvContract.Programs.CONTENT_URI,
- true, mProgramUpdateObserver);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- if (DEBUG) Log.d(TAG, "onDetachedToWindow");
- getContext().getContentResolver().unregisterContentObserver(mProgramUpdateObserver);
- super.onDetachedFromWindow();
- }
-
- @Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -345,19 +304,17 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
* Set new lock type.
*
* @param lockType Any of LOCK_NONE, LOCK_PROGRAM_DETAIL, or LOCK_CHANNEL_INFO.
- * @return {@code true} only if lock type is changed
+ * @return the previous lock type of the channel banner.
* @throws IllegalArgumentException if lockType is invalid.
*/
- public boolean setLockType(int lockType) {
+ public int setLockType(int lockType) {
if (lockType != LOCK_NONE && lockType != LOCK_CHANNEL_INFO
&& lockType != LOCK_PROGRAM_DETAIL) {
throw new IllegalArgumentException("No such lock type " + lockType);
}
- if (mLockType != lockType) {
- mLockType = lockType;
- return true;
- }
- return false;
+ int previousLockType = mLockType;
+ mLockType = lockType;
+ return previousLockType;
}
/**
@@ -372,31 +329,34 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
/**
* Update channel banner view.
*
- * @param info A StreamInfo that includes stream information.
- * If it's {@code null}, only program information will be updated.
+ * @param updateOnTune {@false} denotes the channel banner is updated due to other reasons than
+ * tuning. The channel info will not be updated in this case.
*/
- public void updateViews(StreamInfo info) {
+ public void updateViews(boolean updateOnTune) {
resetAnimationEffects();
- Channel channel = mMainActivity.getCurrentChannel();
- if (!Objects.equals(mCurrentChannel, channel)) {
- mBlockingContentRating = null;
+ mChannelView.setVisibility(VISIBLE);
+ mUpdateOnTune = updateOnTune;
+ if (mUpdateOnTune) {
if (isShown()) {
scheduleHide();
}
- }
- mCurrentChannel = channel;
- mChannelView.setVisibility(VISIBLE);
- if (info != null) {
- // If the current channels between ChannelTuner and TvView are different,
- // the stream information should not be seen.
- updateStreamInfo(channel != null && channel.equals(info.getCurrentChannel()) ? info
- : null);
+ mBlockingContentRating = null;
+ mCurrentChannel = mMainActivity.getCurrentChannel();
+ mCurrentChannelLogoExists =
+ mCurrentChannel != null && mCurrentChannel.channelLogoExists();
+ updateStreamInfo(null);
updateChannelInfo();
}
updateProgramInfo(mMainActivity.getCurrentProgram());
+ mUpdateOnTune = false;
}
- private void updateStreamInfo(StreamInfo info) {
+ /**
+ * Update channel banner view with stream info.
+ *
+ * @param info A StreamInfo that includes stream information.
+ */
+ public void updateStreamInfo(StreamInfo info) {
// Update stream information in a channel.
if (mLockType != LOCK_CHANNEL_INFO && info != null) {
updateText(mClosedCaptionTextView, info.hasClosedCaption() ? sClosedCaptionMark
@@ -414,9 +374,6 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
mAspectRatioTextView.setVisibility(View.GONE);
mResolutionTextView.setVisibility(View.GONE);
mAudioChannelTextView.setVisibility(View.GONE);
- for (int i = 0; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
- mContentRatingsTextViews[i].setVisibility(View.GONE);
- }
}
}
@@ -467,7 +424,7 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
}
mChannelLogoImageView.setImageBitmap(null);
mChannelLogoImageView.setVisibility(View.GONE);
- if (mCurrentChannel != null) {
+ if (mCurrentChannel != null && mCurrentChannelLogoExists) {
mCurrentChannel.loadBitmap(getContext(), Channel.LOAD_IMAGE_TYPE_CHANNEL_LOGO,
mChannelLogoImageViewWidth, mChannelLogoImageViewHeight,
createChannelLogoCallback(this, mCurrentChannel));
@@ -550,8 +507,9 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
if (mResizeAnimator == null) {
String description = mProgramDescriptionTextView.getText().toString();
- boolean needFadeAnimation = !description.equals(mProgramDescriptionText);
- updateBannerHeight(needFadeAnimation);
+ boolean programDescriptionNeedFadeAnimation =
+ !description.equals(mProgramDescriptionText) && !mUpdateOnTune;
+ updateBannerHeight(programDescriptionNeedFadeAnimation);
} else {
mProgramInfoUpdatePendingByResizing = true;
}
@@ -559,9 +517,9 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
private void updateProgramInfo(Program program) {
if (mLockType == LOCK_CHANNEL_INFO) {
- program = sLockedChannelProgram;
+ program = mLockedChannelProgram;
} else if (program == null || !program.isValid() || TextUtils.isEmpty(program.getTitle())) {
- program = sNoProgram;
+ program = mNoProgram;
}
if (mLastUpdatedProgram == null
@@ -590,9 +548,9 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
mProgramDescriptionText = program.getDescription();
}
String description = mProgramDescriptionTextView.getText().toString();
- boolean needFadeAnimation = isProgramChanged
- || !description.equals(mProgramDescriptionText);
- updateBannerHeight(needFadeAnimation);
+ boolean programDescriptionNeedFadeAnimation = (isProgramChanged
+ || !description.equals(mProgramDescriptionText)) && !mUpdateOnTune;
+ updateBannerHeight(programDescriptionNeedFadeAnimation);
} else {
mProgramInfoUpdatePendingByResizing = true;
}
@@ -603,7 +561,7 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
if (program == null) {
return;
}
- updateProgramTextView(program == sLockedChannelProgram, program.getTitle(),
+ updateProgramTextView(program == mLockedChannelProgram, program.getTitle(),
program.getEpisodeDisplayTitle(getContext()));
}
@@ -630,9 +588,8 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mProgramTextView.setText(text);
}
- int width = mProgramDescriptionTextViewWidth
- - ((mChannelLogoImageView.getVisibility() != View.VISIBLE)
- ? 0 : mChannelLogoImageViewWidth + mChannelLogoImageViewMarginStart);
+ int width = mProgramDescriptionTextViewWidth + (mCurrentChannelLogoExists ?
+ 0 : mChannelLogoImageViewWidth + mChannelLogoImageViewMarginStart);
ViewGroup.LayoutParams lp = mProgramTextView.getLayoutParams();
lp.width = width;
mProgramTextView.setLayoutParams(lp);
@@ -655,23 +612,32 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
}
private void updateProgramRatings(Program program) {
- if (mBlockingContentRating != null) {
- mContentRatingsTextViews[0].setText(
- mContentRatingsManager.getDisplayNameForRating(mBlockingContentRating));
- mContentRatingsTextViews[0].setVisibility(View.VISIBLE);
- for (int i = 1; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
+ if (mLockType == LOCK_CHANNEL_INFO) {
+ for (int i = 0; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
mContentRatingsTextViews[i].setVisibility(View.GONE);
}
- return;
- }
- TvContentRating[] ratings = (program == null) ? null : program.getContentRatings();
- for (int i = 0; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
- if (ratings == null || ratings.length <= i) {
- mContentRatingsTextViews[i].setVisibility(View.GONE);
+ } else if (mBlockingContentRating != null) {
+ String displayNameForRating =
+ mContentRatingsManager.getDisplayNameForRating(mBlockingContentRating);
+ if (!TextUtils.isEmpty(displayNameForRating)) {
+ mContentRatingsTextViews[0].setText(displayNameForRating);
+ mContentRatingsTextViews[0].setVisibility(View.VISIBLE);
} else {
- mContentRatingsTextViews[i].setText(
- mContentRatingsManager.getDisplayNameForRating(ratings[i]));
- mContentRatingsTextViews[i].setVisibility(View.VISIBLE);
+ mContentRatingsTextViews[0].setVisibility(View.GONE);
+ }
+ for (int i = 1; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
+ mContentRatingsTextViews[i].setVisibility(View.GONE);
+ }
+ } else {
+ TvContentRating[] ratings = (program == null) ? null : program.getContentRatings();
+ for (int i = 0; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
+ if (ratings == null || ratings.length <= i) {
+ mContentRatingsTextViews[i].setVisibility(View.GONE);
+ } else {
+ mContentRatingsTextViews[i].setText(
+ mContentRatingsManager.getDisplayNameForRating(ratings[i]));
+ mContentRatingsTextViews[i].setVisibility(View.VISIBLE);
+ }
}
}
}
@@ -769,8 +735,8 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
mLastUpdatedProgram = program;
}
- private void updateBannerHeight(boolean needFadeAnimation) {
- Assert.assertNull(mResizeAnimator);
+ private void updateBannerHeight(boolean needProgramDescriptionFadeAnimation) {
+ SoftPreconditions.checkState(mResizeAnimator == null);
// Need to measure the layout height with the new description text.
CharSequence oldDescription = mProgramDescriptionTextView.getText();
mProgramDescriptionTextView.setText(mProgramDescriptionText);
@@ -785,12 +751,13 @@ public class ChannelBannerView extends FrameLayout implements TvTransitionManage
layoutParams.height = targetHeight;
setLayoutParams(layoutParams);
}
- } else if (mCurrentHeight != targetHeight || needFadeAnimation) {
+ } else if (mCurrentHeight != targetHeight || needProgramDescriptionFadeAnimation) {
// Restore description text for fade in/out animation.
- if (needFadeAnimation) {
+ if (needProgramDescriptionFadeAnimation) {
mProgramDescriptionTextView.setText(oldDescription);
}
- mResizeAnimator = createResizeAnimator(targetHeight, needFadeAnimation);
+ mResizeAnimator =
+ createResizeAnimator(targetHeight, needProgramDescriptionFadeAnimation);
mResizeAnimator.start();
}
}
diff --git a/src/com/android/tv/ui/KeypadChannelSwitchView.java b/src/com/android/tv/ui/KeypadChannelSwitchView.java
index abc05bad..ac5d841d 100644
--- a/src/com/android/tv/ui/KeypadChannelSwitchView.java
+++ b/src/com/android/tv/ui/KeypadChannelSwitchView.java
@@ -39,7 +39,7 @@ import android.widget.TextView;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.analytics.DurationTimer;
+import com.android.tv.util.DurationTimer;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
diff --git a/src/com/android/tv/ui/SelectInputView.java b/src/com/android/tv/ui/SelectInputView.java
index 5e25ae43..dc92111c 100644
--- a/src/com/android/tv/ui/SelectInputView.java
+++ b/src/com/android/tv/ui/SelectInputView.java
@@ -18,7 +18,6 @@ package com.android.tv.ui;
import android.content.Context;
import android.content.res.Resources;
-import android.hardware.hdmi.HdmiDeviceInfo;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputManager.TvInputCallback;
@@ -37,14 +36,13 @@ import android.widget.TextView;
import com.android.tv.ApplicationSingletons;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.analytics.DurationTimer;
+import com.android.tv.util.DurationTimer;
import com.android.tv.analytics.Tracker;
import com.android.tv.data.Channel;
import com.android.tv.util.TvInputManagerHelper;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -58,7 +56,7 @@ public class SelectInputView extends VerticalGridView implements
private final TvInputManagerHelper mTvInputManagerHelper;
private final List<TvInputInfo> mInputList = new ArrayList<>();
- private final InputsComparator mComparator = new InputsComparator();
+ private final TvInputManagerHelper.HardwareInputComparator mComparator;
private final Tracker mTracker;
private final DurationTimer mViewDurationTimer = new DurationTimer();
private final TvInputCallback mTvInputCallback = new TvInputCallback() {
@@ -149,6 +147,8 @@ public class SelectInputView extends VerticalGridView implements
ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
mTracker = appSingletons.getTracker();
mTvInputManagerHelper = appSingletons.getTvInputManagerHelper();
+ mComparator =
+ new TvInputManagerHelper.HardwareInputComparator(context, mTvInputManagerHelper);
Resources resources = context.getResources();
mInputItemHeight = resources.getDimensionPixelSize(R.dimen.input_banner_item_height);
@@ -385,72 +385,6 @@ public class SelectInputView extends VerticalGridView implements
}
}
- private class InputsComparator implements Comparator<TvInputInfo> {
- @Override
- public int compare(TvInputInfo lhs, TvInputInfo rhs) {
- if (lhs == null) {
- return (rhs == null) ? 0 : 1;
- }
- if (rhs == null) {
- return -1;
- }
-
- boolean enabledL = isInputEnabled(lhs);
- boolean enabledR = isInputEnabled(rhs);
- if (enabledL != enabledR) {
- return enabledL ? -1 : 1;
- }
-
- int priorityL = getPriority(lhs);
- int priorityR = getPriority(rhs);
- if (priorityL != priorityR) {
- return priorityR - priorityL;
- }
-
- String customLabelL = (String) lhs.loadCustomLabel(getContext());
- String customLabelR = (String) rhs.loadCustomLabel(getContext());
- if (!TextUtils.equals(customLabelL, customLabelR)) {
- customLabelL = customLabelL == null ? "" : customLabelL;
- customLabelR = customLabelR == null ? "" : customLabelR;
- return customLabelL.compareToIgnoreCase(customLabelR);
- }
-
- String labelL = (String) lhs.loadLabel(getContext());
- String labelR = (String) rhs.loadLabel(getContext());
- labelL = labelL == null ? "" : labelL;
- labelR = labelR == null ? "" : labelR;
- return labelL.compareToIgnoreCase(labelR);
- }
-
- private int getPriority(TvInputInfo info) {
- switch (info.getType()) {
- case TvInputInfo.TYPE_TUNER:
- return 9;
- case TvInputInfo.TYPE_HDMI:
- HdmiDeviceInfo hdmiInfo = info.getHdmiDeviceInfo();
- if (hdmiInfo != null && hdmiInfo.isCecDevice()) {
- return 8;
- }
- return 7;
- case TvInputInfo.TYPE_DVI:
- return 6;
- case TvInputInfo.TYPE_COMPONENT:
- return 5;
- case TvInputInfo.TYPE_SVIDEO:
- return 4;
- case TvInputInfo.TYPE_COMPOSITE:
- return 3;
- case TvInputInfo.TYPE_DISPLAY_PORT:
- return 2;
- case TvInputInfo.TYPE_VGA:
- return 1;
- case TvInputInfo.TYPE_SCART:
- default:
- return 0;
- }
- }
- }
-
/**
* A callback interface for the input selection.
*/
diff --git a/src/com/android/tv/ui/TunableTvView.java b/src/com/android/tv/ui/TunableTvView.java
index cbe459fb..48386698 100644
--- a/src/com/android/tv/ui/TunableTvView.java
+++ b/src/com/android/tv/ui/TunableTvView.java
@@ -19,9 +19,18 @@ package com.android.tv.ui;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
-import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ApplicationErrorReport;
import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.media.PlaybackParams;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputInfo;
@@ -33,12 +42,11 @@ import android.media.tv.TvView.TvInputCallback;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.annotation.UiThread;
-import android.support.v4.os.BuildCompat;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.AttributeSet;
@@ -47,23 +55,29 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.tv.ApplicationSingletons;
+import com.android.tv.Features;
import com.android.tv.InputSessionManager;
import com.android.tv.InputSessionManager.TvViewSession;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.analytics.DurationTimer;
+import com.android.tv.data.Program;
+import com.android.tv.data.ProgramDataManager;
+import com.android.tv.parental.ParentalControlSettings;
+import com.android.tv.util.DurationTimer;
+import com.android.tv.util.Debug;
import com.android.tv.analytics.Tracker;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.Channel;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.WatchedHistoryManager;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.recommendation.NotificationService;
+import com.android.tv.util.ImageLoader;
import com.android.tv.util.NetworkUtils;
import com.android.tv.util.PermissionUtils;
import com.android.tv.util.TvInputManagerHelper;
@@ -79,6 +93,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
public static final int VIDEO_UNAVAILABLE_REASON_NOT_TUNED = -1;
public static final int VIDEO_UNAVAILABLE_REASON_NO_RESOURCE = -2;
+ public static final int VIDEO_UNAVAILABLE_REASON_SCREEN_BLOCKED = -3;
+ public static final int VIDEO_UNAVAILABLE_REASON_NONE = -100;
@Retention(RetentionPolicy.SOURCE)
@IntDef({BLOCK_SCREEN_TYPE_NO_UI, BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW, BLOCK_SCREEN_TYPE_NORMAL})
@@ -105,17 +121,17 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
private static final int FADING_IN = 2;
private static final int FADING_OUT = 3;
- // It is too small to see the description text without PIP_BLOCK_SCREEN_SCALE_FACTOR.
- private static final float PIP_BLOCK_SCREEN_SCALE_FACTOR = 1.2f;
-
private AppLayerTvView mTvView;
private TvViewSession mTvViewSession;
private Channel mCurrentChannel;
private TvInputManagerHelper mInputManagerHelper;
private ContentRatingsManager mContentRatingsManager;
+ private ParentalControlSettings mParentalControlSettings;
+ private ProgramDataManager mProgramDataManager;
@Nullable
private WatchedHistoryManager mWatchedHistoryManager;
private boolean mStarted;
+ private String mTagetInputId;
private TvInputInfo mInputInfo;
private OnTuneListener mOnTuneListener;
private int mVideoWidth;
@@ -125,7 +141,6 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
private float mVideoDisplayAspectRatio;
private int mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN;
private boolean mHasClosedCaption = false;
- private boolean mVideoAvailable;
private boolean mScreenBlocked;
private OnScreenBlockingChangedListener mOnScreenBlockedListener;
private TvContentRating mBlockedContentRating;
@@ -136,10 +151,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
private boolean mParentControlEnabled;
private int mFixedSurfaceWidth;
private int mFixedSurfaceHeight;
- private boolean mIsPip;
- private int mScreenHeight;
- private int mShrunkenTvViewHeight;
private final boolean mCanModifyParentalControls;
+ private boolean mIsUnderShrunken;
@TimeShiftState private int mTimeShiftState = TIME_SHIFT_STATE_NONE;
private TimeShiftListener mTimeShiftListener;
@@ -150,21 +163,16 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
private final DurationTimer mChannelViewTimer = new DurationTimer();
private InternetCheckTask mInternetCheckTask;
- // A block screen view which has lock icon with black background.
- // This indicates that user's action is needed to play video.
+ // A block screen view to hide the real TV view underlying. It may be used to enforce parental
+ // control, or hide screen when there's no video available and show appropriate information.
private final BlockScreenView mBlockScreenView;
-
- // A View to hide screen when there's problem in video playback.
- private final BlockScreenView mHideScreenView;
-
- // A View to block screen until onContentAllowed is received if parental control is on.
- private final View mBlockScreenForTuneView;
+ private final int mTuningImageColorFilter;
// A spinner view to show buffering status.
private final View mBufferingSpinnerView;
- // A View for fade-in/out animation
private final View mDimScreenView;
+
private int mFadeState = FADED_IN;
private Runnable mActionAfterFade;
@@ -286,21 +294,77 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
@Override
public void onVideoAvailable(String inputId) {
- unhideScreenByVideoAvailability();
+ if (DEBUG) Log.d(TAG, "onVideoAvailable: {inputId=" + inputId + "}");
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log("Start up of Live TV ends," +
+ " TunableTvView.onVideoAvailable resets timer");
+ long startUpDurationTime = Debug.getTimer(Debug.TAG_START_UP_TIMER).reset();
+ Debug.removeTimer(Debug.TAG_START_UP_TIMER);
+ if (BuildConfig.ENG && startUpDurationTime > Debug.TIME_START_UP_DURATION_THRESHOLD) {
+ showAlertDialogForLongStartUp();
+ }
+ mVideoUnavailableReason = VIDEO_UNAVAILABLE_REASON_NONE;
+ updateBlockScreenAndMuting();
if (mOnTuneListener != null) {
mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
}
}
+ private void showAlertDialogForLongStartUp() {
+ new AlertDialog.Builder(getContext()).setTitle(
+ getContext().getString(R.string.settings_send_feedback))
+ .setMessage("Because the start up time of Live channels is too long," +
+ " please send feedback")
+ .setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ Intent intent = new Intent(Intent.ACTION_APP_ERROR);
+ ApplicationErrorReport report = new ApplicationErrorReport();
+ report.packageName = report.processName = getContext()
+ .getApplicationContext().getPackageName();
+ report.time = System.currentTimeMillis();
+ report.type = ApplicationErrorReport.TYPE_CRASH;
+
+ // Add the crash info to add title of feedback automatically.
+ ApplicationErrorReport.CrashInfo crash = new
+ ApplicationErrorReport.CrashInfo();
+ crash.exceptionClassName =
+ "Live TV start up takes long time";
+ crash.exceptionMessage =
+ "The start up time of Live TV is too long";
+ report.crashInfo = crash;
+
+ intent.putExtra(Intent.EXTRA_BUG_REPORT, report);
+ getContext().startActivity(intent);
+ }
+ })
+ .setNegativeButton(android.R.string.no, null)
+ .show();
+ }
+
@Override
public void onVideoUnavailable(String inputId, int reason) {
- hideScreenByVideoAvailability(inputId, reason);
+ if (reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING
+ && reason != TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING) {
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
+ "TunableTvView.onVideoUnAvailable reason = (" + reason
+ + ") and removes timer");
+ Debug.removeTimer(Debug.TAG_START_UP_TIMER);
+ } else {
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log(
+ "TunableTvView.onVideoUnAvailable reason = (" + reason + ")");
+ }
+ mVideoUnavailableReason = reason;
+ if (closePipIfNeeded()) {
+ return;
+ }
+ updateBlockScreenAndMuting();
if (mOnTuneListener != null) {
mOnTuneListener.onStreamInfoChanged(TunableTvView.this);
}
switch (reason) {
- case TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING:
case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:
+ case TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING:
case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:
mTracker.sendChannelVideoUnavailable(mCurrentChannel, reason);
default:
@@ -310,8 +374,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
@Override
public void onContentAllowed(String inputId) {
- mBlockScreenForTuneView.setVisibility(View.GONE);
- unblockScreenByContentRating();
+ mBlockedContentRating = null;
+ updateBlockScreenAndMuting();
if (mOnTuneListener != null) {
mOnTuneListener.onContentAllowed();
}
@@ -319,7 +383,14 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
@Override
public void onContentBlocked(String inputId, TvContentRating rating) {
- blockScreenByContentRating(rating);
+ if (rating != null && rating.equals(mBlockedContentRating)) {
+ return;
+ }
+ mBlockedContentRating = rating;
+ if (closePipIfNeeded()) {
+ return;
+ }
+ updateBlockScreenAndMuting();
if (mOnTuneListener != null) {
mOnTuneListener.onContentBlocked();
}
@@ -327,6 +398,10 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
@Override
public void onTimeShiftStatusChanged(String inputId, int status) {
+ if (DEBUG) {
+ Log.d(TAG, "onTimeShiftStatusChanged: {inputId=" + inputId + ", status=" + status +
+ "}");
+ }
boolean available = status == TvInputManager.TIME_SHIFT_STATUS_AVAILABLE;
setTimeShiftAvailable(available);
}
@@ -361,25 +436,17 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mTracker = appSingletons.getTracker();
mBlockScreenType = BLOCK_SCREEN_TYPE_NORMAL;
mBlockScreenView = (BlockScreenView) findViewById(R.id.block_screen);
- if (!mCanModifyParentalControls) {
- mBlockScreenView.setImage(R.drawable.ic_message_lock_no_permission);
- mBlockScreenView.setScaleType(ImageView.ScaleType.CENTER);
- } else {
- mBlockScreenView.setImage(R.drawable.ic_message_lock);
- }
- mBlockScreenView.setShrunkenImage(R.drawable.ic_message_lock_preview);
- mBlockScreenView.addFadeOutAnimationListener(new AnimatorListenerAdapter() {
+ mBlockScreenView.addInfoFadeInAnimationListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onAnimationStart(Animator animation) {
adjustBlockScreenSpacingAndText();
}
});
- mHideScreenView = (BlockScreenView) findViewById(R.id.hide_screen);
- mHideScreenView.setImageVisibility(false);
mBufferingSpinnerView = findViewById(R.id.buffering_spinner);
- mBlockScreenForTuneView = findViewById(R.id.block_screen_for_tune);
- mDimScreenView = findViewById(R.id.dim);
+ mTuningImageColorFilter = getResources()
+ .getColor(R.color.tvview_block_image_color_filter, null);
+ mDimScreenView = findViewById(R.id.dim_screen);
mDimScreenView.animate().setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -397,27 +464,21 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
});
}
- public void initialize(AppLayerTvView tvView, boolean isPip, int screenHeight,
- int shrunkenTvViewHeight) {
- mTvView = tvView;
+ public void initialize(ProgramDataManager programDataManager,
+ TvInputManagerHelper tvInputManagerHelper) {
+ mTvView = (AppLayerTvView) findViewById(R.id.tv_view);
+ mProgramDataManager = programDataManager;
+ mInputManagerHelper = tvInputManagerHelper;
+ mContentRatingsManager = tvInputManagerHelper.getContentRatingsManager();
+ mParentalControlSettings = tvInputManagerHelper.getParentalControlSettings();
if (mInputSessionManager != null) {
- mTvViewSession = mInputSessionManager.createTvViewSession(tvView, this, mCallback);
+ mTvViewSession = mInputSessionManager.createTvViewSession(mTvView, this, mCallback);
} else {
mTvView.setCallback(mCallback);
}
- mIsPip = isPip;
- mScreenHeight = screenHeight;
- mShrunkenTvViewHeight = shrunkenTvViewHeight;
- mTvView.setZOrderOnTop(isPip);
- copyLayoutParamsToTvView();
}
- public void start(TvInputManagerHelper tvInputManagerHelper) {
- mInputManagerHelper = tvInputManagerHelper;
- mContentRatingsManager = tvInputManagerHelper.getContentRatingsManager();
- if (mStarted) {
- return;
- }
+ public void start() {
mStarted = true;
}
@@ -431,7 +492,8 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
} else {
mTvView.tune(inputId, channelUri);
}
- hideScreenByVideoAvailability(inputId, TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING);
+ mVideoUnavailableReason = TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING;
+ updateBlockScreenAndMuting();
}
}
@@ -462,15 +524,16 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
/**
- * Reset TV view.
+ * Resets TV view.
*/
public void reset() {
resetInternal();
- hideScreenByVideoAvailability(null, VIDEO_UNAVAILABLE_REASON_NOT_TUNED);
+ mVideoUnavailableReason = VIDEO_UNAVAILABLE_REASON_NOT_TUNED;
+ updateBlockScreenAndMuting();
}
/**
- * Reset TV view to acquire the recording session.
+ * Resets TV view to acquire the recording session.
*/
public void resetByRecording() {
resetInternal();
@@ -497,6 +560,13 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mWatchedHistoryManager = watchedHistoryManager;
}
+ /**
+ * Sets if the TunableTvView is under shrunken.
+ */
+ public void setIsUnderShrunken(boolean isUnderShrunken) {
+ mIsUnderShrunken = isUnderShrunken;
+ }
+
public boolean isPlaying() {
return mStarted;
}
@@ -506,8 +576,9 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
*/
public void onParentalControlChanged(boolean enabled) {
mParentControlEnabled = enabled;
- if (!mParentControlEnabled) {
- mBlockScreenForTuneView.setVisibility(View.GONE);
+ if (!enabled) {
+ // Unblock screen immediately if parental control is turned off
+ updateBlockScreenAndMuting();
}
}
@@ -519,6 +590,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
* if the state is disconnected or channelId doesn't exist, it returns false.
*/
public boolean tuneTo(Channel channel, Bundle params, OnTuneListener listener) {
+ Debug.getTimer(Debug.TAG_START_UP_TIMER).log("TunableTvView.tuneTo");
if (!mStarted) {
throw new IllegalStateException("TvView isn't started");
}
@@ -541,6 +613,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
&& params.getString(NotificationService.TUNE_PARAMS_RECOMMENDATION_TYPE) != null;
boolean needSurfaceSizeUpdate = false;
if (!inputInfo.equals(mInputInfo)) {
+ mTagetInputId = inputInfo.getId();
mInputInfo = inputInfo;
mCanReceiveInputEvent = getContext().getPackageManager().checkPermission(
PERMISSION_RECEIVE_INPUT_EVENT, mInputInfo.getServiceInfo().packageName)
@@ -560,6 +633,7 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
mVideoDisplayAspectRatio = 0f;
mAudioChannelCount = StreamInfo.AUDIO_CHANNEL_COUNT_UNKNOWN;
mHasClosedCaption = false;
+ mBlockedContentRating = null;
mTimeShiftCurrentPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
// To reduce the IPCs, unregister the callback here and register it when necessary.
mTvView.setTimeShiftPositionCallback(null);
@@ -569,19 +643,13 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
// So we need to call SurfaceHolder.setFixedSize for the new SurfaceView.
getSurfaceView().getHolder().setFixedSize(mFixedSurfaceWidth, mFixedSurfaceHeight);
}
- hideScreenByVideoAvailability(mInputInfo.getId(),
- TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING);
+ mVideoUnavailableReason = TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING;
if (mTvViewSession != null) {
mTvViewSession.tune(channel, params, listener);
} else {
mTvView.tune(mInputInfo.getId(), mCurrentChannel.getUri(), params);
}
- unblockScreenByContentRating();
- if (channel.isPassthrough()) {
- mBlockScreenForTuneView.setVisibility(View.GONE);
- } else if (mParentControlEnabled) {
- mBlockScreenForTuneView.setVisibility(View.VISIBLE);
- }
+ updateBlockScreenAndMuting();
if (mOnTuneListener != null) {
mOnTuneListener.onStreamInfoChanged(this);
}
@@ -711,7 +779,13 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
@Override
public boolean isVideoAvailable() {
- return mVideoAvailable;
+ return mVideoUnavailableReason == VIDEO_UNAVAILABLE_REASON_NONE;
+ }
+
+ @Override
+ public boolean isVideoOrAudioAvailable() {
+ return mVideoUnavailableReason == VIDEO_UNAVAILABLE_REASON_NONE
+ || mVideoUnavailableReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY;
}
@Override
@@ -747,12 +821,50 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
/**
- * Returns if the screen is blocked by {@link #blockScreen()}.
+ * Gets {@link android.view.ViewGroup.MarginLayoutParams} of the underlying
+ * {@link TvView}, which is the actual view to play live TV videos.
+ */
+ public MarginLayoutParams getTvViewLayoutParams() {
+ return (MarginLayoutParams) mTvView.getLayoutParams();
+ }
+
+ /**
+ * Sets {@link android.view.ViewGroup.MarginLayoutParams} of the underlying
+ * {@link TvView}, which is the actual view to play live TV videos.
+ */
+ public void setTvViewLayoutParams(MarginLayoutParams layoutParams) {
+ mTvView.setLayoutParams(layoutParams);
+ }
+
+ /**
+ * Gets the underlying {@link AppLayerTvView}, which is the actual view to play live TV videos.
+ */
+ public TvView getTvView() {
+ return mTvView;
+ }
+
+ /**
+ * Returns if the screen is blocked, either by {@link #blockOrUnblockScreen(boolean)} or because
+ * the content is blocked.
+ */
+ public boolean isBlocked() {
+ return isScreenBlocked() || isContentBlocked();
+ }
+
+ /**
+ * Returns if the screen is blocked by {@link #blockOrUnblockScreen(boolean)}.
*/
public boolean isScreenBlocked() {
return mScreenBlocked;
}
+ /**
+ * Returns {@code true} if the content is blocked, otherwise {@code false}.
+ */
+ public boolean isContentBlocked() {
+ return mBlockedContentRating != null;
+ }
+
public void setOnScreenBlockedListener(OnScreenBlockingChangedListener listener) {
mOnScreenBlockedListener = listener;
}
@@ -766,77 +878,23 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
}
/**
- * Locks current TV screen and mutes.
+ * Blocks/unblocks current TV screen and mutes.
* There would be black screen with lock icon in order to show that
* screen block is intended and not an error.
- * TODO: Accept parameter to show lock icon or not.
+ *
+ * @param blockOrUnblock {@code true} to block the screen, or {@code false} to unblock.
*/
- public void blockScreen() {
- mScreenBlocked = true;
- checkBlockScreenAndMuteNeeded();
- if (mOnScreenBlockedListener != null) {
- mOnScreenBlockedListener.onScreenBlockingChanged(true);
- }
- }
-
- private void blockScreenByContentRating(TvContentRating rating) {
- mBlockedContentRating = rating;
- checkBlockScreenAndMuteNeeded();
- }
-
- @Override
- @SuppressLint("RtlHardcoded")
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- if (mIsPip) {
- int height = bottom - top;
- float scale;
- if (mBlockScreenType == BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW) {
- scale = height * PIP_BLOCK_SCREEN_SCALE_FACTOR / mShrunkenTvViewHeight;
- } else {
- scale = height * PIP_BLOCK_SCREEN_SCALE_FACTOR / mScreenHeight;
- }
- // TODO: need to get UX confirmation.
- mBlockScreenView.scaleContainerView(scale);
+ public void blockOrUnblockScreen(boolean blockOrUnblock) {
+ if (mScreenBlocked == blockOrUnblock) {
+ return;
}
- }
-
- @Override
- public void setLayoutParams(ViewGroup.LayoutParams params) {
- super.setLayoutParams(params);
- if (mTvView != null) {
- copyLayoutParamsToTvView();
+ mScreenBlocked = blockOrUnblock;
+ if (closePipIfNeeded()) {
+ return;
}
- }
-
- private void copyLayoutParamsToTvView() {
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
- FrameLayout.LayoutParams tvViewLp = (FrameLayout.LayoutParams) mTvView.getLayoutParams();
- if (tvViewLp.bottomMargin != lp.bottomMargin
- || tvViewLp.topMargin != lp.topMargin
- || tvViewLp.leftMargin != lp.leftMargin
- || tvViewLp.rightMargin != lp.rightMargin
- || tvViewLp.gravity != lp.gravity
- || tvViewLp.height != lp.height
- || tvViewLp.width != lp.width) {
- if (lp.topMargin == tvViewLp.topMargin && lp.leftMargin == tvViewLp.leftMargin
- && !BuildCompat.isAtLeastN()) {
- // HACK: If top and left position aren't changed and SurfaceHolder.setFixedSize is
- // used, SurfaceView doesn't catch the width and height change. It causes a bug that
- // PIP size change isn't shown when PIP is located TOP|LEFT. So we adjust 1 px for
- // small size PIP as a workaround.
- // Note: This framework issue has been fixed from NYC.
- tvViewLp.leftMargin = lp.leftMargin + 1;
- } else {
- tvViewLp.leftMargin = lp.leftMargin;
- }
- tvViewLp.topMargin = lp.topMargin;
- tvViewLp.bottomMargin = lp.bottomMargin;
- tvViewLp.rightMargin = lp.rightMargin;
- tvViewLp.gravity = lp.gravity;
- tvViewLp.height = lp.height;
- tvViewLp.width = lp.width;
- mTvView.setLayoutParams(tvViewLp);
+ updateBlockScreenAndMuting();
+ if (mOnScreenBlockedListener != null) {
+ mOnScreenBlockedListener.onScreenBlockingChanged(blockOrUnblock);
}
}
@@ -859,35 +917,67 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
* @param type The type of block screen to set.
*/
public void setBlockScreenType(@BlockScreenType int type) {
- // TODO: need to support the transition from NORMAL to SHRUNKEN and vice verse.
if (mBlockScreenType != type) {
mBlockScreenType = type;
- updateBlockScreenUI(true);
+ updateBlockScreen(true);
}
}
- private void updateBlockScreenUI(boolean animation) {
+ private void updateBlockScreen(boolean animation) {
mBlockScreenView.endAnimations();
-
- if (!mScreenBlocked && mBlockedContentRating == null) {
- mBlockScreenView.setVisibility(GONE);
- return;
- }
-
- mBlockScreenView.setVisibility(VISIBLE);
- if (!animation || mBlockScreenType != TunableTvView.BLOCK_SCREEN_TYPE_NO_UI) {
- adjustBlockScreenSpacingAndText();
+ int blockReason = (mScreenBlocked || mBlockedContentRating != null)
+ && mParentControlEnabled ? VIDEO_UNAVAILABLE_REASON_SCREEN_BLOCKED
+ : mVideoUnavailableReason;
+ if (blockReason != VIDEO_UNAVAILABLE_REASON_NONE) {
+ mBufferingSpinnerView.setVisibility(
+ blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING
+ || blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING ?
+ VISIBLE : GONE);
+ if (!animation) {
+ adjustBlockScreenSpacingAndText();
+ }
+ if (blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING) {
+ return;
+ }
+ mBlockScreenView.setVisibility(VISIBLE);
+ mBlockScreenView.setBackgroundImage(null);
+ if (blockReason == VIDEO_UNAVAILABLE_REASON_SCREEN_BLOCKED) {
+ mBlockScreenView.setIconVisibility(true);
+ if (!mCanModifyParentalControls) {
+ mBlockScreenView.setIconImage(R.drawable.ic_message_lock_no_permission);
+ mBlockScreenView.setIconScaleType(ImageView.ScaleType.CENTER);
+ } else {
+ mBlockScreenView.setIconImage(R.drawable.ic_message_lock);
+ mBlockScreenView.setIconScaleType(ImageView.ScaleType.FIT_CENTER);
+ }
+ } else {
+ if (mInternetCheckTask != null) {
+ mInternetCheckTask.cancel(true);
+ mInternetCheckTask = null;
+ }
+ mBlockScreenView.setIconVisibility(false);
+ if (blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING) {
+ showImageForTuningIfNeeded();
+ } else if (blockReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN
+ && mCurrentChannel != null && !mCurrentChannel.isPhysicalTunerChannel()) {
+ mInternetCheckTask = new InternetCheckTask();
+ mInternetCheckTask.execute();
+ }
+ }
+ mBlockScreenView.onBlockStatusChanged(mBlockScreenType, animation);
+ } else {
+ mBufferingSpinnerView.setVisibility(GONE);
+ if (mBlockScreenView.getVisibility() == VISIBLE) {
+ mBlockScreenView.fadeOut();
+ }
}
- mBlockScreenView.onBlockStatusChanged(mBlockScreenType, animation);
}
private void adjustBlockScreenSpacingAndText() {
- // TODO: need to add animation for padding change when the block screen type is changed
- // NORMAL to SHRUNKEN and vice verse.
mBlockScreenView.setSpacing(mBlockScreenType);
String text = getBlockScreenText();
if (text != null) {
- mBlockScreenView.setText(text);
+ mBlockScreenView.setInfoText(text);
}
}
@@ -896,151 +986,121 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
* Note that returning {@code null} value means that the current text should not be changed.
*/
private String getBlockScreenText() {
- if (mScreenBlocked) {
+ // TODO: add a test for this method
+ Resources res = getResources();
+ if (mScreenBlocked && mParentControlEnabled) {
switch (mBlockScreenType) {
case BLOCK_SCREEN_TYPE_NO_UI:
case BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW:
return "";
case BLOCK_SCREEN_TYPE_NORMAL:
if (mCanModifyParentalControls) {
- return getResources().getString(R.string.tvview_channel_locked);
+ return res.getString(R.string.tvview_channel_locked);
} else {
- return getResources().getString(
- R.string.tvview_channel_locked_no_permission);
+ return res.getString(R.string.tvview_channel_locked_no_permission);
}
}
- } else if (mBlockedContentRating != null) {
+ } else if (mBlockedContentRating != null && mParentControlEnabled) {
String name = mContentRatingsManager.getDisplayNameForRating(mBlockedContentRating);
switch (mBlockScreenType) {
case BLOCK_SCREEN_TYPE_NO_UI:
return "";
case BLOCK_SCREEN_TYPE_SHRUNKEN_TV_VIEW:
if (TextUtils.isEmpty(name)) {
- return getResources().getString(R.string.shrunken_tvview_content_locked);
+ return res.getString(R.string.shrunken_tvview_content_locked);
+ } else if (name.equals(res.getString(R.string.unrated_rating_name))) {
+ return res.getString(R.string.shrunken_tvview_content_locked_unrated);
} else {
- return getContext().getString(
- R.string.shrunken_tvview_content_locked_format, name);
+ return res.getString(R.string.shrunken_tvview_content_locked_format, name);
}
case BLOCK_SCREEN_TYPE_NORMAL:
if (TextUtils.isEmpty(name)) {
if (mCanModifyParentalControls) {
- return getResources().getString(R.string.tvview_content_locked);
+ return res.getString(R.string.tvview_content_locked);
} else {
- return getResources().getString(
- R.string.tvview_content_locked_no_permission);
+ return res.getString(R.string.tvview_content_locked_no_permission);
}
} else {
if (mCanModifyParentalControls) {
- return getContext().getString(
- R.string.tvview_content_locked_format, name);
+ return name.equals(res.getString(R.string.unrated_rating_name))
+ ? res.getString(R.string.tvview_content_locked_unrated)
+ : res.getString(R.string.tvview_content_locked_format, name);
} else {
- return getContext().getString(
- R.string.tvview_content_locked_format_no_permission, name);
+ return name.equals(res.getString(R.string.unrated_rating_name))
+ ? res.getString(
+ R.string.tvview_content_locked_unrated_no_permission)
+ : res.getString(
+ R.string.tvview_content_locked_format_no_permission,
+ name);
}
}
}
+ } else if (mVideoUnavailableReason != VIDEO_UNAVAILABLE_REASON_NONE) {
+ switch (mVideoUnavailableReason) {
+ case TvInputManager.VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY:
+ return res.getString(R.string.tvview_msg_audio_only);
+ case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:
+ return res.getString(R.string.tvview_msg_weak_signal);
+ case VIDEO_UNAVAILABLE_REASON_NO_RESOURCE:
+ return getTuneConflictMessage();
+ default:
+ return "";
+ }
}
return null;
}
- private void checkBlockScreenAndMuteNeeded() {
- updateBlockScreenUI(false);
- if (mScreenBlocked || mBlockedContentRating != null) {
- mute();
- if (mIsPip) {
- // If we don't make mTvView invisible, some frames are leaked when a user changes
- // PIP layout in options.
- // Note: When video is unavailable, we keep the mTvView's visibility, because
- // TIS implementation may not send video available with no surface.
- mTvView.setVisibility(View.INVISIBLE);
- }
- } else {
- unmuteIfPossible();
- if (mIsPip) {
- mTvView.setVisibility(View.VISIBLE);
- }
+ private boolean closePipIfNeeded() {
+ if (Features.PICTURE_IN_PICTURE.isEnabled(getContext())
+ && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
+ && ((Activity) getContext()).isInPictureInPictureMode()
+ && (mScreenBlocked
+ || mBlockedContentRating != null
+ || mVideoUnavailableReason
+ == TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN)) {
+ ((Activity) getContext()).finish();
+ return true;
}
+ return false;
}
- public void unblockScreen() {
- mScreenBlocked = false;
- checkBlockScreenAndMuteNeeded();
- if (mOnScreenBlockedListener != null) {
- mOnScreenBlockedListener.onScreenBlockingChanged(false);
- }
+ private void updateBlockScreenAndMuting() {
+ updateBlockScreen(false);
+ updateMuteStatus();
}
- private void unblockScreenByContentRating() {
- mBlockedContentRating = null;
- checkBlockScreenAndMuteNeeded();
+ private boolean shouldShowImageForTuning() {
+ if (mVideoUnavailableReason != TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING
+ || mScreenBlocked || mBlockedContentRating != null || mCurrentChannel == null
+ || mIsUnderShrunken || getWidth() == 0 || getWidth() == 0 || !isBundledInput()) {
+ return false;
+ }
+ Program currentProgram = mProgramDataManager.getCurrentProgram(mCurrentChannel.getId());
+ if (currentProgram == null) {
+ return false;
+ }
+ TvContentRating rating =
+ mParentalControlSettings.getBlockedRating(currentProgram.getContentRatings());
+ return !(mParentControlEnabled && rating != null);
}
- @UiThread
- private void hideScreenByVideoAvailability(String inputId, int reason) {
- mVideoAvailable = false;
- mVideoUnavailableReason = reason;
- if (mInternetCheckTask != null) {
- mInternetCheckTask.cancel(true);
- mInternetCheckTask = null;
- }
- switch (reason) {
- case TvInputManager.VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY:
- mHideScreenView.setVisibility(VISIBLE);
- mHideScreenView.setImageVisibility(false);
- mHideScreenView.setText(R.string.tvview_msg_audio_only);
- mBufferingSpinnerView.setVisibility(GONE);
- unmuteIfPossible();
- break;
- case TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING:
- mBufferingSpinnerView.setVisibility(VISIBLE);
- mute();
- break;
- case TvInputManager.VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL:
- mHideScreenView.setVisibility(VISIBLE);
- mHideScreenView.setText(R.string.tvview_msg_weak_signal);
- mBufferingSpinnerView.setVisibility(GONE);
- mute();
- break;
- case TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING:
- mHideScreenView.setVisibility(VISIBLE);
- mHideScreenView.setImageVisibility(false);
- mHideScreenView.setText(null);
- mBufferingSpinnerView.setVisibility(VISIBLE);
- mute();
- break;
- case VIDEO_UNAVAILABLE_REASON_NOT_TUNED:
- mHideScreenView.setVisibility(VISIBLE);
- mHideScreenView.setImageVisibility(false);
- mHideScreenView.setText(null);
- mBufferingSpinnerView.setVisibility(GONE);
- mute();
- break;
- case VIDEO_UNAVAILABLE_REASON_NO_RESOURCE:
- mHideScreenView.setVisibility(VISIBLE);
- mHideScreenView.setImageVisibility(false);
- mHideScreenView.setText(getTuneConflictMessage(inputId));
- mBufferingSpinnerView.setVisibility(GONE);
- mute();
- break;
- case TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN:
- default:
- mHideScreenView.setVisibility(VISIBLE);
- mHideScreenView.setImageVisibility(false);
- mHideScreenView.setText(null);
- mBufferingSpinnerView.setVisibility(GONE);
- mute();
- if (mCurrentChannel != null && !mCurrentChannel.isPhysicalTunerChannel()) {
- mInternetCheckTask = new InternetCheckTask();
- mInternetCheckTask.execute();
- }
- break;
+ private void showImageForTuningIfNeeded() {
+ if (shouldShowImageForTuning()) {
+ if (mCurrentChannel == null) {
+ return;
+ }
+ Program currentProgram = mProgramDataManager.getCurrentProgram(mCurrentChannel.getId());
+ if (currentProgram != null) {
+ currentProgram.loadPosterArt(getContext(), getWidth(), getHeight(),
+ createProgramPosterArtCallback(mCurrentChannel.getId()));
+ }
}
}
- private String getTuneConflictMessage(String inputId) {
- if (inputId != null) {
- TvInputInfo input = mInputManager.getTvInputInfo(inputId);
- Long timeMs = mInputSessionManager.getEarliestRecordingSessionEndTimeMs(inputId);
+ private String getTuneConflictMessage() {
+ if (mTagetInputId != null) {
+ TvInputInfo input = mInputManager.getTvInputInfo(mTagetInputId);
+ Long timeMs = mInputSessionManager.getEarliestRecordingSessionEndTimeMs(mTagetInputId);
if (timeMs != null) {
return getResources().getQuantityString(R.plurals.tvview_msg_input_no_resource,
input.getTunerCount(),
@@ -1050,27 +1110,36 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
return null;
}
- private void unhideScreenByVideoAvailability() {
- mVideoAvailable = true;
- mHideScreenView.setVisibility(GONE);
- mBufferingSpinnerView.setVisibility(GONE);
- unmuteIfPossible();
- }
-
- private void unmuteIfPossible() {
- if (mVideoAvailable && !mScreenBlocked && mBlockedContentRating == null) {
- unmute();
+ private void updateMuteStatus() {
+ // Workaround: TunerTvInputService uses AC3 pass-through implementation, which disables
+ // audio tracks to enforce the mute request. We don't want to send mute request if we are
+ // not going to block the screen to prevent the video jankiness resulted by disabling audio
+ // track before the playback is started. In other way, we should send unmute request before
+ // the playback is started, because TunerTvInput will remember the muted state and mute
+ // itself right way when the playback is going to be started, which results the initial
+ // jankiness, too.
+ boolean isBundledInput = isBundledInput();
+ if ((isBundledInput || isVideoOrAudioAvailable()) && !mScreenBlocked
+ && mBlockedContentRating == null) {
+ if (mIsMuted) {
+ mIsMuted = false;
+ mTvView.setStreamVolume(mVolume);
+ }
+ } else {
+ if (!mIsMuted) {
+ if ((mInputInfo == null || isBundledInput)
+ && !mScreenBlocked && mBlockedContentRating == null) {
+ return;
+ }
+ mIsMuted = true;
+ mTvView.setStreamVolume(0);
+ }
}
}
- private void mute() {
- mIsMuted = true;
- mTvView.setStreamVolume(0);
- }
-
- private void unmute() {
- mIsMuted = false;
- mTvView.setStreamVolume(mVolume);
+ private boolean isBundledInput() {
+ return mInputInfo != null && mInputInfo.getType() == TvInputInfo.TYPE_TUNER
+ && Utils.isBundledInput(mInputInfo.getId());
}
/** Returns true if this view is faded out. */
@@ -1268,6 +1337,24 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
return mTimeShiftCurrentPositionMs;
}
+ private ImageLoader.ImageLoaderCallback<BlockScreenView> createProgramPosterArtCallback(
+ final long channelId) {
+ return new ImageLoader.ImageLoaderCallback<BlockScreenView>(mBlockScreenView) {
+ @Override
+ public void onBitmapLoaded(BlockScreenView view, @Nullable Bitmap posterArt) {
+ if (posterArt == null || getCurrentChannel() == null
+ || channelId != getCurrentChannel().getId()
+ || !shouldShowImageForTuning()) {
+ return;
+ }
+ Drawable drawablePosterArt = new BitmapDrawable(view.getResources(), posterArt);
+ drawablePosterArt.mutate().setColorFilter(
+ mTuningImageColorFilter, PorterDuff.Mode.SRC_OVER);
+ view.setBackgroundImage(drawablePosterArt);
+ }
+ };
+ }
+
/**
* Used to receive the time-shift events.
*/
@@ -1304,11 +1391,12 @@ public class TunableTvView extends FrameLayout implements StreamInfo {
@Override
protected void onPostExecute(Boolean networkAvailable) {
mInternetCheckTask = null;
- if (!mVideoAvailable && !networkAvailable && isAttachedToWindow()
+ if (!networkAvailable && isAttachedToWindow()
+ && !mScreenBlocked && mBlockedContentRating == null
&& mVideoUnavailableReason == TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN) {
- mHideScreenView.setImageVisibility(true);
- mHideScreenView.setImage(R.drawable.ic_sad_cloud);
- mHideScreenView.setText(R.string.tvview_msg_no_internet_connection);
+ mBlockScreenView.setIconVisibility(true);
+ mBlockScreenView.setIconImage(R.drawable.ic_sad_cloud);
+ mBlockScreenView.setInfoText(R.string.tvview_msg_no_internet_connection);
}
}
}
diff --git a/src/com/android/tv/ui/TvOverlayManager.java b/src/com/android/tv/ui/TvOverlayManager.java
index e14b286b..9324742e 100644
--- a/src/com/android/tv/ui/TvOverlayManager.java
+++ b/src/com/android/tv/ui/TvOverlayManager.java
@@ -20,6 +20,7 @@ import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentManager.OnBackStackChangedListener;
import android.content.Intent;
+import android.media.tv.TvContentRating;
import android.media.tv.TvInputInfo;
import android.os.Bundle;
import android.os.Handler;
@@ -39,6 +40,7 @@ import com.android.tv.MainActivity.KeyHandlerResultType;
import com.android.tv.R;
import com.android.tv.TimeShiftManager;
import com.android.tv.TvApplication;
+import com.android.tv.TvOptionsManager;
import com.android.tv.analytics.Tracker;
import com.android.tv.common.WeakHandler;
import com.android.tv.common.feature.CommonFeatures;
@@ -46,14 +48,16 @@ import com.android.tv.common.ui.setup.OnActionClickListener;
import com.android.tv.common.ui.setup.SetupFragment;
import com.android.tv.common.ui.setup.SetupMultiPaneFragment;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.dialog.DvrHistoryDialogFragment;
import com.android.tv.dialog.FullscreenDialogFragment;
+import com.android.tv.dialog.HalfSizedDialogFragment;
import com.android.tv.dialog.PinDialogFragment;
import com.android.tv.dialog.RecentlyWatchedDialogFragment;
import com.android.tv.dialog.SafeDismissDialogFragment;
import com.android.tv.dvr.DvrDataManager;
-import com.android.tv.dvr.ui.DvrActivity;
-import com.android.tv.dvr.ui.HalfSizedDialogFragment;
+import com.android.tv.dvr.ui.browse.DvrBrowseActivity;
import com.android.tv.guide.ProgramGuide;
+import com.android.tv.license.LicenseDialogFragment;
import com.android.tv.menu.Menu;
import com.android.tv.menu.Menu.MenuShowReason;
import com.android.tv.menu.MenuRowFactory;
@@ -62,7 +66,6 @@ import com.android.tv.onboarding.NewSourcesFragment;
import com.android.tv.onboarding.SetupSourcesFragment;
import com.android.tv.search.ProgramGuideSearchFragment;
import com.android.tv.ui.TvTransitionManager.SceneType;
-import com.android.tv.ui.sidepanel.SettingsFragment;
import com.android.tv.ui.sidepanel.SideFragmentManager;
import com.android.tv.ui.sidepanel.parentalcontrols.RatingsFragment;
import com.android.tv.util.TvInputManagerHelper;
@@ -157,15 +160,47 @@ public class TvOverlayManager {
// Used for the padded print of the overlay type.
private static final int NUM_OVERLAY_TYPES = 9;
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW, UPDATE_CHANNEL_BANNER_REASON_TUNE,
+ UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST, UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO,
+ UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK,
+ UPDATE_CHANNEL_BANNER_REASON_UPDATE_STREAM_INFO})
+ private @interface ChannelBannerUpdateReason {}
+ /**
+ * Updates channel banner because the channel banner is forced to show.
+ */
+ public static final int UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW = 1;
+ /**
+ * Updates channel banner because of tuning.
+ */
+ public static final int UPDATE_CHANNEL_BANNER_REASON_TUNE = 2;
+ /**
+ * Updates channel banner because of fast tuning.
+ */
+ public static final int UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST = 3;
+ /**
+ * Updates channel banner because of info updating.
+ */
+ public static final int UPDATE_CHANNEL_BANNER_REASON_UPDATE_INFO = 4;
+ /**
+ * Updates channel banner because the current watched channel is locked or unlocked.
+ */
+ public static final int UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK = 5;
+ /**
+ * Updates channel banner because of stream info updating.
+ */
+ public static final int UPDATE_CHANNEL_BANNER_REASON_UPDATE_STREAM_INFO = 6;
+
private static final String FRAGMENT_TAG_SETUP_SOURCES = "tag_setup_sources";
private static final String FRAGMENT_TAG_NEW_SOURCES = "tag_new_sources";
private static final Set<String> AVAILABLE_DIALOG_TAGS = new HashSet<>();
static {
AVAILABLE_DIALOG_TAGS.add(RecentlyWatchedDialogFragment.DIALOG_TAG);
+ AVAILABLE_DIALOG_TAGS.add(DvrHistoryDialogFragment.DIALOG_TAG);
AVAILABLE_DIALOG_TAGS.add(PinDialogFragment.DIALOG_TAG);
AVAILABLE_DIALOG_TAGS.add(FullscreenDialogFragment.DIALOG_TAG);
- AVAILABLE_DIALOG_TAGS.add(SettingsFragment.LicenseActionItem.DIALOG_TAG);
+ AVAILABLE_DIALOG_TAGS.add(LicenseDialogFragment.DIALOG_TAG);
AVAILABLE_DIALOG_TAGS.add(RatingsFragment.AttributionItem.DIALOG_TAG);
AVAILABLE_DIALOG_TAGS.add(HalfSizedDialogFragment.DIALOG_TAG);
}
@@ -176,8 +211,10 @@ public class TvOverlayManager {
private final ChannelDataManager mChannelDataManager;
private final TvInputManagerHelper mInputManager;
private final Menu mMenu;
+ private final TunableTvView mTvView;
private final SideFragmentManager mSideFragmentManager;
private final ProgramGuide mProgramGuide;
+ private final ChannelBannerView mChannelBannerView;
private final KeypadChannelSwitchView mKeypadChannelSwitchView;
private final SelectInputView mSelectInputView;
private final ProgramGuideSearchFragment mSearchFragment;
@@ -185,6 +222,7 @@ public class TvOverlayManager {
private SafeDismissDialogFragment mCurrentDialog;
private boolean mSetupFragmentActive;
private boolean mNewSourcesFragmentActive;
+ private boolean mChannelBannerHiddenBySideFragment;
private final Handler mHandler = new TvOverlayHandler(this);
private @TvOverlayType int mOpenedOverlays;
@@ -195,15 +233,17 @@ public class TvOverlayManager {
private OnBackStackChangedListener mOnBackStackChangedListener;
public TvOverlayManager(MainActivity mainActivity, ChannelTuner channelTuner,
- TunableTvView tvView, KeypadChannelSwitchView keypadChannelSwitchView,
- ChannelBannerView channelBannerView, InputBannerView inputBannerView,
- SelectInputView selectInputView, ViewGroup sceneContainer,
- ProgramGuideSearchFragment searchFragment) {
+ TunableTvView tvView, TvOptionsManager optionsManager,
+ KeypadChannelSwitchView keypadChannelSwitchView, ChannelBannerView channelBannerView,
+ InputBannerView inputBannerView, SelectInputView selectInputView,
+ ViewGroup sceneContainer, ProgramGuideSearchFragment searchFragment) {
mMainActivity = mainActivity;
mChannelTuner = channelTuner;
ApplicationSingletons singletons = TvApplication.getSingletons(mainActivity);
mChannelDataManager = singletons.getChannelDataManager();
mInputManager = singletons.getTvInputManagerHelper();
+ mTvView = tvView;
+ mChannelBannerView = channelBannerView;
mKeypadChannelSwitchView = keypadChannelSwitchView;
mSelectInputView = selectInputView;
mSearchFragment = searchFragment;
@@ -225,7 +265,8 @@ public class TvOverlayManager {
});
// Menu
MenuView menuView = (MenuView) mainActivity.findViewById(R.id.menu);
- mMenu = new Menu(mainActivity, tvView, menuView, new MenuRowFactory(mainActivity, tvView),
+ mMenu = new Menu(mainActivity, tvView, optionsManager, menuView,
+ new MenuRowFactory(mainActivity, tvView),
new Menu.OnMenuVisibilityChangeListener() {
@Override
public void onMenuVisibilityChange(boolean visible) {
@@ -249,7 +290,7 @@ public class TvOverlayManager {
new Runnable() {
@Override
public void run() {
- mMainActivity.showChannelBannerIfHiddenBySideFragment();
+ showChannelBannerIfHiddenBySideFragment();
onOverlayClosed(OVERLAY_TYPE_SIDE_FRAGMENT);
}
});
@@ -320,6 +361,9 @@ public class TvOverlayManager {
public void release() {
mMenu.release();
mHandler.removeCallbacksAndMessages(null);
+ if (mKeypadChannelSwitchView != null) {
+ mKeypadChannelSwitchView.setChannels(null);
+ }
}
/**
@@ -436,6 +480,13 @@ public class TvOverlayManager {
onOverlayOpened(OVERLAY_TYPE_DIALOG);
}
+ /**
+ * Should be called by {@link MainActivity} when the currently browsable channels are updated.
+ */
+ public void onBrowsableChannelsUpdated() {
+ mKeypadChannelSwitchView.setChannels(mChannelTuner.getBrowsableChannelList());
+ }
+
private void runAfterSideFragmentsAreClosed(final Runnable runnable) {
if (mSideFragmentManager.isSidePanelVisible()) {
// When the side panel is closing, it closes all the fragments, so the new fragment
@@ -541,7 +592,7 @@ public class TvOverlayManager {
* Shows DVR manager.
*/
public void showDvrManager() {
- Intent intent = new Intent(mMainActivity, DvrActivity.class);
+ Intent intent = new Intent(mMainActivity, DvrBrowseActivity.class);
mMainActivity.startActivity(intent);
}
@@ -564,18 +615,34 @@ public class TvOverlayManager {
}
/**
+ * Shows DVR history dialog.
+ */
+ public void showDvrHistoryDialog() {
+ showDialogFragment(DvrHistoryDialogFragment.DIALOG_TAG,
+ new DvrHistoryDialogFragment(), false);
+ }
+
+ /**
* Shows banner view.
*/
public void showBanner() {
mTransitionManager.goToChannelBannerScene();
}
- public void showKeypadChannelSwitch() {
- hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SCENE
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
- | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
- mTransitionManager.goToKeypadChannelSwitchScene();
+ /**
+ * Pops up the KeypadChannelSwitchView with the given key input event.
+ *
+ * @param keyCode A key code of the key event.
+ */
+ public void showKeypadChannelSwitch(int keyCode) {
+ if (mChannelTuner.areAllChannelsLoaded()) {
+ hideOverlays(TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SCENE
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
+ | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
+ mTransitionManager.goToKeypadChannelSwitchScene();
+ mKeypadChannelSwitchView.onNumberKeyUp(keyCode - KeyEvent.KEYCODE_0);
+ }
}
/**
@@ -619,6 +686,31 @@ public class TvOverlayManager {
}
/**
+ * Shows/hides the program guide according to it's hidden or shown now.
+ *
+ * @return {@code true} if program guide is going to be shown, otherwise {@code false}.
+ */
+ public boolean toggleProgramGuide() {
+ if (mProgramGuide.isActive()) {
+ mProgramGuide.onBackPressed();
+ return false;
+ } else {
+ showProgramGuide();
+ return true;
+ }
+ }
+
+ /**
+ * Sets blocking content rating of the currently playing TV channel.
+ */
+ public void setBlockingContentRating(TvContentRating rating) {
+ if (!mMainActivity.isChannelChangeKeyDownReceived()) {
+ mChannelBannerView.setBlockingContentRating(rating);
+ updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK);
+ }
+ }
+
+ /**
* Hides all the opened overlays according to the flags.
*/
// TODO: Add test for this method.
@@ -631,12 +723,12 @@ public class TvOverlayManager {
} else {
if (mCurrentDialog != null) {
if (mCurrentDialog instanceof PinDialogFragment) {
- // The result listener of PinDialogFragment could call MenuView when
- // the dialog is dismissed. In order not to call it, set the result listener
- // to null.
- ((PinDialogFragment) mCurrentDialog).setResultListener(null);
+ // We don't want any OnPinCheckedListener is triggered to prevent any possible
+ // side effects. Dismisses the dialog silently.
+ ((PinDialogFragment) mCurrentDialog).dismissSilently();
+ } else {
+ mCurrentDialog.dismiss();
}
- mCurrentDialog.dismiss();
}
mPendingDialogActionQueue.clear();
mCurrentDialog = null;
@@ -674,7 +766,7 @@ public class TvOverlayManager {
}
if ((flags & FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS) != 0) {
// Keeps side panels.
- } else if (mSideFragmentManager.isSidePanelVisible()) {
+ } else if (mSideFragmentManager.isActive()) {
if ((flags & FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANEL_HISTORY) != 0) {
mSideFragmentManager.hideSidePanel(withAnimation);
} else {
@@ -701,6 +793,83 @@ public class TvOverlayManager {
|| mNewSourcesFragmentActive;
}
+ /**
+ * Updates and shows channel banner if it's needed.
+ */
+ public void updateChannelBannerAndShowIfNeeded(@ChannelBannerUpdateReason int reason) {
+ if(DEBUG) Log.d(TAG, "updateChannelBannerAndShowIfNeeded(reason=" + reason + ")");
+ if (mMainActivity.isChannelChangeKeyDownReceived()
+ && reason != UPDATE_CHANNEL_BANNER_REASON_TUNE
+ && reason != UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST) {
+ // Tuning is still ongoing, no need to update banner for other reasons
+ return;
+ }
+ if (!mChannelTuner.isCurrentChannelPassthrough()) {
+ int lockType = ChannelBannerView.LOCK_NONE;
+ if (reason == UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST) {
+ if (mMainActivity.getParentalControlSettings().isParentalControlsEnabled()
+ && mMainActivity.getCurrentChannel().isLocked()) {
+ lockType = ChannelBannerView.LOCK_CHANNEL_INFO;
+ } else {
+ // Do not show detailed program information while fast-tuning.
+ lockType = ChannelBannerView.LOCK_PROGRAM_DETAIL;
+ }
+ } else if (reason == UPDATE_CHANNEL_BANNER_REASON_TUNE) {
+ if (mMainActivity.getParentalControlSettings().isParentalControlsEnabled()) {
+ if (mMainActivity.getCurrentChannel().isLocked()) {
+ lockType = ChannelBannerView.LOCK_CHANNEL_INFO;
+ } else {
+ // If parental control is turned on,
+ // assumes that program is locked by default and waits for onContentAllowed.
+ lockType = ChannelBannerView.LOCK_PROGRAM_DETAIL;
+ }
+ }
+ } else if (mTvView.isScreenBlocked()) {
+ lockType = ChannelBannerView.LOCK_CHANNEL_INFO;
+ } else if (mTvView.isContentBlocked() || (mMainActivity.getParentalControlSettings()
+ .isParentalControlsEnabled() && !mTvView.isVideoOrAudioAvailable())) {
+ // If the parental control is enabled, do not show the program detail until the
+ // video becomes available.
+ lockType = ChannelBannerView.LOCK_PROGRAM_DETAIL;
+ }
+ // If lock type is not changed, we don't need to update channel banner by parental
+ // control.
+ int previousLockType = mChannelBannerView.setLockType(lockType);
+ if (previousLockType == lockType
+ && reason == UPDATE_CHANNEL_BANNER_REASON_LOCK_OR_UNLOCK) {
+ return;
+ } else if (reason == UPDATE_CHANNEL_BANNER_REASON_UPDATE_STREAM_INFO) {
+ mChannelBannerView.updateStreamInfo(mTvView);
+ // If parental control is enabled, we shows program description when the video is
+ // available, instead of tuning. Therefore we need to check it here if the program
+ // description is previously hidden by parental control.
+ if (previousLockType == ChannelBannerView.LOCK_PROGRAM_DETAIL &&
+ lockType != ChannelBannerView.LOCK_PROGRAM_DETAIL) {
+ mChannelBannerView.updateViews(false);
+ }
+ } else {
+ mChannelBannerView.updateViews(reason == UPDATE_CHANNEL_BANNER_REASON_TUNE
+ || reason == UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST);
+ }
+ }
+ boolean needToShowBanner = (reason == UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW
+ || reason == UPDATE_CHANNEL_BANNER_REASON_TUNE
+ || reason == UPDATE_CHANNEL_BANNER_REASON_TUNE_FAST);
+ if (needToShowBanner && !mMainActivity.willShowOverlayUiWhenResume()
+ && getCurrentDialog() == null
+ && !isSetupFragmentActive()
+ && !isNewSourcesFragmentActive()) {
+ if (mChannelTuner.getCurrentChannel() == null) {
+ mChannelBannerHiddenBySideFragment = false;
+ } else if (getSideFragmentManager().isActive()) {
+ mChannelBannerHiddenBySideFragment = true;
+ } else {
+ mChannelBannerHiddenBySideFragment = false;
+ showBanner();
+ }
+ }
+ }
+
@TvOverlayType private int convertSceneToOverlayType(@SceneType int sceneType) {
switch (sceneType) {
case TvTransitionManager.SCENE_TYPE_CHANNEL_BANNER:
@@ -749,6 +918,18 @@ public class TvOverlayManager {
}
}
+ /**
+ * Shows the channel banner if it was hidden from the side fragment.
+ *
+ * <p>When the side fragment is visible, showing the channel banner should be put off until the
+ * side fragment is closed even though the channel changes.
+ */
+ private void showChannelBannerIfHiddenBySideFragment() {
+ if (mChannelBannerHiddenBySideFragment) {
+ updateChannelBannerAndShowIfNeeded(UPDATE_CHANNEL_BANNER_REASON_FORCE_SHOW);
+ }
+ }
+
private String toBinaryString(int value) {
return String.format("0b%" + NUM_OVERLAY_TYPES + "s", Integer.toBinaryString(value))
.replace(' ', '0');
@@ -843,6 +1024,7 @@ public class TvOverlayManager {
timeShiftManager.play();
showMenu(Menu.REASON_PLAY_CONTROLS_PLAY);
break;
+ case KeyEvent.KEYCODE_MEDIA_STOP:
case KeyEvent.KEYCODE_MEDIA_PAUSE:
timeShiftManager.pause();
showMenu(Menu.REASON_PLAY_CONTROLS_PAUSE);
@@ -916,7 +1098,7 @@ public class TvOverlayManager {
}
if (mMenu.isActive()) {
if (KeypadChannelSwitchView.isChannelNumberKey(keyCode)) {
- mMainActivity.showKeypadChannelSwitchView(keyCode);
+ showKeypadChannelSwitch(keyCode);
return MainActivity.KEY_EVENT_HANDLER_RESULT_HANDLED;
}
return MainActivity.KEY_EVENT_HANDLER_RESULT_DISPATCH_TO_OVERLAY;
@@ -971,6 +1153,7 @@ public class TvOverlayManager {
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
case KeyEvent.KEYCODE_MEDIA_SKIP_FORWARD:
case KeyEvent.KEYCODE_MEDIA_SKIP_BACKWARD:
+ case KeyEvent.KEYCODE_MEDIA_STOP:
return true;
}
return false;
diff --git a/src/com/android/tv/ui/TvTransitionManager.java b/src/com/android/tv/ui/TvTransitionManager.java
index 52e96cc0..628bbb72 100644
--- a/src/com/android/tv/ui/TvTransitionManager.java
+++ b/src/com/android/tv/ui/TvTransitionManager.java
@@ -129,8 +129,8 @@ public class TvTransitionManager extends TransitionManager {
public void goToSelectInputScene() {
initIfNeeded();
if (mCurrentScene != mSelectInputScene) {
- transitionTo(mSelectInputScene);
mSelectInputView.setCurrentChannel(mMainActivity.getCurrentChannel());
+ transitionTo(mSelectInputScene);
}
}
diff --git a/src/com/android/tv/ui/TvViewUiManager.java b/src/com/android/tv/ui/TvViewUiManager.java
index bf874fc7..f042987a 100644
--- a/src/com/android/tv/ui/TvViewUiManager.java
+++ b/src/com/android/tv/ui/TvViewUiManager.java
@@ -24,21 +24,19 @@ import android.animation.TimeInterpolator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
+import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.util.Property;
import android.view.Display;
-import android.view.Gravity;
-import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
@@ -52,9 +50,8 @@ import com.android.tv.data.DisplayMode;
import com.android.tv.util.TvSettings;
/**
- * The TvViewUiManager is responsible for handling UI layouting and animation of main and PIP
- * TvViews. It also control the settings regarding TvView UI such as display mode, PIP layout,
- * and PIP size.
+ * The TvViewUiManager is responsible for handling UI layouting and animation of main TvView.
+ * It also control the settings regarding TvView UI such as display mode.
*/
public class TvViewUiManager {
private static final String TAG = "TvViewManager";
@@ -69,42 +66,44 @@ public class TvViewUiManager {
private final Resources mResources;
private final FrameLayout mContentView;
private final TunableTvView mTvView;
- private final TunableTvView mPipView;
private final TvOptionsManager mTvOptionsManager;
- private final int mTvViewPapWidth;
private final int mTvViewShrunkenStartMargin;
private final int mTvViewShrunkenEndMargin;
- private final int mTvViewPapStartMargin;
- private final int mTvViewPapEndMargin;
private int mWindowWidth;
private int mWindowHeight;
- private final int mPipViewHorizontalMargin;
- private final int mPipViewTopMargin;
- private final int mPipViewBottomMargin;
private final SharedPreferences mSharedPreferences;
private final TimeInterpolator mLinearOutSlowIn;
private final TimeInterpolator mFastOutLinearIn;
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch(msg.what) {
- case MSG_SET_LAYOUT_PARAMS:
- FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) msg.obj;
- if (DEBUG) {
- Log.d(TAG, "setFixedSize: w=" + layoutParams.width + " h="
- + layoutParams.height);
- }
- mTvView.setLayoutParams(layoutParams);
- // Smooth PIP size change, we don't change surface size when
- // isInPictureInPictureMode is true.
- if (!Features.PICTURE_IN_PICTURE.isEnabled(mContext)
- || !((Activity) mContext).isInPictureInPictureMode()) {
- mTvView.setFixedSurfaceSize(layoutParams.width, layoutParams.height);
+ private final Handler mHandler =
+ new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SET_LAYOUT_PARAMS:
+ FrameLayout.LayoutParams layoutParams =
+ (FrameLayout.LayoutParams) msg.obj;
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "setFixedSize: w="
+ + layoutParams.width
+ + " h="
+ + layoutParams.height);
+ }
+ mTvView.setTvViewLayoutParams(layoutParams);
+ mTvView.setLayoutParams(mTvViewFrame);
+ // Smooth PIP size change, we don't change surface size when
+ // isInPictureInPictureMode is true.
+ if (!Features.PICTURE_IN_PICTURE.isEnabled(mContext)
+ || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
+ && !((Activity) mContext).isInPictureInPictureMode())) {
+ mTvView.setFixedSurfaceSize(
+ layoutParams.width, layoutParams.height);
+ }
+ break;
}
- break;
- }
- }
- };
+ }
+ };
private int mDisplayMode;
// Used to restore the previous state from ShrunkenTvView state.
private int mTvViewStartMarginBeforeShrunken;
@@ -113,16 +112,13 @@ public class TvViewUiManager {
private boolean mIsUnderShrunkenTvView;
private int mTvViewStartMargin;
private int mTvViewEndMargin;
- private int mPipLayout;
- private int mPipSize;
- private boolean mPipStarted;
private ObjectAnimator mTvViewAnimator;
private FrameLayout.LayoutParams mTvViewLayoutParams;
// TV view's position when the display mode is FULL. It is used to compute PIP location relative
// to TV view's position.
- private MarginLayoutParams mTvViewFrame;
- private MarginLayoutParams mLastAnimatedTvViewFrame;
- private MarginLayoutParams mOldTvViewFrame;
+ private FrameLayout.LayoutParams mTvViewFrame;
+ private FrameLayout.LayoutParams mLastAnimatedTvViewFrame;
+ private FrameLayout.LayoutParams mOldTvViewFrame;
private ObjectAnimator mBackgroundAnimator;
private int mBackgroundColor;
private int mAppliedDisplayedMode = DisplayMode.MODE_NOT_DEFINED;
@@ -130,12 +126,11 @@ public class TvViewUiManager {
private int mAppliedTvViewEndMargin;
private float mAppliedVideoDisplayAspectRatio;
- public TvViewUiManager(Context context, TunableTvView tvView, TunableTvView pipView,
+ public TvViewUiManager(Context context, TunableTvView tvView,
FrameLayout contentView, TvOptionsManager tvOptionManager) {
mContext = context;
mResources = mContext.getResources();
mTvView = tvView;
- mPipView = pipView;
mContentView = contentView;
mTvOptionsManager = tvOptionManager;
@@ -147,18 +142,12 @@ public class TvViewUiManager {
mWindowWidth = size.x;
mWindowHeight = size.y;
- // Have an assumption that PIP and TvView Shrinking happens only in full screen.
+ // Have an assumption that TvView Shrinking happens only in full screen.
mTvViewShrunkenStartMargin = mResources
.getDimensionPixelOffset(R.dimen.shrunken_tvview_margin_start);
mTvViewShrunkenEndMargin =
mResources.getDimensionPixelOffset(R.dimen.shrunken_tvview_margin_end)
+ mResources.getDimensionPixelSize(R.dimen.side_panel_width);
- int papMarginHorizontal = mResources
- .getDimensionPixelOffset(R.dimen.papview_margin_horizontal);
- int papSpacing = mResources.getDimensionPixelOffset(R.dimen.papview_spacing);
- mTvViewPapWidth = (mWindowWidth - papSpacing) / 2 - papMarginHorizontal;
- mTvViewPapStartMargin = papMarginHorizontal + mTvViewPapWidth + papSpacing;
- mTvViewPapEndMargin = papMarginHorizontal;
mTvViewFrame = createMarginLayoutParams(0, 0, 0, 0);
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
@@ -167,11 +156,6 @@ public class TvViewUiManager {
.loadInterpolator(mContext, android.R.interpolator.linear_out_slow_in);
mFastOutLinearIn = AnimationUtils
.loadInterpolator(mContext, android.R.interpolator.fast_out_linear_in);
-
- mPipViewHorizontalMargin = mResources
- .getDimensionPixelOffset(R.dimen.pipview_margin_horizontal);
- mPipViewTopMargin = mResources.getDimensionPixelOffset(R.dimen.pipview_margin_top);
- mPipViewBottomMargin = mResources.getDimensionPixelOffset(R.dimen.pipview_margin_bottom);
}
public void onConfigurationChanged(final int windowWidth, final int windowHeight) {
@@ -200,18 +184,11 @@ public class TvViewUiManager {
*/
public void startShrunkenTvView() {
mIsUnderShrunkenTvView = true;
+ mTvView.setIsUnderShrunken(true);
mTvViewStartMarginBeforeShrunken = mTvViewStartMargin;
mTvViewEndMarginBeforeShrunken = mTvViewEndMargin;
- if (mPipStarted && getPipLayout() == TvSettings.PIP_LAYOUT_SIDE_BY_SIDE) {
- float sidePanelWidth = mResources.getDimensionPixelOffset(R.dimen.side_panel_width);
- float factor = 1.0f - sidePanelWidth / mWindowWidth;
- int startMargin = (int) (mTvViewPapStartMargin * factor);
- int endMargin = (int) (mTvViewPapEndMargin * factor + sidePanelWidth);
- setTvViewMargin(startMargin, endMargin);
- } else {
- setTvViewMargin(mTvViewShrunkenStartMargin, mTvViewShrunkenEndMargin);
- }
+ setTvViewMargin(mTvViewShrunkenStartMargin, mTvViewShrunkenEndMargin);
mDisplayModeBeforeShrunken = setDisplayMode(DisplayMode.MODE_NORMAL, false, true);
}
@@ -221,6 +198,7 @@ public class TvViewUiManager {
*/
public void endShrunkenTvView() {
mIsUnderShrunkenTvView = false;
+ mTvView.setIsUnderShrunken(false);
setTvViewMargin(mTvViewStartMarginBeforeShrunken, mTvViewEndMarginBeforeShrunken);
setDisplayMode(mDisplayModeBeforeShrunken, false, true);
}
@@ -296,9 +274,9 @@ public class TvViewUiManager {
}
/**
- * Updates TvView. It is called when video resolution is updated.
+ * Updates TvView's aspect ratio. It should be called when video resolution is changed.
*/
- public void updateTvView() {
+ public void updateTvAspectRatio() {
applyDisplayMode(mTvView.getVideoDisplayAspectRatio(), false, false);
if (mTvView.isVideoAvailable() && mTvView.isFadedOut()) {
mTvView.fadeIn(mResources.getInteger(R.integer.tvview_fade_in_duration),
@@ -327,120 +305,6 @@ public class TvViewUiManager {
}
/**
- * Returns the current PIP layout. The layout should be one of
- * {@link TvSettings#PIP_LAYOUT_BOTTOM_RIGHT}, {@link TvSettings#PIP_LAYOUT_TOP_RIGHT},
- * {@link TvSettings#PIP_LAYOUT_TOP_LEFT}, {@link TvSettings#PIP_LAYOUT_BOTTOM_LEFT} and
- * {@link TvSettings#PIP_LAYOUT_SIDE_BY_SIDE}.
- */
- public int getPipLayout() {
- return mPipLayout;
- }
-
- /**
- * Sets the PIP layout. The layout should be one of
- * {@link TvSettings#PIP_LAYOUT_BOTTOM_RIGHT}, {@link TvSettings#PIP_LAYOUT_TOP_RIGHT},
- * {@link TvSettings#PIP_LAYOUT_TOP_LEFT}, {@link TvSettings#PIP_LAYOUT_BOTTOM_LEFT} and
- * {@link TvSettings#PIP_LAYOUT_SIDE_BY_SIDE}.
- *
- * @param storeInPreference if true, the stored value will be restored by
- * {@link #restorePipLayout()}.
- */
- public void setPipLayout(int pipLayout, boolean storeInPreference) {
- mPipLayout = pipLayout;
- if (storeInPreference) {
- TvSettings.setPipLayout(mContext, pipLayout);
- }
- updatePipView(mTvViewFrame);
- if (mPipLayout == TvSettings.PIP_LAYOUT_SIDE_BY_SIDE) {
- setTvViewMargin(mTvViewPapStartMargin, mTvViewPapEndMargin);
- setDisplayMode(DisplayMode.MODE_NORMAL, false, false);
- } else {
- setTvViewMargin(0, 0);
- restoreDisplayMode(false);
- }
- mTvOptionsManager.onPipLayoutChanged(pipLayout);
- }
-
- /**
- * Restores the PIP layout which {@link #setPipLayout} lastly stores.
- */
- public void restorePipLayout() {
- setPipLayout(TvSettings.getPipLayout(mContext), false);
- }
-
- /**
- * Called when PIP is started.
- */
- public void onPipStart() {
- mPipStarted = true;
- updatePipView();
- mPipView.setVisibility(View.VISIBLE);
- }
-
- /**
- * Called when PIP is stopped.
- */
- public void onPipStop() {
- setTvViewMargin(0, 0);
- mPipView.setVisibility(View.GONE);
- mPipStarted = false;
- }
-
- /**
- * Called when PIP is resumed.
- */
- public void showPipForResume() {
- mPipView.setVisibility(View.VISIBLE);
- }
-
- /**
- * Called when PIP is paused.
- */
- public void hidePipForPause() {
- if (mPipLayout != TvSettings.PIP_LAYOUT_SIDE_BY_SIDE) {
- mPipView.setVisibility(View.GONE);
- }
- }
-
- /**
- * Updates PIP view. It is usually called, when video resolution in PIP is updated.
- */
- public void updatePipView() {
- updatePipView(mTvViewFrame);
- }
-
- /**
- * Returns the size of the PIP view.
- */
- public int getPipSize() {
- return mPipSize;
- }
-
- /**
- * Sets PIP size and applies it immediately.
- *
- * @param pipSize PIP size. The value should be one of {@link TvSettings#PIP_SIZE_BIG}
- * and {@link TvSettings#PIP_SIZE_SMALL}.
- * @param storeInPreference if true, the stored value will be restored by
- * {@link #restorePipSize()}.
- */
- public void setPipSize(int pipSize, boolean storeInPreference) {
- mPipSize = pipSize;
- if (storeInPreference) {
- TvSettings.setPipSize(mContext, pipSize);
- }
- updatePipView(mTvViewFrame);
- mTvOptionsManager.onPipSizeChanged(pipSize);
- }
-
- /**
- * Restores the PIP size which {@link #setPipSize} lastly stores.
- */
- public void restorePipSize() {
- setPipSize(TvSettings.getPipSize(mContext), false);
- }
-
- /**
* This margins will be applied when applyDisplayMode is called.
*/
private void setTvViewMargin(int tvViewStartMargin, int tvViewEndMargin) {
@@ -488,14 +352,14 @@ public class TvViewUiManager {
}
private void setTvViewPosition(final FrameLayout.LayoutParams layoutParams,
- MarginLayoutParams tvViewFrame, boolean animate) {
+ FrameLayout.LayoutParams tvViewFrame, boolean animate) {
if (DEBUG) {
Log.d(TAG, "setTvViewPosition: w=" + layoutParams.width + " h=" + layoutParams.height
+ " s=" + layoutParams.getMarginStart() + " t=" + layoutParams.topMargin
+ " e=" + layoutParams.getMarginEnd() + " b=" + layoutParams.bottomMargin
+ " animate=" + animate);
}
- MarginLayoutParams oldTvViewFrame = mTvViewFrame;
+ FrameLayout.LayoutParams oldTvViewFrame = mTvViewFrame;
mTvViewLayoutParams = layoutParams;
mTvViewFrame = tvViewFrame;
if (animate) {
@@ -503,11 +367,11 @@ public class TvViewUiManager {
if (mTvViewAnimator.isStarted()) {
// Cancel the current animation and start new one.
mTvViewAnimator.cancel();
- mOldTvViewFrame = mLastAnimatedTvViewFrame;
+ mOldTvViewFrame = new FrameLayout.LayoutParams(mLastAnimatedTvViewFrame);
} else {
- mOldTvViewFrame = oldTvViewFrame;
+ mOldTvViewFrame = new FrameLayout.LayoutParams(oldTvViewFrame);
}
- mTvViewAnimator.setObjectValues(mTvView.getLayoutParams(), layoutParams);
+ mTvViewAnimator.setObjectValues(mTvView.getTvViewLayoutParams(), layoutParams);
mTvViewAnimator.setEvaluator(new TypeEvaluator<FrameLayout.LayoutParams>() {
FrameLayout.LayoutParams lp;
@Override
@@ -517,7 +381,7 @@ public class TvViewUiManager {
lp = new FrameLayout.LayoutParams(0, 0);
lp.gravity = startValue.gravity;
}
- interpolateMarginsRelative(lp, startValue, endValue, fraction);
+ interpolateMargins(lp, startValue, endValue, fraction);
return lp;
}
});
@@ -538,116 +402,10 @@ public class TvViewUiManager {
mHandler.removeMessages(MSG_SET_LAYOUT_PARAMS);
mHandler.obtainMessage(MSG_SET_LAYOUT_PARAMS, layoutParams).sendToTarget();
} else {
- mTvView.setLayoutParams(layoutParams);
- }
- updatePipView(mTvViewFrame);
- }
- }
-
- /**
- * The redlines assume that the ratio of the TV screen is 16:9. If the radio is not 16:9, the
- * layout of PAP can be broken.
- */
- @SuppressLint("RtlHardcoded")
- private void updatePipView(MarginLayoutParams tvViewFrame) {
- if (!mPipStarted) {
- return;
- }
- int width;
- int height;
- int startMargin;
- int endMargin;
- int topMargin;
- int bottomMargin;
- int gravity;
-
- if (mPipLayout == TvSettings.PIP_LAYOUT_SIDE_BY_SIDE) {
- gravity = Gravity.CENTER_VERTICAL | Gravity.START;
- height = tvViewFrame.height;
- float videoDisplayAspectRatio = mPipView.getVideoDisplayAspectRatio();
- if (videoDisplayAspectRatio <= 0f) {
- width = tvViewFrame.width;
- } else {
- width = (int) (height * videoDisplayAspectRatio);
- if (width > tvViewFrame.width) {
- width = tvViewFrame.width;
- }
- }
- startMargin = mResources.getDimensionPixelOffset(R.dimen.papview_margin_horizontal)
- * tvViewFrame.width / mTvViewPapWidth + (tvViewFrame.width - width) / 2;
- endMargin = 0;
- topMargin = 0;
- bottomMargin = 0;
- } else {
- int tvViewWidth = tvViewFrame.width;
- int tvViewHeight = tvViewFrame.height;
- int tvStartMargin = tvViewFrame.getMarginStart();
- int tvEndMargin = tvViewFrame.getMarginEnd();
- int tvTopMargin = tvViewFrame.topMargin;
- int tvBottomMargin = tvViewFrame.bottomMargin;
- float horizontalScaleFactor = (float) tvViewWidth / mWindowWidth;
- float verticalScaleFactor = (float) tvViewHeight / mWindowHeight;
-
- int maxWidth;
- if (mPipSize == TvSettings.PIP_SIZE_SMALL) {
- maxWidth = (int) (mResources.getDimensionPixelSize(R.dimen.pipview_small_size_width)
- * horizontalScaleFactor);
- height = (int) (mResources.getDimensionPixelSize(R.dimen.pipview_small_size_height)
- * verticalScaleFactor);
- } else if (mPipSize == TvSettings.PIP_SIZE_BIG) {
- maxWidth = (int) (mResources.getDimensionPixelSize(R.dimen.pipview_large_size_width)
- * horizontalScaleFactor);
- height = (int) (mResources.getDimensionPixelSize(R.dimen.pipview_large_size_height)
- * verticalScaleFactor);
- } else {
- throw new IllegalArgumentException("Invalid PIP size: " + mPipSize);
- }
- float videoDisplayAspectRatio = mPipView.getVideoDisplayAspectRatio();
- if (videoDisplayAspectRatio <= 0f) {
- width = maxWidth;
- } else {
- width = (int) (height * videoDisplayAspectRatio);
- if (width > maxWidth) {
- width = maxWidth;
- }
- }
-
- startMargin = tvStartMargin + (int) (mPipViewHorizontalMargin * horizontalScaleFactor);
- endMargin = tvEndMargin + (int) (mPipViewHorizontalMargin * horizontalScaleFactor);
- topMargin = tvTopMargin + (int) (mPipViewTopMargin * verticalScaleFactor);
- bottomMargin = tvBottomMargin + (int) (mPipViewBottomMargin * verticalScaleFactor);
-
- switch (mPipLayout) {
- case TvSettings.PIP_LAYOUT_TOP_LEFT:
- gravity = Gravity.TOP | Gravity.LEFT;
- break;
- case TvSettings.PIP_LAYOUT_TOP_RIGHT:
- gravity = Gravity.TOP | Gravity.RIGHT;
- break;
- case TvSettings.PIP_LAYOUT_BOTTOM_LEFT:
- gravity = Gravity.BOTTOM | Gravity.LEFT;
- break;
- case TvSettings.PIP_LAYOUT_BOTTOM_RIGHT:
- gravity = Gravity.BOTTOM | Gravity.RIGHT;
- break;
- default:
- throw new IllegalArgumentException("Invalid PIP location: " + mPipLayout);
+ mTvView.setTvViewLayoutParams(layoutParams);
+ mTvView.setLayoutParams(mTvViewFrame);
}
}
-
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mPipView.getLayoutParams();
- if (lp.width != width || lp.height != height || lp.getMarginStart() != startMargin
- || lp.getMarginEnd() != endMargin || lp.topMargin != topMargin
- || lp.bottomMargin != bottomMargin || lp.gravity != gravity) {
- lp.width = width;
- lp.height = height;
- lp.setMarginStart(startMargin);
- lp.setMarginEnd(endMargin);
- lp.topMargin = topMargin;
- lp.bottomMargin = bottomMargin;
- lp.gravity = gravity;
- mPipView.setLayoutParams(lp);
- }
}
private void initTvAnimatorIfNeeded() {
@@ -663,7 +421,7 @@ public class TvViewUiManager {
// because TvView may request layout itself during animation and layout SurfaceView with
// its own parameters when TvInputService requests to do so.
mTvViewAnimator = new ObjectAnimator();
- mTvViewAnimator.setTarget(mTvView);
+ mTvViewAnimator.setTarget(mTvView.getTvView());
mTvViewAnimator.setProperty(
Property.of(FrameLayout.class, ViewGroup.LayoutParams.class, "layoutParams"));
mTvViewAnimator.setDuration(mResources.getInteger(R.integer.tvview_anim_duration));
@@ -693,10 +451,10 @@ public class TvViewUiManager {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
float fraction = animator.getAnimatedFraction();
- mLastAnimatedTvViewFrame = new MarginLayoutParams(0, 0);
- interpolateMarginsRelative(mLastAnimatedTvViewFrame,
+ mLastAnimatedTvViewFrame = (FrameLayout.LayoutParams) mTvView.getLayoutParams();
+ interpolateMargins(mLastAnimatedTvViewFrame,
mOldTvViewFrame, mTvViewFrame, fraction);
- updatePipView(mLastAnimatedTvViewFrame);
+ mTvView.setLayoutParams(mLastAnimatedTvViewFrame);
}
});
}
@@ -745,66 +503,58 @@ public class TvViewUiManager {
}
int availableAreaWidth = mWindowWidth - mTvViewStartMargin - mTvViewEndMargin;
int availableAreaHeight = availableAreaWidth * mWindowHeight / mWindowWidth;
- FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(0, 0,
- ((FrameLayout.LayoutParams) mTvView.getLayoutParams()).gravity);
int displayMode = mDisplayMode;
- double availableAreaRatio = 0;
- double videoRatio = 0;
+ float availableAreaRatio = 0;
if (availableAreaWidth <= 0 || availableAreaHeight <= 0) {
displayMode = DisplayMode.MODE_FULL;
Log.w(TAG, "Some resolution info is missing during applyDisplayMode. ("
+ "availableAreaWidth=" + availableAreaWidth + ", availableAreaHeight="
+ availableAreaHeight + ")");
} else {
- availableAreaRatio = (double) availableAreaWidth / availableAreaHeight;
- videoRatio = videoDisplayAspectRatio;
+ availableAreaRatio = (float) availableAreaWidth / availableAreaHeight;
}
-
- int tvViewFrameTop = (mWindowHeight - availableAreaHeight) / 2;
- MarginLayoutParams tvViewFrame = createMarginLayoutParams(
- mTvViewStartMargin, mTvViewEndMargin, tvViewFrameTop, tvViewFrameTop);
- layoutParams.width = availableAreaWidth;
- layoutParams.height = availableAreaHeight;
+ FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(0, 0,
+ ((FrameLayout.LayoutParams) mTvView.getTvViewLayoutParams()).gravity);
switch (displayMode) {
- case DisplayMode.MODE_FULL:
- layoutParams.width = availableAreaWidth;
- layoutParams.height = availableAreaHeight;
- break;
case DisplayMode.MODE_ZOOM:
- if (videoRatio < availableAreaRatio) {
+ if (videoDisplayAspectRatio < availableAreaRatio) {
// Y axis will be clipped.
layoutParams.width = availableAreaWidth;
- layoutParams.height = (int) Math.round(availableAreaWidth / videoRatio);
+ layoutParams.height = Math.round(availableAreaWidth / videoDisplayAspectRatio);
} else {
// X axis will be clipped.
- layoutParams.width = (int) Math.round(availableAreaHeight * videoRatio);
+ layoutParams.width = Math.round(availableAreaHeight * videoDisplayAspectRatio);
layoutParams.height = availableAreaHeight;
}
break;
case DisplayMode.MODE_NORMAL:
- if (videoRatio < availableAreaRatio) {
+ if (videoDisplayAspectRatio < availableAreaRatio) {
// X axis has black area.
- layoutParams.width = (int) Math.round(availableAreaHeight * videoRatio);
+ layoutParams.width = Math.round(availableAreaHeight * videoDisplayAspectRatio);
layoutParams.height = availableAreaHeight;
} else {
// Y axis has black area.
layoutParams.width = availableAreaWidth;
- layoutParams.height = (int) Math.round(availableAreaWidth / videoRatio);
+ layoutParams.height = Math.round(availableAreaWidth / videoDisplayAspectRatio);
}
break;
+ case DisplayMode.MODE_FULL:
+ default:
+ layoutParams.width = availableAreaWidth;
+ layoutParams.height = availableAreaHeight;
+ break;
}
-
// FrameLayout has an issue with centering when left and right margins differ.
// So stick to Gravity.START | Gravity.CENTER_VERTICAL.
- int marginStart = mTvViewStartMargin + (availableAreaWidth - layoutParams.width) / 2;
+ int marginStart = (availableAreaWidth - layoutParams.width) / 2;
layoutParams.setMarginStart(marginStart);
- // Set marginEnd as well because setTvViewPosition uses both start/end margin.
- layoutParams.setMarginEnd(mWindowWidth - layoutParams.width - marginStart);
-
+ int tvViewFrameTop = (mWindowHeight - availableAreaHeight) / 2;
+ FrameLayout.LayoutParams tvViewFrame = createMarginLayoutParams(
+ mTvViewStartMargin, mTvViewEndMargin, tvViewFrameTop, tvViewFrameTop);
+ setTvViewPosition(layoutParams, tvViewFrame, animate);
setBackgroundColor(mResources.getColor(isTvViewFullScreen()
? R.color.tvactivity_background : R.color.tvactivity_background_on_shrunken_tvview,
- null), layoutParams, animate);
- setTvViewPosition(layoutParams, tvViewFrame, animate);
+ null), layoutParams, animate);
// Update the current display mode.
mTvOptionsManager.onDisplayModeChanged(displayMode);
@@ -814,7 +564,7 @@ public class TvViewUiManager {
return (int) (start + (end - start) * fraction);
}
- private static void interpolateMarginsRelative(MarginLayoutParams out,
+ private static void interpolateMargins(MarginLayoutParams out,
MarginLayoutParams startValue, MarginLayoutParams endValue, float fraction) {
out.topMargin = interpolate(startValue.topMargin, endValue.topMargin, fraction);
out.bottomMargin = interpolate(startValue.bottomMargin, endValue.bottomMargin, fraction);
@@ -825,9 +575,9 @@ public class TvViewUiManager {
out.height = interpolate(startValue.height, endValue.height, fraction);
}
- private MarginLayoutParams createMarginLayoutParams(
+ private FrameLayout.LayoutParams createMarginLayoutParams(
int startMargin, int endMargin, int topMargin, int bottomMargin) {
- MarginLayoutParams lp = new MarginLayoutParams(0, 0);
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(0, 0);
lp.setMarginStart(startMargin);
lp.setMarginEnd(endMargin);
lp.topMargin = topMargin;
@@ -836,4 +586,4 @@ public class TvViewUiManager {
lp.height = mWindowHeight - topMargin - bottomMargin;
return lp;
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/ui/sidepanel/ActionItem.java b/src/com/android/tv/ui/sidepanel/ActionItem.java
index 23aff91c..cd70a886 100644
--- a/src/com/android/tv/ui/sidepanel/ActionItem.java
+++ b/src/com/android/tv/ui/sidepanel/ActionItem.java
@@ -17,7 +17,6 @@
package com.android.tv.ui.sidepanel;
import android.view.View;
-import android.widget.ImageView;
import android.widget.TextView;
import com.android.tv.R;
@@ -25,24 +24,14 @@ import com.android.tv.R;
public abstract class ActionItem extends Item {
private final String mTitle;
private final String mDescription;
- private final int mIconId;
public ActionItem(String title) {
- this(title, null, 0);
+ this(title, null);
}
public ActionItem(String title, String description) {
- this(title, description, 0);
- }
-
- public ActionItem(String title, int iconId) {
- this(title, null, iconId);
- }
-
- public ActionItem(String title, String description, int iconId) {
mTitle = title;
mDescription = description;
- mIconId = iconId;
}
@Override
@@ -62,12 +51,5 @@ public abstract class ActionItem extends Item {
} else {
descriptionView.setVisibility(View.GONE);
}
- ImageView iconView = (ImageView) view.findViewById(R.id.icon);
- if (mIconId != 0) {
- iconView.setVisibility(View.VISIBLE);
- iconView.setImageResource(mIconId);
- } else {
- iconView.setVisibility(View.GONE);
- }
}
} \ No newline at end of file
diff --git a/src/com/android/tv/ui/sidepanel/ClosedCaptionFragment.java b/src/com/android/tv/ui/sidepanel/ClosedCaptionFragment.java
index d6ccdf6b..341e4350 100644
--- a/src/com/android/tv/ui/sidepanel/ClosedCaptionFragment.java
+++ b/src/com/android/tv/ui/sidepanel/ClosedCaptionFragment.java
@@ -18,6 +18,7 @@ package com.android.tv.ui.sidepanel;
import android.media.tv.TvTrackInfo;
import android.os.Bundle;
+import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -25,7 +26,6 @@ import android.view.ViewGroup;
import com.android.tv.R;
import com.android.tv.util.CaptionSettings;
-import com.android.tv.util.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -38,8 +38,6 @@ public class ClosedCaptionFragment extends SideFragment {
private String mClosedCaptionLanguage;
private String mClosedCaptionTrackId;
private ClosedCaptionOptionItem mSelectedItem;
- private List<Item> mItems;
- private boolean mPaused;
public ClosedCaptionFragment() {
super(KeyEvent.KEYCODE_CAPTIONS, KeyEvent.KEYCODE_S);
@@ -63,37 +61,32 @@ public class ClosedCaptionFragment extends SideFragment {
mClosedCaptionLanguage = captionSettings.getLanguage();
mClosedCaptionTrackId = captionSettings.getTrackId();
- mItems = new ArrayList<>();
+ List<Item> items = new ArrayList<>();
mSelectedItem = null;
List<TvTrackInfo> tracks = getMainActivity().getTracks(TvTrackInfo.TYPE_SUBTITLE);
if (tracks != null && !tracks.isEmpty()) {
- String trackId = captionSettings.isEnabled() ?
+ String selectedTrackId = captionSettings.isEnabled() ?
getMainActivity().getSelectedTrack(TvTrackInfo.TYPE_SUBTITLE) : null;
- boolean isEnabled = trackId != null;
-
- ClosedCaptionOptionItem item = new ClosedCaptionOptionItem(
- getString(R.string.closed_caption_option_item_off),
- CaptionSettings.OPTION_OFF, null, null);
- // Pick 'Off' as default because we may fail to find the matching language.
- mSelectedItem = item;
- if (!isEnabled) {
+ ClosedCaptionOptionItem item = new ClosedCaptionOptionItem(null, null);
+ items.add(item);
+ if (selectedTrackId == null) {
+ mSelectedItem = item;
item.setChecked(true);
+ setSelectedPosition(0);
}
- mItems.add(item);
-
- for (final TvTrackInfo track : tracks) {
- item = new ClosedCaptionOptionItem(getLabel(track),
- CaptionSettings.OPTION_ON, track.getId(), track.getLanguage());
- if (isEnabled && track.getId().equals(trackId)) {
- item.setChecked(true);
+ for (int i = 0; i < tracks.size(); i++) {
+ item = new ClosedCaptionOptionItem(tracks.get(i), i);
+ if (TextUtils.equals(selectedTrackId, tracks.get(i).getId())) {
mSelectedItem = item;
+ item.setChecked(true);
+ setSelectedPosition(i + 1);
}
- mItems.add(item);
+ items.add(item);
}
}
if (getMainActivity().hasCaptioningSettingsActivity()) {
- mItems.add(new ActionItem(getString(R.string.closed_caption_system_settings),
+ items.add(new ActionItem(getString(R.string.closed_caption_system_settings),
getString(R.string.closed_caption_system_settings_description)) {
@Override
protected void onSelected() {
@@ -103,14 +96,14 @@ public class ClosedCaptionFragment extends SideFragment {
@Override
protected void onFocused() {
super.onFocused();
- if (!mPaused && mSelectedItem != null) {
+ if (mSelectedItem != null) {
getMainActivity().selectSubtitleTrack(
mSelectedItem.mOption, mSelectedItem.mTrackId);
}
}
});
}
- return mItems;
+ return items;
}
@Override
@@ -120,50 +113,6 @@ public class ClosedCaptionFragment extends SideFragment {
}
@Override
- public void onResume() {
- super.onResume();
- if (mPaused) {
- // Apply system's closed caption settings to the UI.
- CaptionSettings captionSettings = getMainActivity().getCaptionSettings();
- mClosedCaptionOption = CaptionSettings.OPTION_SYSTEM;
- mClosedCaptionLanguage = captionSettings.getSystemLanguage();
- ClosedCaptionOptionItem selectedItem = null;
- if (captionSettings.isSystemSettingEnabled()) {
- for (Item item : mItems) {
- if (!(item instanceof ClosedCaptionOptionItem)) {
- continue;
- }
- ClosedCaptionOptionItem captionItem = (ClosedCaptionOptionItem) item;
- if (Utils.isEqualLanguage(captionItem.mLanguage, mClosedCaptionLanguage)) {
- selectedItem = captionItem;
- break;
- }
- }
- }
- if (mSelectedItem != null) {
- mSelectedItem.setChecked(false);
- }
- if (selectedItem == null && mItems.get(0) instanceof ClosedCaptionOptionItem) {
- selectedItem = (ClosedCaptionOptionItem) mItems.get(0);
- }
- if (selectedItem != null) {
- selectedItem.setChecked(true);
- }
- // We shouldn't call MainActivity.selectSubtitleTrack() here because
- // 1. Tracks are not available because video is just started at this moment.
- // 2. MainActivity will apply system settings when video's tracks are available.
- mSelectedItem = selectedItem;
- }
- mPaused = false;
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mPaused = true;
- }
-
- @Override
public void onDestroyView() {
if (mResetClosedCaption) {
getMainActivity().selectSubtitleLanguage(mClosedCaptionOption, mClosedCaptionLanguage,
@@ -172,23 +121,28 @@ public class ClosedCaptionFragment extends SideFragment {
super.onDestroyView();
}
- private String getLabel(TvTrackInfo track) {
- if (track.getLanguage() != null) {
+ private String getLabel(TvTrackInfo track, Integer trackIndex) {
+ if (track == null) {
+ return getString(R.string.closed_caption_option_item_off);
+ } else if (track.getLanguage() != null) {
return new Locale(track.getLanguage()).getDisplayName();
}
- return getString(R.string.default_language);
+ return getString(R.string.closed_caption_unknown_language, trackIndex + 1);
}
private class ClosedCaptionOptionItem extends RadioButtonItem {
private final int mOption;
private final String mTrackId;
- private final String mLanguage;
- private ClosedCaptionOptionItem(String title, int option, String trackId, String language) {
- super(title);
- mOption = option;
- mTrackId = trackId;
- mLanguage = language;
+ private ClosedCaptionOptionItem(TvTrackInfo track, Integer trackIndex) {
+ super(getLabel(track, trackIndex));
+ if (track == null) {
+ mOption = CaptionSettings.OPTION_OFF;
+ mTrackId = null;
+ } else {
+ mOption = CaptionSettings.OPTION_ON;
+ mTrackId = track.getId();
+ }
}
@Override
diff --git a/src/com/android/tv/ui/sidepanel/CompoundButtonItem.java b/src/com/android/tv/ui/sidepanel/CompoundButtonItem.java
index 7613a9a2..c2746937 100644
--- a/src/com/android/tv/ui/sidepanel/CompoundButtonItem.java
+++ b/src/com/android/tv/ui/sidepanel/CompoundButtonItem.java
@@ -23,9 +23,12 @@ import android.widget.TextView;
import com.android.tv.R;
public abstract class CompoundButtonItem extends Item {
+ private static int sDefaultMaxLine = 0;
+
private final String mCheckedTitle;
private final String mUncheckedTitle;
private final String mDescription;
+ private final int mMaxLine;
private boolean mChecked;
private TextView mTextView;
private CompoundButton mCompoundButton;
@@ -38,6 +41,15 @@ public abstract class CompoundButtonItem extends Item {
mCheckedTitle = checkedTitle;
mUncheckedTitle = uncheckedTitle;
mDescription = description;
+ mMaxLine = 0;
+ }
+
+ public CompoundButtonItem(String checkedTitle, String uncheckedTitle, String description,
+ int maxLine) {
+ mCheckedTitle = checkedTitle;
+ mUncheckedTitle = uncheckedTitle;
+ mDescription = description;
+ mMaxLine = maxLine;
}
protected abstract int getCompoundButtonId();
@@ -57,6 +69,15 @@ public abstract class CompoundButtonItem extends Item {
mTextView = (TextView) view.findViewById(getTitleViewId());
TextView descriptionView = (TextView) view.findViewById(getDescriptionViewId());
if (mDescription != null) {
+ if (mMaxLine != 0) {
+ descriptionView.setMaxLines(mMaxLine);
+ } else {
+ if (sDefaultMaxLine == 0) {
+ sDefaultMaxLine = view.getContext().getResources()
+ .getInteger(R.integer.option_item_description_max_lines);
+ }
+ descriptionView.setMaxLines(sDefaultMaxLine);
+ }
descriptionView.setVisibility(View.VISIBLE);
descriptionView.setText(mDescription);
} else {
diff --git a/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java b/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java
index 9cc54ed2..297e69d9 100644
--- a/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java
+++ b/src/com/android/tv/ui/sidepanel/CustomizeChannelListFragment.java
@@ -16,6 +16,8 @@
package com.android.tv.ui.sidepanel;
+import android.content.Context;
+import android.content.SharedPreferences;
import android.media.tv.TvContract.Channels;
import android.os.Bundle;
import android.support.v17.leanback.widget.VerticalGridView;
@@ -27,6 +29,7 @@ import android.widget.TextView;
import com.android.tv.MainActivity;
import com.android.tv.R;
+import com.android.tv.common.SharedPreferencesUtils;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelNumber;
import com.android.tv.ui.OnRepeatedKeyInterceptListener;
@@ -36,39 +39,38 @@ import com.android.tv.util.Utils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.List;
import java.util.Iterator;
+import java.util.List;
public class CustomizeChannelListFragment extends SideFragment {
private static final int GROUP_BY_SOURCE = 0;
private static final int GROUP_BY_HD_SD = 1;
private static final String TRACKER_LABEL = "customize channel list";
- private final List<Channel> mChannels = new ArrayList<>();
- private final long mInitialChannelId;
+ private static final String PREF_KEY_GROUP_SETTINGS = "pref_key_group_settigns";
+ private final List<Channel> mChannels = new ArrayList<>();
+ private long mInitialChannelId = Channel.INVALID_ID;
private long mLastFocusedChannelId = Channel.INVALID_ID;
- private int mGroupingType = GROUP_BY_SOURCE;
+ private static Integer sGroupingType;
private TvInputManagerHelper mInputManager;
private Channel.DefaultComparator mChannelComparator;
private boolean mGroupByFragmentRunning;
private final List<Item> mItems = new ArrayList<>();
- public CustomizeChannelListFragment() {
- this(Channel.INVALID_ID);
- }
-
- public CustomizeChannelListFragment(long initialChannelId) {
- mInitialChannelId = initialChannelId;
- }
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mInputManager = getMainActivity().getTvInputManagerHelper();
+ mInitialChannelId = getMainActivity().getCurrentChannelId();
mChannelComparator = new Channel.DefaultComparator(getActivity(), mInputManager);
+ if (sGroupingType == null) {
+ SharedPreferences sharedPreferences = getContext().getSharedPreferences(
+ SharedPreferencesUtils.SHARED_PREF_UI_SETTINGS, Context.MODE_PRIVATE);
+ sGroupingType = sharedPreferences.getInt(PREF_KEY_GROUP_SETTINGS, GROUP_BY_SOURCE);
+ }
}
@Override
@@ -128,13 +130,16 @@ public class CustomizeChannelListFragment extends SideFragment {
@Override
public void onDestroyView() {
getChannelDataManager().applyUpdatedValuesToDb();
- if (!mGroupByFragmentRunning) {
- getMainActivity().endShrunkenTvView();
- }
super.onDestroyView();
}
@Override
+ public void onDestroy() {
+ super.onDestroy();
+ getMainActivity().endShrunkenTvView();
+ }
+
+ @Override
protected String getTitle() {
return getString(R.string.side_panel_title_edit_channels_for_an_input);
}
@@ -149,7 +154,7 @@ public class CustomizeChannelListFragment extends SideFragment {
mItems.clear();
mChannels.clear();
mChannels.addAll(getChannelDataManager().getChannelList());
- if (mGroupingType == GROUP_BY_SOURCE) {
+ if (sGroupingType == GROUP_BY_SOURCE) {
addItemForGroupBySource(mItems);
} else {
// GROUP_BY_HD_SD
@@ -321,6 +326,49 @@ public class CustomizeChannelListFragment extends SideFragment {
}
}
+ public static class GroupByFragment extends SideFragment {
+ @Override
+ protected String getTitle() {
+ return getString(R.string.side_panel_title_group_by);
+ }
+ @Override
+ public String getTrackerLabel() {
+ return GroupBySubMenu.TRACKER_LABEL;
+ }
+
+ @Override
+ protected List<Item> getItemList() {
+ List<Item> items = new ArrayList<>();
+ items.add(new RadioButtonItem(
+ getString(R.string.edit_channels_group_by_sources)) {
+ @Override
+ protected void onSelected() {
+ super.onSelected();
+ setGroupingType(GROUP_BY_SOURCE);
+ closeFragment();
+ }
+ });
+ items.add(new RadioButtonItem(
+ getString(R.string.edit_channels_group_by_hd_sd)) {
+ @Override
+ protected void onSelected() {
+ super.onSelected();
+ setGroupingType(GROUP_BY_HD_SD);
+ closeFragment();
+ }
+ });
+ ((RadioButtonItem) items.get(sGroupingType)).setChecked(true);
+ return items;
+ }
+
+ private void setGroupingType(int groupingType) {
+ sGroupingType = groupingType;
+ SharedPreferences sharedPreferences = getContext().getSharedPreferences(
+ SharedPreferencesUtils.SHARED_PREF_UI_SETTINGS, Context.MODE_PRIVATE);
+ sharedPreferences.edit().putInt(PREF_KEY_GROUP_SETTINGS, groupingType).apply();
+ }
+ }
+
private class GroupBySubMenu extends SubMenuItem {
private static final String TRACKER_LABEL = "Group by";
public GroupBySubMenu(String description) {
@@ -330,41 +378,7 @@ public class CustomizeChannelListFragment extends SideFragment {
@Override
protected SideFragment getFragment() {
- return new SideFragment() {
- @Override
- protected String getTitle() {
- return getString(R.string.side_panel_title_group_by);
- }
- @Override
- public String getTrackerLabel() {
- return GroupBySubMenu.TRACKER_LABEL;
- }
-
- @Override
- protected List<Item> getItemList() {
- List<Item> items = new ArrayList<>();
- items.add(new RadioButtonItem(
- getString(R.string.edit_channels_group_by_sources)) {
- @Override
- protected void onSelected() {
- super.onSelected();
- mGroupingType = GROUP_BY_SOURCE;
- closeFragment();
- }
- });
- items.add(new RadioButtonItem(
- getString(R.string.edit_channels_group_by_hd_sd)) {
- @Override
- protected void onSelected() {
- super.onSelected();
- mGroupingType = GROUP_BY_HD_SD;
- closeFragment();
- }
- });
- ((RadioButtonItem) items.get(mGroupingType)).setChecked(true);
- return items;
- }
- };
+ return new GroupByFragment();
}
@Override
diff --git a/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java b/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
index 0d189cca..f633fa5a 100644
--- a/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
+++ b/src/com/android/tv/ui/sidepanel/DeveloperOptionFragment.java
@@ -18,8 +18,6 @@ package com.android.tv.ui.sidepanel;
import android.accounts.Account;
import android.app.Activity;
-import android.app.ApplicationErrorReport;
-import android.content.Intent;
import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.Toast;
@@ -27,9 +25,11 @@ import android.widget.Toast;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.common.BuildConfig;
+import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.epg.EpgFetcher;
import com.android.tv.experiments.Experiments;
import com.android.tv.tuner.TunerPreferences;
+import com.android.tv.util.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -54,7 +54,15 @@ public class DeveloperOptionFragment extends SideFragment {
@Override
protected List<Item> getItemList() {
List<Item> items = new ArrayList<>();
- if (BuildConfig.ENG) {
+ if (CommonFeatures.DVR.isEnabled(getContext())) {
+ items.add(new ActionItem(getString(R.string.dev_item_dvr_history)) {
+ @Override
+ protected void onSelected() {
+ getMainActivity().getOverlayManager().showDvrHistoryDialog();
+ }
+ });
+ }
+ if (Utils.isDeveloper()) {
items.add(new ActionItem(getString(R.string.dev_item_watch_history)) {
@Override
protected void onSelected() {
@@ -62,18 +70,6 @@ public class DeveloperOptionFragment extends SideFragment {
}
});
}
- items.add(new ActionItem(getString(R.string.dev_item_send_feedback)) {
- @Override
- protected void onSelected() {
- Intent intent = new Intent(Intent.ACTION_APP_ERROR);
- ApplicationErrorReport report = new ApplicationErrorReport();
- report.packageName = report.processName = getContext().getPackageName();
- report.time = System.currentTimeMillis();
- report.type = ApplicationErrorReport.TYPE_NONE;
- intent.putExtra(Intent.EXTRA_BUG_REPORT, report);
- startActivityForResult(intent, 0);
- }
- });
items.add(new SwitchItem(getString(R.string.dev_item_store_ts_on),
getString(R.string.dev_item_store_ts_off),
getString(R.string.dev_item_store_ts_description)) {
@@ -89,13 +85,18 @@ public class DeveloperOptionFragment extends SideFragment {
TunerPreferences.setStoreTsStream(getContext(), isChecked());
}
});
+ if (Utils.isDeveloper()) {
+ items.add(
+ new ActionItem(getString(R.string.dev_item_show_performance_monitor_log)) {
+ @Override
+ protected void onSelected() {
+ TvApplication.getSingletons(getContext())
+ .getPerformanceMonitor()
+ .startPerformanceMonitorEventDebugActivity(getContext());
+ }
+ });
+ }
return items;
}
-
- /** True if there is the dev options menu */
- public static boolean shouldShow() {
- return Experiments.ENABLE_DEVELOPER_FEATURES.get() || BuildConfig.ENG;
- }
-
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/ui/sidepanel/Item.java b/src/com/android/tv/ui/sidepanel/Item.java
index 00f16427..4e47e75b 100644
--- a/src/com/android/tv/ui/sidepanel/Item.java
+++ b/src/com/android/tv/ui/sidepanel/Item.java
@@ -24,6 +24,7 @@ import android.view.ViewGroup;
public abstract class Item {
private View mItemView;
private boolean mEnabled = true;
+ private boolean mClickable = true;
public void setEnabled(boolean enabled) {
if (mEnabled != enabled) {
@@ -35,6 +36,16 @@ public abstract class Item {
}
/**
+ * Sets the item to be clickable or not.
+ */
+ public void setClickable(boolean clickable) {
+ mClickable = clickable;
+ if (mItemView != null) {
+ mItemView.setClickable(clickable);
+ }
+ }
+
+ /**
* Returns whether this item is enabled.
*/
public boolean isEnabled() {
@@ -64,6 +75,7 @@ public abstract class Item {
*/
protected void onUpdate() {
setEnabledInternal(mItemView, mEnabled);
+ mItemView.setClickable(mClickable);
}
protected abstract void onSelected();
diff --git a/src/com/android/tv/ui/sidepanel/PipInputSelectorFragment.java b/src/com/android/tv/ui/sidepanel/PipInputSelectorFragment.java
deleted file mode 100644
index dec017a8..00000000
--- a/src/com/android/tv/ui/sidepanel/PipInputSelectorFragment.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.ui.sidepanel;
-
-import android.media.tv.TvInputInfo;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.tv.R;
-import com.android.tv.util.PipInputManager;
-import com.android.tv.util.PipInputManager.PipInput;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-public class PipInputSelectorFragment extends SideFragment {
- private static final String TAG = "PipInputSelector";
- private static final String TRACKER_LABEL = "PIP input source";
-
- private final List<Item> mInputItems = new ArrayList<>();
- private PipInputManager mPipInputManager;
- private PipInput mInitialPipInput;
- private boolean mSelected;
-
- private final PipInputManager.Listener mPipInputListener = new PipInputManager.Listener() {
- @Override
- public void onPipInputStateUpdated() {
- notifyDataSetChanged();
- }
-
- @Override
- public void onPipInputListUpdated() {
- refreshInputList();
- setItems(mInputItems);
- }
- };
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- mPipInputManager = getMainActivity().getPipInputManager();
- mPipInputManager.addListener(mPipInputListener);
- getMainActivity().startShrunkenTvView(false, false);
- return super.onCreateView(inflater, container, savedInstanceState);
- }
-
- @Override
- public void onStart() {
- super.onStart();
- mInitialPipInput = mPipInputManager.getPipInput(getMainActivity().getPipChannel());
- if (mInitialPipInput == null) {
- Log.w(TAG, "PIP should be on");
- closeFragment();
- }
- int count = 0;
- for (Item item : mInputItems) {
- InputItem inputItem = (InputItem) item;
- if (Objects.equals(inputItem.mPipInput, mInitialPipInput)) {
- setSelectedPosition(count);
- break;
- }
- ++count;
- }
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- mPipInputManager.removeListener(mPipInputListener);
- if (!mSelected) {
- getMainActivity().tuneToChannelForPip(mInitialPipInput.getChannel());
- }
- getMainActivity().endShrunkenTvView();
- }
-
- @Override
- protected String getTitle() {
- return getString(R.string.side_panel_title_pip_input_source);
- }
-
- @Override
- public String getTrackerLabel() {
- return TRACKER_LABEL;
- }
-
- @Override
- protected List<Item> getItemList() {
- refreshInputList();
- return mInputItems;
- }
-
- private void refreshInputList() {
- mInputItems.clear();
- for (PipInput input : mPipInputManager.getPipInputList(false)) {
- mInputItems.add(new InputItem(input));
- }
- }
-
- private class InputItem extends RadioButtonItem {
- private final PipInput mPipInput;
-
- private InputItem(PipInput input) {
- super(input.getLongLabel());
- mPipInput = input;
- setEnabled(isAvailable());
- }
-
- @Override
- protected void onUpdate() {
- super.onUpdate();
- setEnabled(mPipInput.isAvailable());
- setChecked(mPipInput == mInitialPipInput);
- }
-
- @Override
- protected void onFocused() {
- super.onFocused();
- if (isEnabled()) {
- getMainActivity().tuneToChannelForPip(mPipInput.getChannel());
- }
- }
-
- @Override
- protected void onSelected() {
- super.onSelected();
- if (isEnabled()) {
- mSelected = true;
- closeFragment();
- }
- }
-
- private boolean isAvailable() {
- if (!mPipInput.isAvailable()) {
- return false;
- }
-
- // If this input shares the same parent with the current main input, you cannot select
- // it. (E.g. two HDMI CEC devices that are connected to HDMI port 1 through an A/V
- // receiver.)
- PipInput pipInput = mPipInputManager.getPipInput(getMainActivity().getCurrentChannel());
- if (pipInput == null) {
- return false;
- }
- TvInputInfo mainInputInfo = pipInput.getInputInfo();
- TvInputInfo pipInputInfo = mPipInput.getInputInfo();
- return mainInputInfo == null || pipInputInfo == null
- || !TextUtils.equals(mainInputInfo.getId(), pipInputInfo.getId())
- && !TextUtils.equals(mainInputInfo.getParentId(), pipInputInfo.getParentId());
- }
- }
-}
diff --git a/src/com/android/tv/ui/sidepanel/SettingsFragment.java b/src/com/android/tv/ui/sidepanel/SettingsFragment.java
index e8033a22..6a5b510c 100644
--- a/src/com/android/tv/ui/sidepanel/SettingsFragment.java
+++ b/src/com/android/tv/ui/sidepanel/SettingsFragment.java
@@ -16,18 +16,25 @@
package com.android.tv.ui.sidepanel;
+import static com.android.tv.Features.TUNER;
+
+import android.app.ApplicationErrorReport;
+import android.content.Intent;
+import android.media.tv.TvInputInfo;
import android.view.View;
import android.widget.Toast;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvApplication;
+import com.android.tv.customization.TvCustomizationManager;
import com.android.tv.dialog.PinDialogFragment;
-import com.android.tv.dialog.WebDialogFragment;
-import com.android.tv.license.LicenseUtils;
-import com.android.tv.ui.sidepanel.parentalcontrols.ParentalControlsFragment;
+import com.android.tv.license.LicenseSideFragment;
+import com.android.tv.license.Licenses;
+import com.android.tv.tuner.TunerPreferences;
import com.android.tv.util.PermissionUtils;
import com.android.tv.util.SetupUtils;
+import com.android.tv.util.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -38,33 +45,6 @@ import java.util.List;
public class SettingsFragment extends SideFragment {
private static final String TRACKER_LABEL = "settings";
- private final long mCurrentChannelId;
-
- public SettingsFragment(long currentChannelId) {
- mCurrentChannelId = currentChannelId;
- }
-
- /**
- * Opens a dialog showing open source licenses.
- */
- public static final class LicenseActionItem extends ActionItem {
- public final static String DIALOG_TAG = LicenseActionItem.class.getSimpleName();
- public static final String TRACKER_LABEL = "Open Source Licenses";
- private final MainActivity mMainActivity;
-
- public LicenseActionItem(MainActivity mainActivity) {
- super(mainActivity.getString(R.string.settings_menu_licenses));
- mMainActivity = mainActivity;
- }
-
- @Override
- protected void onSelected() {
- WebDialogFragment dialog = WebDialogFragment.newInstance(LicenseUtils.LICENSE_FILE,
- mMainActivity.getString(R.string.dialog_title_licenses), TRACKER_LABEL);
- mMainActivity.getOverlayManager().showDialogFragment(DIALOG_TAG, dialog, false);
- }
- }
-
@Override
protected String getTitle() {
return getResources().getString(R.string.side_panel_title_settings);
@@ -80,11 +60,11 @@ public class SettingsFragment extends SideFragment {
List<Item> items = new ArrayList<>();
final Item customizeChannelListItem = new SubMenuItem(
getString(R.string.settings_channel_source_item_customize_channels),
- getString(R.string.settings_channel_source_item_customize_channels_description), 0,
+ getString(R.string.settings_channel_source_item_customize_channels_description),
getMainActivity().getOverlayManager().getSideFragmentManager()) {
@Override
protected SideFragment getFragment() {
- return new CustomizeChannelListFragment(mCurrentChannelId);
+ return new CustomizeChannelListFragment();
}
@Override
@@ -122,25 +102,11 @@ public class SettingsFragment extends SideFragment {
: R.string.option_toggle_parental_controls_off)) {
@Override
protected void onSelected() {
- final MainActivity tvActivity = getMainActivity();
- final SideFragmentManager sideFragmentManager = tvActivity.getOverlayManager()
- .getSideFragmentManager();
- sideFragmentManager.hideSidePanel(true);
- PinDialogFragment fragment = new PinDialogFragment(
- PinDialogFragment.PIN_DIALOG_TYPE_ENTER_PIN,
- new PinDialogFragment.ResultListener() {
- @Override
- public void done(boolean success) {
- if (success) {
- sideFragmentManager
- .show(new ParentalControlsFragment(), false);
- sideFragmentManager.showSidePanel(true);
- } else {
- sideFragmentManager.hideAll(false);
- }
- }
- });
- tvActivity.getOverlayManager()
+ getMainActivity().getOverlayManager()
+ .getSideFragmentManager().hideSidePanel(true);
+ PinDialogFragment fragment = PinDialogFragment
+ .create(PinDialogFragment.PIN_DIALOG_TYPE_ENTER_PIN);
+ getMainActivity().getOverlayManager()
.showDialogFragment(PinDialogFragment.DIALOG_TAG, fragment, true);
}
});
@@ -149,12 +115,73 @@ public class SettingsFragment extends SideFragment {
// But, we may be able to turn on channel lock feature regardless of the permission.
// It's TBD.
}
- if (LicenseUtils.hasLicenses(activity.getAssets())) {
- items.add(new LicenseActionItem(activity));
+ boolean showTrickplaySetting = false;
+ if (TUNER.isEnabled(getContext())) {
+ for (TvInputInfo inputInfo : TvApplication.getSingletons(getContext())
+ .getTvInputManagerHelper().getTvInputInfos(true, true)) {
+ if (Utils.isInternalTvInput(getContext(), inputInfo.getId())) {
+ showTrickplaySetting = true;
+ break;
+ }
+ }
+ if (showTrickplaySetting) {
+ showTrickplaySetting =
+ TvCustomizationManager.getTrickplayMode(getContext())
+ == TvCustomizationManager.TRICKPLAY_MODE_ENABLED;
+ }
+ }
+ if (showTrickplaySetting) {
+ items.add(
+ new SwitchItem(getString(R.string.settings_trickplay),
+ getString(R.string.settings_trickplay),
+ getString(R.string.settings_trickplay_description),
+ getResources().getInteger(R.integer.trickplay_description_max_lines)) {
+ @Override
+ protected void onUpdate() {
+ super.onUpdate();
+ boolean enabled = TunerPreferences.getTrickplaySetting(getContext())
+ != TunerPreferences.TRICKPLAY_SETTING_DISABLED;
+ setChecked(enabled);
+ }
+
+ @Override
+ protected void onSelected() {
+ super.onSelected();
+ @TunerPreferences.TrickplaySetting int setting =
+ isChecked() ? TunerPreferences.TRICKPLAY_SETTING_ENABLED
+ : TunerPreferences.TRICKPLAY_SETTING_DISABLED;
+ TunerPreferences.setTrickplaySetting(getContext(), setting);
+ }
+ });
+ }
+ items.add(new ActionItem(getString(R.string.settings_send_feedback)) {
+ @Override
+ protected void onSelected() {
+ Intent intent = new Intent(Intent.ACTION_APP_ERROR);
+ ApplicationErrorReport report = new ApplicationErrorReport();
+ report.packageName = report.processName = getContext().getPackageName();
+ report.time = System.currentTimeMillis();
+ report.type = ApplicationErrorReport.TYPE_NONE;
+ intent.putExtra(Intent.EXTRA_BUG_REPORT, report);
+ startActivityForResult(intent, 0);
+ }
+ });
+ if (Licenses.hasLicenses(getContext())) {
+ items.add(
+ new SubMenuItem(
+ getString(R.string.settings_menu_licenses),
+ getMainActivity().getOverlayManager().getSideFragmentManager()) {
+ @Override
+ protected SideFragment getFragment() {
+ return new LicenseSideFragment();
+ }
+ });
}
// Show version.
- items.add(new SimpleItem(getString(R.string.settings_menu_version),
- ((TvApplication) activity.getApplicationContext()).getVersionName()));
+ SimpleActionItem version = new SimpleActionItem(getString(R.string.settings_menu_version),
+ ((TvApplication) activity.getApplicationContext()).getVersionName());
+ version.setClickable(false);
+ items.add(version);
return items;
}
diff --git a/src/com/android/tv/ui/sidepanel/SideFragment.java b/src/com/android/tv/ui/sidepanel/SideFragment.java
index 8df56cd2..6bd921a2 100644
--- a/src/com/android/tv/ui/sidepanel/SideFragment.java
+++ b/src/com/android/tv/ui/sidepanel/SideFragment.java
@@ -26,32 +26,36 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvApplication;
-import com.android.tv.analytics.DurationTimer;
+import com.android.tv.util.DurationTimer;
import com.android.tv.analytics.HasTrackerLabel;
import com.android.tv.analytics.Tracker;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.ProgramDataManager;
import com.android.tv.util.SystemProperties;
+import com.android.tv.util.ViewCache;
import java.util.List;
-public abstract class SideFragment extends Fragment implements HasTrackerLabel {
+public abstract class SideFragment<T extends Item> extends Fragment implements HasTrackerLabel {
public static final int INVALID_POSITION = -1;
- private static final int RECYCLED_VIEW_POOL_SIZE = 7;
- private static final int[] PRELOADED_VIEW_IDS = {
+ private static final int PRELOAD_VIEW_SIZE = 7;
+ private static final int[] PRELOAD_VIEW_IDS = {
R.layout.option_item_radio_button,
R.layout.option_item_channel_lock,
R.layout.option_item_check_box,
- R.layout.option_item_channel_check
+ R.layout.option_item_channel_check,
+ R.layout.option_item_action
};
- private static RecyclerView.RecycledViewPool sRecycledViewPool;
+ private static RecyclerView.RecycledViewPool sRecycledViewPool =
+ new RecyclerView.RecycledViewPool();
private VerticalGridView mListView;
private ItemAdapter mAdapter;
@@ -89,14 +93,8 @@ public abstract class SideFragment extends Fragment implements HasTrackerLabel {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- if (sRecycledViewPool == null) {
- // sRecycledViewPool should be initialized by calling preloadRecycledViews()
- // before the entering animation of this fragment starts,
- // because it takes long time and if it is called after the animation starts (e.g. here)
- // it can affect the animation.
- throw new IllegalStateException("The RecyclerView pool has not been initialized.");
- }
- View view = inflater.inflate(getFragmentLayoutResourceId(), container, false);
+ View view = ViewCache.getInstance().getOrCreateView(
+ inflater, getFragmentLayoutResourceId(), container);
TextView textView = (TextView) view.findViewById(R.id.side_panel_title);
textView.setText(getTitle());
@@ -158,7 +156,7 @@ public abstract class SideFragment extends Fragment implements HasTrackerLabel {
return mListView.getSelectedPosition();
}
- public void setItems(List<Item> items) {
+ public void setItems(List<T> items) {
mAdapter.reset(items);
}
@@ -229,56 +227,50 @@ public abstract class SideFragment extends Fragment implements HasTrackerLabel {
protected abstract String getTitle();
@Override
public abstract String getTrackerLabel();
- protected abstract List<Item> getItemList();
+ protected abstract List<T> getItemList();
public interface SideFragmentListener {
void onSideFragmentViewDestroyed();
}
/**
- * Preloads the view holders.
+ * Preloads the item views.
*/
- public static void preloadRecycledViews(Context context) {
- if (sRecycledViewPool != null) {
- return;
- }
- sRecycledViewPool = new RecyclerView.RecycledViewPool();
- LayoutInflater inflater =
- (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- for (int id : PRELOADED_VIEW_IDS) {
- sRecycledViewPool.setMaxRecycledViews(id, RECYCLED_VIEW_POOL_SIZE);
- for (int j = 0; j < RECYCLED_VIEW_POOL_SIZE; ++j) {
- ItemAdapter.ViewHolder viewHolder = new ItemAdapter.ViewHolder(
- inflater.inflate(id, null, false));
- sRecycledViewPool.putRecycledView(viewHolder);
- }
+ public static void preloadItemViews(Context context) {
+ ViewCache.getInstance().putView(
+ context, R.layout.option_fragment, new FrameLayout(context), 1);
+ VerticalGridView fakeParent = new VerticalGridView(context);
+ for (int id : PRELOAD_VIEW_IDS) {
+ sRecycledViewPool.setMaxRecycledViews(id, PRELOAD_VIEW_SIZE);
+ ViewCache.getInstance().putView(context, id, fakeParent, PRELOAD_VIEW_SIZE);
}
}
/**
- * Releases the pre-loaded view holders.
+ * Releases the recycled view pool.
*/
- public static void releasePreloadedRecycledViews() {
- sRecycledViewPool = null;
+ public static void releaseRecycledViewPool() {
+ sRecycledViewPool.clear();
}
- private static class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {
+ private static class ItemAdapter<T extends Item> extends RecyclerView.Adapter<ViewHolder> {
private final LayoutInflater mLayoutInflater;
- private List<Item> mItems;
+ private List<T> mItems;
- private ItemAdapter(LayoutInflater layoutInflater, List<Item> items) {
+ private ItemAdapter(LayoutInflater layoutInflater, List<T> items) {
mLayoutInflater = layoutInflater;
mItems = items;
}
- private void reset(List<Item> items) {
+ private void reset(List<T> items) {
mItems = items;
notifyDataSetChanged();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- return new ViewHolder(mLayoutInflater.inflate(viewType, parent, false));
+ View view = ViewCache.getInstance().getOrCreateView(mLayoutInflater, viewType, parent);
+ return new ViewHolder(view);
}
@Override
@@ -301,11 +293,11 @@ public abstract class SideFragment extends Fragment implements HasTrackerLabel {
return mItems == null ? 0 : mItems.size();
}
- private Item getItem(int position) {
+ private T getItem(int position) {
return mItems.get(position);
}
- private void clearRadioGroup(Item item) {
+ private void clearRadioGroup(T item) {
int position = mItems.indexOf(item);
for (int i = position - 1; i >= 0; --i) {
if ((item = mItems.get(i)) instanceof RadioButtonItem) {
@@ -322,55 +314,57 @@ public abstract class SideFragment extends Fragment implements HasTrackerLabel {
}
}
}
+ }
- private static class ViewHolder extends RecyclerView.ViewHolder
- implements View.OnClickListener, View.OnFocusChangeListener {
- private ItemAdapter mAdapter;
- public Item mItem;
+ private static class ViewHolder extends RecyclerView.ViewHolder
+ implements View.OnClickListener, View.OnFocusChangeListener {
+ private ItemAdapter mAdapter;
+ public Item mItem;
- private ViewHolder(View view) {
- super(view);
- itemView.setOnClickListener(this);
- itemView.setOnFocusChangeListener(this);
- }
+ private ViewHolder(View view) {
+ super(view);
+ itemView.setOnClickListener(this);
+ itemView.setOnFocusChangeListener(this);
+ }
- public void onBind(ItemAdapter adapter, Item item) {
- mAdapter = adapter;
- mItem = item;
- mItem.onBind(itemView);
- mItem.onUpdate();
- }
+ public void onBind(ItemAdapter adapter, Item item) {
+ mAdapter = adapter;
+ mItem = item;
+ mItem.onBind(itemView);
+ mItem.onUpdate();
+ }
- public void onUnbind() {
- mItem.onUnbind();
- mItem = null;
- mAdapter = null;
- }
+ public void onUnbind() {
+ mItem.onUnbind();
+ mItem = null;
+ mAdapter = null;
+ }
- @Override
- public void onClick(View view) {
- if (mItem instanceof RadioButtonItem) {
- mAdapter.clearRadioGroup(mItem);
- }
- if (view.getBackground() instanceof RippleDrawable) {
- view.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (mItem != null) {
- mItem.onSelected();
+ @Override
+ public void onClick(View view) {
+ if (mItem instanceof RadioButtonItem) {
+ mAdapter.clearRadioGroup(mItem);
+ }
+ if (view.getBackground() instanceof RippleDrawable) {
+ view.postDelayed(
+ new Runnable() {
+ @Override
+ public void run() {
+ if (mItem != null) {
+ mItem.onSelected();
+ }
}
- }
- }, view.getResources().getInteger(R.integer.side_panel_ripple_anim_duration));
- } else {
- mItem.onSelected();
- }
+ },
+ view.getResources().getInteger(R.integer.side_panel_ripple_anim_duration));
+ } else {
+ mItem.onSelected();
}
+ }
- @Override
- public void onFocusChange(View view, boolean focusGained) {
- if (focusGained) {
- mItem.onFocused();
- }
+ @Override
+ public void onFocusChange(View view, boolean focusGained) {
+ if (focusGained) {
+ mItem.onFocused();
}
}
}
diff --git a/src/com/android/tv/ui/sidepanel/SideFragmentManager.java b/src/com/android/tv/ui/sidepanel/SideFragmentManager.java
index 553cd9d7..d02d3fb7 100644
--- a/src/com/android/tv/ui/sidepanel/SideFragmentManager.java
+++ b/src/com/android/tv/ui/sidepanel/SideFragmentManager.java
@@ -24,6 +24,7 @@ import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Handler;
import android.view.View;
+import android.view.ViewTreeObserver;
import com.android.tv.R;
@@ -34,6 +35,7 @@ public class SideFragmentManager {
private final FragmentManager mFragmentManager;
private final Runnable mPreShowRunnable;
private final Runnable mPostHideRunnable;
+ private ViewTreeObserver.OnGlobalLayoutListener mShowOnGlobalLayoutListener;
// To get the count reliably while using popBackStack(),
// instead of using getBackStackEntryCount() with popBackStackImmediate().
@@ -99,17 +101,10 @@ public class SideFragmentManager {
* Shows the given {@link SideFragment}.
*/
public void show(SideFragment sideFragment, boolean showEnterAnimation) {
- SideFragment.preloadRecycledViews(mActivity);
if (isHiding()) {
mHideAnimator.end();
}
boolean isFirst = (mFragmentCount == 0);
- if (isFirst) {
- if (mPreShowRunnable != null) {
- mPreShowRunnable.run();
- }
- }
-
FragmentTransaction ft = mFragmentManager.beginTransaction();
if (!isFirst) {
ft.setCustomAnimations(
@@ -123,8 +118,22 @@ public class SideFragmentManager {
mFragmentCount++;
if (isFirst) {
+ // We should wait for fragment transition and intital layouting finished to start the
+ // slide-in animation to prevent jankiness resulted by performing transition and
+ // layouting at the same time with animation.
mPanel.setVisibility(View.VISIBLE);
- mShowAnimator.start();
+ mShowOnGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ mPanel.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ mShowOnGlobalLayoutListener = null;
+ if (mPreShowRunnable != null) {
+ mPreShowRunnable.run();
+ }
+ mShowAnimator.start();
+ }
+ };
+ mPanel.getViewTreeObserver().addOnGlobalLayoutListener(mShowOnGlobalLayoutListener);
}
scheduleHideAll();
}
@@ -142,6 +151,18 @@ public class SideFragmentManager {
}
public void hideAll(boolean withAnimation) {
+ if (mShowAnimator.isStarted()) {
+ mShowAnimator.end();
+ }
+ if (mShowOnGlobalLayoutListener != null) {
+ // The show operation maybe requested but the show animator is not started yet, in this
+ // case, we show still run mPreShowRunnable.
+ mPanel.getViewTreeObserver().removeOnGlobalLayoutListener(mShowOnGlobalLayoutListener);
+ mShowOnGlobalLayoutListener = null;
+ if (mPreShowRunnable != null) {
+ mPreShowRunnable.run();
+ }
+ }
if (withAnimation) {
if (!isHiding()) {
mHideAnimator.start();
@@ -178,7 +199,6 @@ public class SideFragmentManager {
* @param withAnimation specifies if animation should be shown.
*/
public void showSidePanel(boolean withAnimation) {
- SideFragment.preloadRecycledViews(mActivity);
if (mFragmentCount == 0) {
return;
}
diff --git a/src/com/android/tv/ui/sidepanel/SimpleActionItem.java b/src/com/android/tv/ui/sidepanel/SimpleActionItem.java
new file mode 100644
index 00000000..42553b66
--- /dev/null
+++ b/src/com/android/tv/ui/sidepanel/SimpleActionItem.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 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.tv.ui.sidepanel;
+
+/**
+ * A simple item which shows title and description.
+ */
+public class SimpleActionItem extends ActionItem {
+ public SimpleActionItem(String title) {
+ super(title);
+ }
+
+ public SimpleActionItem(String title, String description) {
+ super(title, description);
+ }
+
+ @Override
+ protected void onSelected() {
+ }
+}
diff --git a/src/com/android/tv/ui/sidepanel/SimpleItem.java b/src/com/android/tv/ui/sidepanel/SimpleItem.java
deleted file mode 100644
index 52a5f13f..00000000
--- a/src/com/android/tv/ui/sidepanel/SimpleItem.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.ui.sidepanel;
-
-/**
- * A simple item which shows title and description.
- */
-public class SimpleItem extends ActionItem {
- public SimpleItem(String title) {
- super(title);
- }
-
- public SimpleItem(String title, String description) {
- super(title, description);
- }
-
- @Override
- protected void onSelected() {
- }
-}
diff --git a/src/com/android/tv/ui/sidepanel/SubMenuItem.java b/src/com/android/tv/ui/sidepanel/SubMenuItem.java
index aa349dbd..4b0e8e2c 100644
--- a/src/com/android/tv/ui/sidepanel/SubMenuItem.java
+++ b/src/com/android/tv/ui/sidepanel/SubMenuItem.java
@@ -21,20 +21,11 @@ public abstract class SubMenuItem extends ActionItem {
private final SideFragmentManager mSideFragmentManager;
public SubMenuItem(String title, SideFragmentManager fragmentManager) {
- this(title, null, 0, fragmentManager);
+ this(title, null, fragmentManager);
}
public SubMenuItem(String title, String description, SideFragmentManager fragmentManager) {
- this(title, description, 0, fragmentManager);
- }
-
- public SubMenuItem(String title, int iconId, SideFragmentManager fragmentManager) {
- this(title, null, iconId, fragmentManager);
- }
-
- public SubMenuItem(String title, String description, int iconId,
- SideFragmentManager fragmentManager) {
- super(title, description, iconId);
+ super(title, description);
mSideFragmentManager = fragmentManager;
}
diff --git a/src/com/android/tv/ui/sidepanel/SwitchItem.java b/src/com/android/tv/ui/sidepanel/SwitchItem.java
index ef9966a5..06591b62 100644
--- a/src/com/android/tv/ui/sidepanel/SwitchItem.java
+++ b/src/com/android/tv/ui/sidepanel/SwitchItem.java
@@ -31,6 +31,11 @@ public class SwitchItem extends CompoundButtonItem {
super(checkedTitle, uncheckedTitle, description);
}
+ public SwitchItem(String checkedTitle, String uncheckedTitle, String description,
+ int maxLines) {
+ super(checkedTitle, uncheckedTitle, description, maxLines);
+ }
+
@Override
protected int getResourceId() {
return R.layout.option_item_switch;
diff --git a/src/com/android/tv/ui/sidepanel/parentalcontrols/ParentalControlsFragment.java b/src/com/android/tv/ui/sidepanel/parentalcontrols/ParentalControlsFragment.java
index da712924..9a4879fc 100644
--- a/src/com/android/tv/ui/sidepanel/parentalcontrols/ParentalControlsFragment.java
+++ b/src/com/android/tv/ui/sidepanel/parentalcontrols/ParentalControlsFragment.java
@@ -130,17 +130,8 @@ public class ParentalControlsFragment extends SideFragment {
protected void onSelected() {
final MainActivity tvActivity = getMainActivity();
tvActivity.getOverlayManager().getSideFragmentManager().hideSidePanel(true);
-
- PinDialogFragment fragment =
- new PinDialogFragment(
- PinDialogFragment.PIN_DIALOG_TYPE_NEW_PIN,
- new PinDialogFragment.ResultListener() {
- @Override
- public void done(boolean success) {
- tvActivity.getOverlayManager().getSideFragmentManager()
- .showSidePanel(true);
- }
- });
+ PinDialogFragment fragment = PinDialogFragment.create(
+ PinDialogFragment.PIN_DIALOG_TYPE_NEW_PIN);
tvActivity.getOverlayManager().showDialogFragment(PinDialogFragment.DIALOG_TAG,
fragment, true);
}
diff --git a/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java b/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
index 6bc47939..7c8cecbe 100644
--- a/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
+++ b/src/com/android/tv/ui/sidepanel/parentalcontrols/RatingsFragment.java
@@ -17,16 +17,17 @@
package com.android.tv.ui.sidepanel.parentalcontrols;
import android.graphics.drawable.Drawable;
+import android.media.tv.TvContentRating;
import android.os.Bundle;
import android.util.ArrayMap;
import android.util.SparseIntArray;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
-
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.dialog.WebDialogFragment;
+import com.android.tv.experiments.Experiments;
import com.android.tv.license.LicenseUtils;
import com.android.tv.parental.ContentRatingSystem;
import com.android.tv.parental.ContentRatingSystem.Rating;
@@ -38,7 +39,6 @@ import com.android.tv.ui.sidepanel.RadioButtonItem;
import com.android.tv.ui.sidepanel.SideFragment;
import com.android.tv.util.TvSettings;
import com.android.tv.util.TvSettings.ContentRatingLevel;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -77,6 +77,7 @@ public class RatingsFragment extends SideFragment {
private final List<RatingLevelItem> mRatingLevelItems = new ArrayList<>();
// A map from the rating system ID string to RatingItem objects.
private final Map<String, List<RatingItem>> mContentRatingSystemItemMap = new ArrayMap<>();
+ private CheckBoxItem mBlockUnratedItem;
private ParentalControlSettings mParentalControlSettings;
public static String getDescription(MainActivity tvActivity) {
@@ -102,6 +103,12 @@ public class RatingsFragment extends SideFragment {
protected List<Item> getItemList() {
List<Item> items = new ArrayList<>();
+ if (mBlockUnratedItem != null
+ && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
+ items.add(mBlockUnratedItem);
+ items.add(new DividerItem());
+ }
+
mRatingLevelItems.clear();
for (int i = 0; i < sLevelResourceIdMap.size(); ++i) {
mRatingLevelItems.add(new RatingLevelItem(sLevelResourceIdMap.keyAt(i)));
@@ -152,6 +159,28 @@ public class RatingsFragment extends SideFragment {
super.onCreate(savedInstanceState);
mParentalControlSettings = getMainActivity().getParentalControlSettings();
mParentalControlSettings.loadRatings();
+ if (Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
+ mBlockUnratedItem =
+ new CheckBoxItem(
+ getResources().getString(R.string.option_block_unrated_programs)) {
+
+ @Override
+ protected void onUpdate() {
+ super.onUpdate();
+ setChecked(
+ mParentalControlSettings.isRatingBlocked(
+ new TvContentRating[] {TvContentRating.UNRATED}));
+ }
+
+ @Override
+ protected void onSelected() {
+ super.onSelected();
+ if (mParentalControlSettings.setUnratedBlocked(isChecked())) {
+ updateRatingLevels();
+ }
+ }
+ };
+ }
}
@Override
@@ -202,6 +231,13 @@ public class RatingsFragment extends SideFragment {
super.onSelected();
mParentalControlSettings.setContentRatingLevel(
getMainActivity().getContentRatingsManager(), mRatingLevel);
+ if (mBlockUnratedItem != null
+ && Boolean.TRUE.equals(Experiments.ENABLE_UNRATED_CONTENT_SETTINGS.get())) {
+ // set checked if UNRATED is blocked, and set unchecked otherwise.
+ mBlockUnratedItem.setChecked(
+ mParentalControlSettings.isRatingBlocked(
+ new TvContentRating[] {TvContentRating.UNRATED}));
+ }
notifyItemsChanged(mRatingLevelItems.size());
}
}
@@ -302,7 +338,7 @@ public class RatingsFragment extends SideFragment {
@Override
protected void onSelected() {
getMainActivity().getOverlayManager().getSideFragmentManager()
- .show(new SubRatingsFragment(mContentRatingSystem, mRating));
+ .show(SubRatingsFragment.create(mContentRatingSystem, mRating.getName()));
}
@Override
diff --git a/src/com/android/tv/ui/sidepanel/parentalcontrols/SubRatingsFragment.java b/src/com/android/tv/ui/sidepanel/parentalcontrols/SubRatingsFragment.java
index f6612fdb..4634b74c 100644
--- a/src/com/android/tv/ui/sidepanel/parentalcontrols/SubRatingsFragment.java
+++ b/src/com/android/tv/ui/sidepanel/parentalcontrols/SubRatingsFragment.java
@@ -17,6 +17,7 @@
package com.android.tv.ui.sidepanel.parentalcontrols;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
@@ -36,13 +37,34 @@ import java.util.List;
public class SubRatingsFragment extends SideFragment {
private static final String TRACKER_LABEL = "Sub ratings";
- private final ContentRatingSystem mContentRatingSystem;
- private final Rating mRating;
+ private static final String ARGS_CONTENT_RATING_SYSTEM_ID = "args_content_rating_system_id";
+ private static final String ARGS_RATING_NAME = "args_rating_name";
+
+ private ContentRatingSystem mContentRatingSystem;
+ private Rating mRating;
private final List<SubRatingItem> mSubRatingItems = new ArrayList<>();
- public SubRatingsFragment(ContentRatingSystem contentRatingSystem, Rating rating) {
- mContentRatingSystem = contentRatingSystem;
- mRating = rating;
+ public static SubRatingsFragment create(ContentRatingSystem contentRatingSystem,
+ String ratingName) {
+ SubRatingsFragment fragment = new SubRatingsFragment();
+ Bundle args = new Bundle();
+ args.putString(ARGS_CONTENT_RATING_SYSTEM_ID, contentRatingSystem.getId());
+ args.putString(ARGS_RATING_NAME, ratingName);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContentRatingSystem = getMainActivity().getContentRatingsManager()
+ .getContentRatingSystem(getArguments().getString(ARGS_CONTENT_RATING_SYSTEM_ID));
+ if (mContentRatingSystem != null) {
+ mRating = mContentRatingSystem.getRating(getArguments().getString(ARGS_RATING_NAME));
+ }
+ if (mRating == null) {
+ closeFragment();
+ }
}
@Override
diff --git a/src/com/android/tv/util/AsyncDbTask.java b/src/com/android/tv/util/AsyncDbTask.java
index 78243642..477412e4 100644
--- a/src/com/android/tv/util/AsyncDbTask.java
+++ b/src/com/android/tv/util/AsyncDbTask.java
@@ -31,7 +31,7 @@ import android.util.Range;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
-import com.android.tv.dvr.RecordedProgram;
+import com.android.tv.dvr.data.RecordedProgram;
import java.util.ArrayList;
import java.util.List;
@@ -76,7 +76,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
* accepted for execution
* @throws NullPointerException if command is null
*/
- public static void execute(Runnable command) {
+ public static void executeOnDbThread(Runnable command) {
DB_EXECUTOR.execute(command);
}
diff --git a/src/com/android/tv/util/BitmapUtils.java b/src/com/android/tv/util/BitmapUtils.java
index d45a8dce..fbaab023 100644
--- a/src/com/android/tv/util/BitmapUtils.java
+++ b/src/com/android/tv/util/BitmapUtils.java
@@ -24,6 +24,7 @@ import android.graphics.BitmapFactory;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.net.TrafficStats;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.text.TextUtils;
@@ -56,6 +57,12 @@ public final class BitmapUtils {
return Bitmap.createScaledBitmap(bm, rect.right, rect.bottom, false);
}
+ public static Bitmap getScaledMutableBitmap(Bitmap bm, int maxWidth, int maxHeight) {
+ Bitmap scaledBitmap = scaleBitmap(bm, maxWidth, maxHeight);
+ return scaledBitmap.isMutable() ? scaledBitmap
+ : scaledBitmap.copy(Bitmap.Config.ARGB_8888, true);
+ }
+
private static Rect calculateNewSize(Bitmap bm, int maxWidth, int maxHeight) {
final double ratio = maxHeight / (double) maxWidth;
final double bmRatio = bm.getHeight() / (double) bm.getWidth();
@@ -89,6 +96,8 @@ public final class BitmapUtils {
boolean isResourceUri = isContentResolverUri(uri);
URLConnection urlConnection = null;
InputStream inputStream = null;
+ final int oldTag = TrafficStats.getThreadStatsTag();
+ TrafficStats.setThreadStatsTag(NetworkTrafficTags.LOGO_FETCHER);
try {
if (isResourceUri) {
inputStream = context.getContentResolver().openInputStream(uri);
@@ -142,6 +151,7 @@ public final class BitmapUtils {
return null;
} finally {
close(inputStream, urlConnection);
+ TrafficStats.setThreadStatsTag(oldTag);
}
}
diff --git a/src/com/android/tv/util/Debug.java b/src/com/android/tv/util/Debug.java
new file mode 100644
index 00000000..67a2683d
--- /dev/null
+++ b/src/com/android/tv/util/Debug.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 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.tv.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A class only for help developers.
+ */
+public class Debug {
+ /**
+ * A threshold of start up time, when the start up time of Live TV is more than it,
+ * a warning will show to the developer.
+ */
+ public static final long TIME_START_UP_DURATION_THRESHOLD = TimeUnit.SECONDS.toMillis(6);
+ /**
+ * Tag for measuring start up time of Live TV.
+ */
+ public static final String TAG_START_UP_TIMER = "start_up_timer";
+
+ /**
+ * A global map for duration timers.
+ */
+ private final static Map<String, DurationTimer> sTimerMap = new HashMap<>();
+
+ /**
+ * Returns the global duration timer by tag.
+ */
+ public static DurationTimer getTimer(String tag) {
+ if (sTimerMap.get(tag) != null) {
+ return sTimerMap.get(tag);
+ }
+ DurationTimer timer = new DurationTimer(tag, true);
+ sTimerMap.put(tag, timer);
+ return timer;
+ }
+
+ /**
+ * Removes the global duration timer by tag.
+ */
+ public static DurationTimer removeTimer(String tag) {
+ return sTimerMap.remove(tag);
+ }
+}
diff --git a/src/com/android/tv/util/DurationTimer.java b/src/com/android/tv/util/DurationTimer.java
new file mode 100644
index 00000000..1f057bf6
--- /dev/null
+++ b/src/com/android/tv/util/DurationTimer.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015 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.tv.util;
+
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.tv.common.BuildConfig;
+
+/**
+ * Times a duration.
+ */
+public final class DurationTimer {
+ private static final String TAG = "DurationTimer";
+ public static final long TIME_NOT_SET = -1;
+
+ private long mStartTimeMs = TIME_NOT_SET;
+ private String mTag = TAG;
+ private boolean mLogEngOnly;
+
+ public DurationTimer() { }
+
+ public DurationTimer(String tag, boolean logEngOnly) {
+ mTag = tag;
+ mLogEngOnly = logEngOnly;
+ }
+
+ /**
+ * Returns true if the timer is running.
+ */
+ public boolean isRunning() {
+ return mStartTimeMs != TIME_NOT_SET;
+ }
+
+ /**
+ * Start the timer.
+ */
+ public void start() {
+ mStartTimeMs = SystemClock.elapsedRealtime();
+ }
+
+ /**
+ * Returns true if timer is started.
+ */
+ public boolean isStarted() {
+ return mStartTimeMs != TIME_NOT_SET;
+ }
+
+ /**
+ * Returns the current duration in milliseconds or {@link #TIME_NOT_SET} if the timer is not
+ * running.
+ */
+ public long getDuration() {
+ return isRunning() ? SystemClock.elapsedRealtime() - mStartTimeMs : TIME_NOT_SET;
+ }
+
+ /**
+ * Stops the timer and resets its value to {@link #TIME_NOT_SET}.
+ *
+ * @return the current duration in milliseconds or {@link #TIME_NOT_SET} if the timer is not
+ * running.
+ */
+ public long reset() {
+ long duration = getDuration();
+ mStartTimeMs = TIME_NOT_SET;
+ return duration;
+ }
+
+ /**
+ * Adds information and duration time to the log.
+ */
+ public void log(String message) {
+ if (isRunning() && (!mLogEngOnly || BuildConfig.ENG)) {
+ Log.i(mTag, message + " : " + getDuration() + "ms");
+ }
+ }
+}
diff --git a/src/com/android/tv/util/ImageLoader.java b/src/com/android/tv/util/ImageLoader.java
index 04bb478a..86bb94c1 100644
--- a/src/com/android/tv/util/ImageLoader.java
+++ b/src/com/android/tv/util/ImageLoader.java
@@ -292,7 +292,8 @@ public final class ImageLoader {
* Checks if a reload would be needed if the results of other was available.
*/
private boolean isReloadNeeded(LoadBitmapTask other) {
- return mMaxHeight >= other.mMaxHeight * 2 || mMaxWidth >= other.mMaxWidth * 2;
+ return (other.mMaxHeight != Integer.MAX_VALUE && mMaxHeight >= other.mMaxHeight * 2)
+ || (other.mMaxWidth != Integer.MAX_VALUE && mMaxWidth >= other.mMaxWidth * 2);
}
@Nullable
diff --git a/src/com/android/tv/util/LocationUtils.java b/src/com/android/tv/util/LocationUtils.java
index 8e3b59e9..d5d7bee3 100644
--- a/src/com/android/tv/util/LocationUtils.java
+++ b/src/com/android/tv/util/LocationUtils.java
@@ -16,15 +16,20 @@
package com.android.tv.util;
+import android.Manifest;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
import android.util.Log;
+import com.android.tv.tuner.util.PostalCodeUtils;
import java.io.IOException;
import java.util.List;
@@ -39,6 +44,7 @@ public class LocationUtils {
private static Context sApplicationContext;
private static Address sAddress;
+ private static String sCountry;
private static IOException sError;
/**
@@ -59,6 +65,18 @@ public class LocationUtils {
return null;
}
+ /** Returns the current country. */
+ @NonNull
+ public static synchronized String getCurrentCountry(Context context) {
+ if (sCountry != null) {
+ return sCountry;
+ }
+ if (TextUtils.isEmpty(sCountry)) {
+ sCountry = context.getResources().getConfiguration().locale.getCountry();
+ }
+ return sCountry;
+ }
+
private static void updateAddress(Location location) {
if (DEBUG) Log.d(TAG, "Updating address with " + location);
if (location == null) {
@@ -68,9 +86,14 @@ public class LocationUtils {
try {
List<Address> addresses = geocoder.getFromLocation(
location.getLatitude(), location.getLongitude(), 1);
- if (addresses != null) {
+ if (addresses != null && !addresses.isEmpty()) {
sAddress = addresses.get(0);
if (DEBUG) Log.d(TAG, "Got " + sAddress);
+ try {
+ PostalCodeUtils.updatePostalCode(sApplicationContext);
+ } catch (Exception e) {
+ // Do nothing
+ }
} else {
if (DEBUG) Log.d(TAG, "No address returned");
}
diff --git a/src/com/android/tv/util/NetworkTrafficTags.java b/src/com/android/tv/util/NetworkTrafficTags.java
new file mode 100644
index 00000000..2dca613c
--- /dev/null
+++ b/src/com/android/tv/util/NetworkTrafficTags.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 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.tv.util;
+
+import android.net.TrafficStats;
+import android.support.annotation.NonNull;
+
+import java.util.concurrent.Executor;
+
+/** Constants for tagging network traffic in the Live channels app. */
+public final class NetworkTrafficTags {
+
+ public static final int DEFAULT_LIVE_CHANNELS = 1;
+ public static final int LOGO_FETCHER = 2;
+ public static final int HDHOMERUN = 3;
+ public static final int EPG_FETCH = 4;
+
+ /**
+ * An executor which simply wraps a provided delegate executor, but calls {@link
+ * TrafficStats#setThreadStatsTag(int)} before executing any task.
+ */
+ public static class TrafficStatsTaggingExecutor implements Executor {
+ private final Executor delegateExecutor;
+ private final int tag;
+
+ public TrafficStatsTaggingExecutor(Executor delegateExecutor, int tag) {
+ this.delegateExecutor = delegateExecutor;
+ this.tag = tag;
+ }
+
+ @Override
+ public void execute(final @NonNull Runnable command) {
+ // TODO(b/62038127): robolectric does not support lamdas in unbundled apps
+ delegateExecutor.execute(
+ new Runnable() {
+ @Override
+ public void run() {
+ TrafficStats.setThreadStatsTag(tag);
+ try {
+ command.run();
+ } finally {
+ TrafficStats.clearThreadStatsTag();
+ }
+ }
+ });
+ }
+ }
+
+ private NetworkTrafficTags() {}
+}
diff --git a/src/com/android/tv/util/OnboardingUtils.java b/src/com/android/tv/util/OnboardingUtils.java
index 3040020e..49b02b82 100644
--- a/src/com/android/tv/util/OnboardingUtils.java
+++ b/src/com/android/tv/util/OnboardingUtils.java
@@ -16,17 +16,10 @@
package com.android.tv.util;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.database.Cursor;
-import android.media.tv.TvContract.Channels;
import android.net.Uri;
import android.preference.PreferenceManager;
-import android.support.annotation.UiThread;
-
-import com.android.tv.TvApplication;
-import com.android.tv.data.ChannelDataManager;
/**
* A utility class related to onboarding experience.
@@ -82,41 +75,11 @@ public final class OnboardingUtils {
}
/**
- * Checks whether the onboarding screen should be shown or not.
- */
- public static boolean needToShowOnboarding(Context context) {
- return isFirstRunWithCurrentVersion(context) || !areChannelsAvailable(context);
- }
-
- /**
- * Checks if there are any available tuner channels.
- */
- @UiThread
- public static boolean areChannelsAvailable(Context context) {
- ChannelDataManager manager = TvApplication.getSingletons(context).getChannelDataManager();
- if (manager.isDbLoadFinished()) {
- return manager.getChannelCount() != 0;
- }
- // This method should block the UI thread.
- ContentResolver resolver = context.getContentResolver();
- try (Cursor c = resolver.query(Channels.CONTENT_URI, new String[] {Channels._ID}, null,
- null, null)) {
- return c != null && c.getCount() != 0;
- }
- }
-
- /**
- * Checks if there are any available TV inputs.
- */
- public static boolean areInputsAvailable(Context context) {
- return TvApplication.getSingletons(context).getTvInputManagerHelper()
- .getTvInputInfos(true, false).size() > 0;
- }
-
- /**
* Returns merchant collection URL.
*/
private static String getMerchantCollectionUrl() {
return "TODO: add a merchant collection url";
}
+
+ private OnboardingUtils() {}
}
diff --git a/src/com/android/tv/util/Partner.java b/src/com/android/tv/util/Partner.java
new file mode 100644
index 00000000..e3688392
--- /dev/null
+++ b/src/com/android/tv/util/Partner.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2017 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.tv.util;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.media.tv.TvInputInfo;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This file refers to Partner.java in LeanbackLauncher. Interact with partner customizations. There
+ * can only be one set of customizations on a device, and it must be bundled with the system.
+ */
+public class Partner {
+ private static final String TAG = "Partner";
+ /** Marker action used to discover partner */
+ private static final String ACTION_PARTNER_CUSTOMIZATION =
+ "com.google.android.leanbacklauncher.action.PARTNER_CUSTOMIZATION";
+
+ /** ID tags for device input types */
+ public static final String INPUT_TYPE_BUNDLED_TUNER = "input_type_combined_tuners";
+ public static final String INPUT_TYPE_TUNER = "input_type_tuner";
+ public static final String INPUT_TYPE_CEC_LOGICAL = "input_type_cec_logical";
+ public static final String INPUT_TYPE_CEC_RECORDER = "input_type_cec_recorder";
+ public static final String INPUT_TYPE_CEC_PLAYBACK = "input_type_cec_playback";
+ public static final String INPUT_TYPE_MHL_MOBILE = "input_type_mhl_mobile";
+ public static final String INPUT_TYPE_HDMI = "input_type_hdmi";
+ public static final String INPUT_TYPE_DVI = "input_type_dvi";
+ public static final String INPUT_TYPE_COMPONENT = "input_type_component";
+ public static final String INPUT_TYPE_SVIDEO = "input_type_svideo";
+ public static final String INPUT_TYPE_COMPOSITE = "input_type_composite";
+ public static final String INPUT_TYPE_DISPLAY_PORT = "input_type_displayport";
+ public static final String INPUT_TYPE_VGA = "input_type_vga";
+ public static final String INPUT_TYPE_SCART = "input_type_scart";
+ public static final String INPUT_TYPE_OTHER = "input_type_other";
+
+ private static final String INPUTS_ORDER = "home_screen_inputs_ordering";
+ private static final String TYPE_ARRAY = "array";
+
+ private static Partner sPartner;
+ private static final Object sLock = new Object();
+
+ private final String mPackageName;
+ private final String mReceiverName;
+ private final Resources mResources;
+
+ private static final Map<String, Integer> INPUT_TYPE_MAP = new HashMap<>();
+ static {
+ INPUT_TYPE_MAP.put(INPUT_TYPE_BUNDLED_TUNER, TvInputManagerHelper.TYPE_BUNDLED_TUNER);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_TUNER, TvInputInfo.TYPE_TUNER);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_CEC_LOGICAL, TvInputManagerHelper.TYPE_CEC_DEVICE);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_CEC_RECORDER, TvInputManagerHelper.TYPE_CEC_DEVICE_RECORDER);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_CEC_PLAYBACK, TvInputManagerHelper.TYPE_CEC_DEVICE_PLAYBACK);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_MHL_MOBILE, TvInputManagerHelper.TYPE_MHL_MOBILE);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_HDMI, TvInputInfo.TYPE_HDMI);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_DVI, TvInputInfo.TYPE_DVI);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_COMPONENT, TvInputInfo.TYPE_COMPONENT);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_SVIDEO, TvInputInfo.TYPE_SVIDEO);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_COMPOSITE, TvInputInfo.TYPE_COMPOSITE);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_DISPLAY_PORT, TvInputInfo.TYPE_DISPLAY_PORT);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_VGA, TvInputInfo.TYPE_VGA);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_SCART, TvInputInfo.TYPE_SCART);
+ INPUT_TYPE_MAP.put(INPUT_TYPE_OTHER, TvInputInfo.TYPE_OTHER);
+ }
+
+ private Partner(String packageName, String receiverName, Resources res) {
+ mPackageName = packageName;
+ mReceiverName = receiverName;
+ mResources = res;
+ }
+
+ /** Returns partner instance. */
+ public static Partner getInstance(Context context) {
+ PackageManager pm = context.getPackageManager();
+ synchronized (sLock) {
+ ResolveInfo info = getPartnerResolveInfo(pm);
+ if (info != null) {
+ final String packageName = info.activityInfo.packageName;
+ final String receiverName = info.activityInfo.name;
+ try {
+ final Resources res = pm.getResourcesForApplication(packageName);
+ sPartner = new Partner(packageName, receiverName, res);
+ sPartner.sendInitBroadcast(context);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Failed to find resources for " + packageName);
+ }
+ }
+ if (sPartner == null) {
+ sPartner = new Partner(null, null, null);
+ }
+ }
+ return sPartner;
+ }
+
+ /** Resets the Partner instance to handle the partner package has changed. */
+ public static void reset(Context context, String packageName) {
+ synchronized (sLock) {
+ if (sPartner != null && !TextUtils.isEmpty(packageName)) {
+ if (packageName.equals(sPartner.mPackageName)) {
+ // Force a refresh, so we send an Init to the updated package
+ sPartner = null;
+ getInstance(context);
+ }
+ }
+ }
+ }
+
+ /** This method is used to send init broadcast to the new/changed partner package. */
+ private void sendInitBroadcast(Context context) {
+ if (!TextUtils.isEmpty(mPackageName) && !TextUtils.isEmpty(mReceiverName)) {
+ Intent intent = new Intent(ACTION_PARTNER_CUSTOMIZATION);
+ final ComponentName componentName = new ComponentName(mPackageName, mReceiverName);
+ intent.setComponent(componentName);
+ intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ context.sendBroadcast(intent);
+ }
+ }
+
+ /** Returns the order of inputs. */
+ public Map<Integer, Integer> getInputsOrderMap() {
+ HashMap<Integer, Integer> map = new HashMap<>();
+ if (mResources != null && !TextUtils.isEmpty(mPackageName)) {
+ String[] inputsArray = null;
+ final int resId = mResources.getIdentifier(INPUTS_ORDER, TYPE_ARRAY, mPackageName);
+ if (resId != 0) {
+ inputsArray = mResources.getStringArray(resId);
+ }
+ if (inputsArray != null) {
+ int priority = 0;
+ for (String input : inputsArray) {
+ Integer type = INPUT_TYPE_MAP.get(input);
+ if (type != null) {
+ map.put(type, priority++);
+ }
+ }
+ }
+ }
+ return map;
+ }
+
+ private static ResolveInfo getPartnerResolveInfo(PackageManager pm) {
+ final Intent intent = new Intent(ACTION_PARTNER_CUSTOMIZATION);
+ ResolveInfo partnerInfo = null;
+ for (ResolveInfo info : pm.queryBroadcastReceivers(intent, 0)) {
+ if (isSystemApp(info)) {
+ partnerInfo = info;
+ break;
+ }
+ }
+ return partnerInfo;
+ }
+
+ protected static boolean isSystemApp(ResolveInfo info) {
+ return (info.activityInfo != null
+ && info.activityInfo.applicationInfo != null
+ && (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
+ }
+}
diff --git a/src/com/android/tv/util/PermissionUtils.java b/src/com/android/tv/util/PermissionUtils.java
index 453885a4..a355be99 100644
--- a/src/com/android/tv/util/PermissionUtils.java
+++ b/src/com/android/tv/util/PermissionUtils.java
@@ -47,4 +47,9 @@ public class PermissionUtils {
return context.checkSelfPermission(PERMISSION_READ_TV_LISTINGS)
== PackageManager.PERMISSION_GRANTED;
}
+
+ public static boolean hasInternet(Context context) {
+ return context.checkSelfPermission("android.permission.INTERNET")
+ == PackageManager.PERMISSION_GRANTED;
+ }
}
diff --git a/src/com/android/tv/util/PipInputManager.java b/src/com/android/tv/util/PipInputManager.java
deleted file mode 100644
index 2c51d5a0..00000000
--- a/src/com/android/tv/util/PipInputManager.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.util;
-
-import android.content.Context;
-import android.media.tv.TvInputInfo;
-import android.media.tv.TvInputManager;
-import android.media.tv.TvInputManager.TvInputCallback;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.tv.ChannelTuner;
-import com.android.tv.R;
-import com.android.tv.data.Channel;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A class that manages inputs for PIP. All tuner inputs are represented to one tuner input for PIP.
- * Hidden inputs should not be visible to the users.
- */
-public class PipInputManager {
- private static final String TAG = "PipInputManager";
-
- // Tuner inputs aren't distinguished each other in PipInput. They are handled as one input.
- // Therefore, we define a fake input id for the unified input.
- private static final String TUNER_INPUT_ID = "tuner_input_id";
-
- private final Context mContext;
- private final TvInputManagerHelper mInputManager;
- private final ChannelTuner mChannelTuner;
- private boolean mStarted;
- private final Map<String, PipInput> mPipInputMap = new HashMap<>(); // inputId -> PipInput
- private final Set<Listener> mListeners = new ArraySet<>();
-
- private final TvInputCallback mTvInputCallback = new TvInputCallback() {
- @Override
- public void onInputAdded(String inputId) {
- TvInputInfo input = mInputManager.getTvInputInfo(inputId);
- if (input.isPassthroughInput()) {
- boolean available = mInputManager.getInputState(input)
- == TvInputManager.INPUT_STATE_CONNECTED;
- mPipInputMap.put(inputId, new PipInput(inputId, available));
- } else if (!mPipInputMap.containsKey(TUNER_INPUT_ID)) {
- boolean available = mChannelTuner.getBrowsableChannelCount() != 0;
- mPipInputMap.put(TUNER_INPUT_ID, new PipInput(TUNER_INPUT_ID, available));
- } else {
- return;
- }
- for (Listener l : mListeners) {
- l.onPipInputListUpdated();
- }
- }
-
- @Override
- public void onInputRemoved(String inputId) {
- PipInput pipInput = mPipInputMap.remove(inputId);
- if (pipInput == null) {
- if (!mPipInputMap.containsKey(TUNER_INPUT_ID)) {
- Log.w(TAG, "A TV input (" + inputId + ") isn't tracked in PipInputManager");
- return;
- }
- if (mInputManager.getTunerTvInputSize() > 0) {
- return;
- }
- mPipInputMap.remove(TUNER_INPUT_ID);
- }
- for (Listener l : mListeners) {
- l.onPipInputListUpdated();
- }
- }
-
- @Override
- public void onInputStateChanged(String inputId, int state) {
- PipInput pipInput = mPipInputMap.get(inputId);
- if (pipInput == null) {
- // For tuner input, state change is handled in mChannelTunerListener.
- return;
- }
- pipInput.updateAvailability();
- }
- };
-
- private final ChannelTuner.Listener mChannelTunerListener = new ChannelTuner.Listener() {
- @Override
- public void onLoadFinished() { }
-
- @Override
- public void onCurrentChannelUnavailable(Channel channel) { }
-
- @Override
- public void onBrowsableChannelListChanged() {
- PipInput tunerInput = mPipInputMap.get(TUNER_INPUT_ID);
- if (tunerInput == null) {
- return;
- }
- tunerInput.updateAvailability();
- }
-
- @Override
- public void onChannelChanged(Channel previousChannel, Channel currentChannel) {
- if (previousChannel != null && currentChannel != null
- && !previousChannel.isPassthrough() && !currentChannel.isPassthrough()) {
- // Channel change between channels for tuner inputs.
- return;
- }
- PipInput previousMainInput = getPipInput(previousChannel);
- if (previousMainInput != null) {
- previousMainInput.updateAvailability();
- }
- PipInput currentMainInput = getPipInput(currentChannel);
- if (currentMainInput != null) {
- currentMainInput.updateAvailability();
- }
- }
- };
-
- public PipInputManager(Context context, TvInputManagerHelper inputManager,
- ChannelTuner channelTuner) {
- mContext = context;
- mInputManager = inputManager;
- mChannelTuner = channelTuner;
- }
-
- /**
- * Starts {@link PipInputManager}.
- */
- public void start() {
- if (mStarted) {
- return;
- }
- mStarted = true;
- mInputManager.addCallback(mTvInputCallback);
- mChannelTuner.addListener(mChannelTunerListener);
- initializePipInputList();
- }
-
- /**
- * Stops {@link PipInputManager}.
- */
- public void stop() {
- if (!mStarted) {
- return;
- }
- mStarted = false;
- mInputManager.removeCallback(mTvInputCallback);
- mChannelTuner.removeListener(mChannelTunerListener);
- mPipInputMap.clear();
- }
-
- /**
- * Adds a {@link PipInputManager.Listener}.
- */
- public void addListener(Listener listener) {
- mListeners.add(listener);
- }
-
- /**
- * Removes a {@link PipInputManager.Listener}.
- */
- public void removeListener(Listener listener) {
- mListeners.remove(listener);
- }
-
- /**
- * Gets the size of inputs for PIP.
- *
- * <p>The hidden inputs are not counted.
- *
- * @param availableOnly If {@code true}, it counts only available PIP inputs. Please see {@link
- * PipInput#isAvailable()} for the details of availability.
- */
- public int getPipInputSize(boolean availableOnly) {
- int count = 0;
- for (PipInput pipInput : mPipInputMap.values()) {
- if (!pipInput.isHidden() && (!availableOnly || pipInput.mAvailable)) {
- ++count;
- }
- if (pipInput.isPassthrough()) {
- TvInputInfo info = pipInput.getInputInfo();
- // Do not count HDMI ports if a CEC device is directly connected to the port.
- if (info.getParentId() != null && !info.isConnectedToHdmiSwitch()) {
- --count;
- }
- }
- }
- return count;
- }
-
- /**
- * Gets the list of inputs for PIP..
- *
- * <p>The hidden inputs are excluded.
- *
- * @param availableOnly If true, it returns only available PIP inputs. Please see {@link
- * PipInput#isAvailable()} for the details of availability.
- */
- public List<PipInput> getPipInputList(boolean availableOnly) {
- List<PipInput> pipInputs = new ArrayList<>();
- List<PipInput> removeInputs = new ArrayList<>();
- for (PipInput pipInput : mPipInputMap.values()) {
- if (!pipInput.isHidden() && (!availableOnly || pipInput.mAvailable)) {
- pipInputs.add(pipInput);
- }
- if (pipInput.isPassthrough()) {
- TvInputInfo info = pipInput.getInputInfo();
- // Do not show HDMI ports if a CEC device is directly connected to the port.
- if (info.getParentId() != null && !info.isConnectedToHdmiSwitch()) {
- removeInputs.add(mPipInputMap.get(info.getParentId()));
- }
- }
- }
- if (!removeInputs.isEmpty()) {
- pipInputs.removeAll(removeInputs);
- }
- Collections.sort(pipInputs, new Comparator<PipInput>() {
- @Override
- public int compare(PipInput lhs, PipInput rhs) {
- if (!lhs.mIsPassthrough) {
- return -1;
- }
- if (!rhs.mIsPassthrough) {
- return 1;
- }
- String a = lhs.getLabel();
- String b = rhs.getLabel();
- return a.compareTo(b);
- }
- });
- return pipInputs;
- }
-
- /**
- * Returns an PIP input corresponding to {@code channel}.
- */
- public PipInput getPipInput(Channel channel) {
- if (channel == null) {
- return null;
- }
- if (channel.isPassthrough()) {
- return mPipInputMap.get(channel.getInputId());
- } else {
- return mPipInputMap.get(TUNER_INPUT_ID);
- }
- }
-
- /**
- * Returns true, if {@code channel1} and {@code channel2} belong to the same input. For example,
- * two channels from different tuner inputs are also in the same input "Tuner" from PIP
- * point of view.
- */
- public boolean areInSamePipInput(Channel channel1, Channel channel2) {
- PipInput input1 = getPipInput(channel1);
- PipInput input2 = getPipInput(channel2);
- return input1 != null && input2 != null
- && getPipInput(channel1).equals(getPipInput(channel2));
- }
-
- private void initializePipInputList() {
- boolean hasTunerInput = false;
- for (TvInputInfo input : mInputManager.getTvInputInfos(false, false)) {
- if (input.isPassthroughInput()) {
- boolean available = mInputManager.getInputState(input)
- == TvInputManager.INPUT_STATE_CONNECTED;
- mPipInputMap.put(input.getId(), new PipInput(input.getId(), available));
- } else if (!hasTunerInput) {
- hasTunerInput = true;
- boolean available = mChannelTuner.getBrowsableChannelCount() != 0;
- mPipInputMap.put(TUNER_INPUT_ID, new PipInput(TUNER_INPUT_ID, available));
- }
- }
- PipInput input = getPipInput(mChannelTuner.getCurrentChannel());
- if (input != null) {
- input.updateAvailability();
- }
- for (Listener l : mListeners) {
- l.onPipInputListUpdated();
- }
- }
-
- /**
- * Listeners to notify PIP input state changes.
- */
- public interface Listener {
- /**
- * Called when the state (availability) of PIP inputs is changed.
- */
- void onPipInputStateUpdated();
-
- /**
- * Called when the list of PIP inputs is changed.
- */
- void onPipInputListUpdated();
- }
-
- /**
- * Input class for PIP. It has useful methods for PIP handling.
- */
- public class PipInput {
- private final String mInputId;
- private final boolean mIsPassthrough;
- private final TvInputInfo mInputInfo;
- private boolean mAvailable;
-
- private PipInput(String inputId, boolean available) {
- mInputId = inputId;
- mIsPassthrough = !mInputId.equals(TUNER_INPUT_ID);
- if (mIsPassthrough) {
- mInputInfo = mInputManager.getTvInputInfo(mInputId);
- } else {
- mInputInfo = null;
- }
- mAvailable = available;
- }
-
- /**
- * Returns the {@link TvInputInfo} object that matches to this PIP input.
- */
- public TvInputInfo getInputInfo() {
- return mInputInfo;
- }
-
- /**
- * Returns {@code true}, if the input is available for PIP. If a channel of an input is
- * already played or an input is not connected state or there is no browsable channel, the
- * input is unavailable.
- */
- public boolean isAvailable() {
- return mAvailable;
- }
-
- /**
- * Returns true, if the input is a passthrough TV input.
- */
- public boolean isPassthrough() {
- return mIsPassthrough;
- }
-
- /**
- * Gets a channel to play in a PIP view.
- */
- public Channel getChannel() {
- if (mIsPassthrough) {
- return Channel.createPassthroughChannel(mInputId);
- } else {
- return mChannelTuner.findNearestBrowsableChannel(
- Utils.getLastWatchedChannelId(mContext));
- }
- }
-
- /**
- * Gets a label of the input.
- */
- public String getLabel() {
- if (mIsPassthrough) {
- return mInputInfo.loadLabel(mContext).toString();
- } else {
- return mContext.getString(R.string.input_selector_tuner_label);
- }
- }
-
- /**
- * Gets a long label including a customized label.
- */
- public String getLongLabel() {
- if (mIsPassthrough) {
- String customizedLabel = Utils.loadLabel(mContext, mInputInfo);
- String label = getLabel();
- if (label.equals(customizedLabel)) {
- return customizedLabel;
- }
- return customizedLabel + " (" + label + ")";
- } else {
- return mContext.getString(R.string.input_long_label_for_tuner);
- }
- }
-
- /**
- * Updates availability. It returns true, if availability is changed.
- */
- private void updateAvailability() {
- boolean available;
- // current playing input cannot be available for PIP.
- Channel currentChannel = mChannelTuner.getCurrentChannel();
- if (mIsPassthrough) {
- if (currentChannel != null && currentChannel.getInputId().equals(mInputId)) {
- available = false;
- } else {
- available = mInputManager.getInputState(mInputId)
- == TvInputManager.INPUT_STATE_CONNECTED;
- }
- } else {
- if (currentChannel != null && !currentChannel.isPassthrough()) {
- available = false;
- } else {
- available = mChannelTuner.getBrowsableChannelCount() > 0;
- }
- }
- if (mAvailable != available) {
- mAvailable = available;
- for (Listener l : mListeners) {
- l.onPipInputStateUpdated();
- }
- }
- }
-
- private boolean isHidden() {
- // mInputInfo is null for the tuner input and it's always visible.
- return mInputInfo != null && mInputInfo.isHidden(mContext);
- }
- }
-}
diff --git a/src/com/android/tv/util/RecurringRunner.java b/src/com/android/tv/util/RecurringRunner.java
index 4135bd4e..8b45131b 100644
--- a/src/com/android/tv/util/RecurringRunner.java
+++ b/src/com/android/tv/util/RecurringRunner.java
@@ -57,12 +57,15 @@ public final class RecurringRunner {
mHandler = new Handler(mContext.getMainLooper());
}
- public void start() {
+ public void start(boolean resetNextRunTime) {
SoftPreconditions.checkState(!mRunning, TAG, mName + " start is called twice.");
if (mRunning) {
return;
}
mRunning = true;
+ if (resetNextRunTime) {
+ resetNextRunTime();
+ }
new AsyncTask<Void, Void, Long>() {
@Override
protected Long doInBackground(Void... params) {
@@ -76,6 +79,10 @@ public final class RecurringRunner {
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
+ public void start() {
+ start(false);
+ }
+
public void stop() {
mRunning = false;
mHandler.removeCallbacksAndMessages(null);
diff --git a/src/com/android/tv/util/SearchManagerHelper.java b/src/com/android/tv/util/SearchManagerHelper.java
deleted file mode 100644
index b6e34d7a..00000000
--- a/src/com/android/tv/util/SearchManagerHelper.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.util;
-
-import android.app.SearchManager;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.util.Log;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * A convenience class for calling methods in android.app.SearchManager.
- */
-public final class SearchManagerHelper {
- private static final String TAG = "SearchManagerHelper";
-
- private static final Object sLock = new Object();
- private static SearchManagerHelper sInstance;
-
- private final SearchManager mSearchManager;
-
- private SearchManagerHelper(Context context) {
- mSearchManager = ((android.app.SearchManager) context.getSystemService(
- Context.SEARCH_SERVICE));
- }
-
- public static SearchManagerHelper getInstance(Context context) {
- synchronized (sLock) {
- if (sInstance == null) {
- sInstance = new SearchManagerHelper(context.getApplicationContext());
- }
- return sInstance;
- }
- }
-
- public void launchAssistAction() {
- try {
- SearchManager.class.getDeclaredMethod("launchLegacyAssist", String.class, Integer.TYPE,
- Bundle.class).invoke(mSearchManager, null, UserHandle.myUserId(), null);
- } catch (NoSuchMethodException | IllegalArgumentException | IllegalAccessException
- | InvocationTargetException e) {
- Log.e(TAG, "Fail to call SearchManager.launchAssistAction", e);
- }
- }
-}
diff --git a/src/com/android/tv/util/SetupUtils.java b/src/com/android/tv/util/SetupUtils.java
index 8223a81c..32e3a81f 100644
--- a/src/com/android/tv/util/SetupUtils.java
+++ b/src/com/android/tv/util/SetupUtils.java
@@ -37,8 +37,6 @@ import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.epg.EpgFetcher;
-import com.android.tv.experiments.Experiments;
import com.android.tv.tuner.tvinput.TunerTvInputService;
import java.util.Collections;
@@ -114,7 +112,7 @@ public class SetupUtils {
@Override
public void onLoadFinished() {
manager.removeListener(this);
- updateChannelBrowsable(mTvApplication, inputId, postRunnable);
+ updateChannelsAfterSetup(mTvApplication, inputId, postRunnable);
}
@Override
@@ -124,17 +122,18 @@ public class SetupUtils {
public void onChannelBrowsableChanged() { }
});
} else {
- updateChannelBrowsable(mTvApplication, inputId, postRunnable);
+ updateChannelsAfterSetup(mTvApplication, inputId, postRunnable);
}
}
- private static void updateChannelBrowsable(Context context, final String inputId,
+ private static void updateChannelsAfterSetup(Context context, final String inputId,
final Runnable postRunnable) {
ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
final ChannelDataManager manager = appSingletons.getChannelDataManager();
manager.updateChannels(new Runnable() {
@Override
public void run() {
+ Channel firstChannelForInput = null;
boolean browsableChanged = false;
for (Channel channel : manager.getChannelList()) {
if (channel.getInputId().equals(inputId)) {
@@ -142,8 +141,14 @@ public class SetupUtils {
manager.updateBrowsable(channel.getId(), true, true);
browsableChanged = true;
}
+ if (firstChannelForInput == null) {
+ firstChannelForInput = channel;
+ }
}
}
+ if (firstChannelForInput != null) {
+ Utils.setLastWatchedChannel(context, firstChannelForInput);
+ }
if (browsableChanged) {
manager.notifyChannelBrowsableChanged();
manager.applyUpdatedValuesToDb();
@@ -382,13 +387,5 @@ public class SetupUtils {
mSetUpInputs.add(inputId);
mSharedPreferences.edit().putStringSet(PREF_KEY_SET_UP_INPUTS, mSetUpInputs).apply();
}
- // Start fetching program guide data for internal tuners.
- Context context = mTvApplication.getApplicationContext();
- if (Utils.isInternalTvInput(context, inputId)) {
- if (context.checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION)
- == PackageManager.PERMISSION_GRANTED && Experiments.CLOUD_EPG.get()) {
- EpgFetcher.getInstance(context).startImmediately();
- }
- }
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/util/StringUtils.java b/src/com/android/tv/util/StringUtils.java
new file mode 100644
index 00000000..659807e2
--- /dev/null
+++ b/src/com/android/tv/util/StringUtils.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 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.tv.util;
+
+/**
+ * Utility class for handling {@link String}.
+ */
+public final class StringUtils {
+
+ private StringUtils() { }
+
+ /**
+ * Returns compares two strings lexicographically and handles null values quietly.
+ */
+ public static int compare(String a, String b) {
+ if (a == null) {
+ return b == null ? 0 : -1;
+ }
+ if (b == null) {
+ return 1;
+ }
+ return a.compareTo(b);
+ }
+}
diff --git a/src/com/android/tv/util/TimeShiftUtils.java b/src/com/android/tv/util/TimeShiftUtils.java
index 238d0e74..8038a78f 100644
--- a/src/com/android/tv/util/TimeShiftUtils.java
+++ b/src/com/android/tv/util/TimeShiftUtils.java
@@ -18,7 +18,6 @@ package com.android.tv.util;
import java.util.concurrent.TimeUnit;
-// TODO: move related functions in TimeShiftManger here.
/**
* A class that includes convenience methods for time shift plays.
*/
@@ -40,7 +39,7 @@ public class TimeShiftUtils {
* Returns real speeds used in time shift play. This method is only for fast-forwarding and
* rewinding. The normal play speed is not addressed here.
*
- * @param speedLevel the valid value is ranged from 0 to {@link MAX_SPPED_LEVEL}.
+ * @param speedLevel the valid value is ranged from 0 to {@link #MAX_SPEED_LEVEL}.
* @param programDurationMillis the length of program under playing.
* @throws IndexOutOfBoundsException if speed level is out of its range.
*/
@@ -60,4 +59,3 @@ public class TimeShiftUtils {
: SHORT_PROGRAM_SPEED_FACTORS[MAX_SPEED_LEVEL];
}
}
-
diff --git a/src/com/android/tv/util/TvInputManagerHelper.java b/src/com/android/tv/util/TvInputManagerHelper.java
index 121f56ed..730a985b 100644
--- a/src/com/android/tv/util/TvInputManagerHelper.java
+++ b/src/com/android/tv/util/TvInputManagerHelper.java
@@ -18,20 +18,26 @@ package com.android.tv.util;
import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.hardware.hdmi.HdmiDeviceInfo;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputManager.TvInputCallback;
import android.os.Handler;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.Log;
import com.android.tv.Features;
import com.android.tv.common.SoftPreconditions;
+import com.android.tv.common.TvCommonUtils;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -42,14 +48,64 @@ import java.util.Map;
public class TvInputManagerHelper {
private static final String TAG = "TvInputManagerHelper";
private static final boolean DEBUG = false;
+
+ /**
+ * Types of HDMI device and bundled tuner.
+ */
+ public static final int TYPE_CEC_DEVICE = -2;
+ public static final int TYPE_BUNDLED_TUNER = -3;
+ public static final int TYPE_CEC_DEVICE_RECORDER = -4;
+ public static final int TYPE_CEC_DEVICE_PLAYBACK = -5;
+ public static final int TYPE_MHL_MOBILE = -6;
+
+ private static final String PERMISSION_ACCESS_ALL_EPG_DATA =
+ "com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA";
+ private static final String [] mPhysicalTunerBlackList = {
+ };
+ private static final String META_LABEL_SORT_KEY = "input_sort_key";
+
+ /**
+ * The default tv input priority to show.
+ */
+ private static final ArrayList<Integer> DEFAULT_TV_INPUT_PRIORITY = new ArrayList<>();
+ static {
+ DEFAULT_TV_INPUT_PRIORITY.add(TYPE_BUNDLED_TUNER);
+ DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_TUNER);
+ DEFAULT_TV_INPUT_PRIORITY.add(TYPE_CEC_DEVICE);
+ DEFAULT_TV_INPUT_PRIORITY.add(TYPE_CEC_DEVICE_RECORDER);
+ DEFAULT_TV_INPUT_PRIORITY.add(TYPE_CEC_DEVICE_PLAYBACK);
+ DEFAULT_TV_INPUT_PRIORITY.add(TYPE_MHL_MOBILE);
+ DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_HDMI);
+ DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_DVI);
+ DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_COMPONENT);
+ DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_SVIDEO);
+ DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_COMPOSITE);
+ DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_DISPLAY_PORT);
+ DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_VGA);
+ DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_SCART);
+ DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_OTHER);
+ }
+
private static final String[] PARTNER_TUNER_INPUT_PREFIX_BLACKLIST = {
};
+ private static final String[] TESTABLE_INPUTS = {
+ "com.android.tv.testinput/.TestTvInputService"
+ };
+
private final Context mContext;
+ private final PackageManager mPackageManager;
private final TvInputManager mTvInputManager;
private final Map<String, Integer> mInputStateMap = new HashMap<>();
private final Map<String, TvInputInfo> mInputMap = new HashMap<>();
+ private final Map<String, String> mTvInputLabels = new ArrayMap<>();
+ private final Map<String, String> mTvInputCustomLabels = new ArrayMap<>();
private final Map<String, Boolean> mInputIdToPartnerInputMap = new HashMap<>();
+
+ private final Map<String, CharSequence> mTvInputApplicationLabels = new ArrayMap<>();
+ private final Map<String, Drawable> mTvInputApplicationIcons = new ArrayMap<>();
+ private final Map<String, Drawable> mTvInputAppliactionBanners = new ArrayMap<>();
+
private final TvInputCallback mInternalCallback = new TvInputCallback() {
@Override
public void onInputStateChanged(String inputId, int state) {
@@ -72,6 +128,11 @@ public class TvInputManagerHelper {
TvInputInfo info = mTvInputManager.getTvInputInfo(inputId);
if (info != null) {
mInputMap.put(inputId, info);
+ mTvInputLabels.put(inputId, info.loadLabel(mContext).toString());
+ CharSequence inputCustomLabel = info.loadCustomLabel(mContext);
+ if (inputCustomLabel != null) {
+ mTvInputCustomLabels.put(inputId, inputCustomLabel.toString());
+ }
mInputStateMap.put(inputId, mTvInputManager.getInputState(inputId));
mInputIdToPartnerInputMap.put(inputId, isPartnerInput(info));
}
@@ -85,6 +146,11 @@ public class TvInputManagerHelper {
public void onInputRemoved(String inputId) {
if (DEBUG) Log.d(TAG, "onInputRemoved " + inputId);
mInputMap.remove(inputId);
+ mTvInputLabels.remove(inputId);
+ mTvInputCustomLabels.remove(inputId);
+ mTvInputApplicationLabels.remove(inputId);
+ mTvInputApplicationIcons.remove(inputId);
+ mTvInputAppliactionBanners.remove(inputId);
mInputStateMap.remove(inputId);
mInputIdToPartnerInputMap.remove(inputId);
mContentRatingsManager.update();
@@ -103,6 +169,14 @@ public class TvInputManagerHelper {
}
TvInputInfo info = mTvInputManager.getTvInputInfo(inputId);
mInputMap.put(inputId, info);
+ mTvInputLabels.put(inputId, info.loadLabel(mContext).toString());
+ CharSequence inputCustomLabel = info.loadCustomLabel(mContext);
+ if (inputCustomLabel != null) {
+ mTvInputCustomLabels.put(inputId, inputCustomLabel.toString());
+ }
+ mTvInputApplicationLabels.remove(inputId);
+ mTvInputApplicationIcons.remove(inputId);
+ mTvInputAppliactionBanners.remove(inputId);
for (TvInputCallback callback : mCallbacks) {
callback.onInputUpdated(inputId);
}
@@ -114,6 +188,11 @@ public class TvInputManagerHelper {
public void onTvInputInfoUpdated(TvInputInfo inputInfo) {
if (DEBUG) Log.d(TAG, "onTvInputInfoUpdated " + inputInfo);
mInputMap.put(inputInfo.getId(), inputInfo);
+ mTvInputLabels.put(inputInfo.getId(), inputInfo.loadLabel(mContext).toString());
+ CharSequence inputCustomLabel = inputInfo.loadCustomLabel(mContext);
+ if (inputCustomLabel != null) {
+ mTvInputCustomLabels.put(inputInfo.getId(), inputCustomLabel.toString());
+ }
for (TvInputCallback callback : mCallbacks) {
callback.onTvInputInfoUpdated(inputInfo);
}
@@ -131,13 +210,18 @@ public class TvInputManagerHelper {
public TvInputManagerHelper(Context context) {
mContext = context.getApplicationContext();
+ mPackageManager = context.getPackageManager();
mTvInputManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
mContentRatingsManager = new ContentRatingsManager(context);
mParentalControlSettings = new ParentalControlSettings(context);
- mTvInputInfoComparator = new TvInputInfoComparator(this);
+ mTvInputInfoComparator = new InputComparatorInternal(this);
}
public void start() {
+ if (!hasTvInputManager()) {
+ // Not a TV device
+ return;
+ }
if (mStarted) {
return;
}
@@ -145,6 +229,11 @@ public class TvInputManagerHelper {
mStarted = true;
mTvInputManager.registerCallback(mInternalCallback, mHandler);
mInputMap.clear();
+ mTvInputLabels.clear();
+ mTvInputCustomLabels.clear();
+ mTvInputApplicationLabels.clear();
+ mTvInputApplicationIcons.clear();
+ mTvInputAppliactionBanners.clear();
mInputStateMap.clear();
mInputIdToPartnerInputMap.clear();
for (TvInputInfo input : mTvInputManager.getTvInputList()) {
@@ -171,9 +260,23 @@ public class TvInputManagerHelper {
mStarted = false;
mInputStateMap.clear();
mInputMap.clear();
+ mTvInputLabels.clear();
+ mTvInputCustomLabels.clear();
+ mTvInputApplicationLabels.clear();
+ mTvInputApplicationIcons.clear();
+ mTvInputAppliactionBanners.clear();;
mInputIdToPartnerInputMap.clear();
}
+ /**
+ * Clears the TvInput labels map.
+ */
+ public void clearTvInputLabels() {
+ mTvInputLabels.clear();
+ mTvInputCustomLabels.clear();
+ mTvInputApplicationLabels.clear();
+ }
+
public List<TvInputInfo> getTvInputInfos(boolean availableOnly, boolean tunerOnly) {
ArrayList<TvInputInfo> list = new ArrayList<>();
for (Map.Entry<String, Integer> pair : mInputStateMap.entrySet()) {
@@ -192,7 +295,7 @@ public class TvInputManagerHelper {
/**
* Returns the default comparator for {@link TvInputInfo}.
- * See {@link TvInputInfoComparator} for detail.
+ * See {@link InputComparatorInternal} for detail.
*/
public Comparator<TvInputInfo> getDefaultTvInputInfoComparator() {
return mTvInputInfoComparator;
@@ -237,15 +340,81 @@ public class TvInputManagerHelper {
}
/**
- * Loads label of {@code info}.
+ * Is (Context.TV_INPUT_SERVICE) available.
*
- * It's visible for comparator test to mock TvInputInfo.
- * Package private is enough for this method, but public is necessary to workaround mockito
- * bug.
+ * <p>This is only available on TV devices.
+ */
+ public boolean hasTvInputManager() {
+ return mTvInputManager != null;
+ }
+
+ /**
+ * Loads label of {@code info}.
*/
- @VisibleForTesting
public String loadLabel(TvInputInfo info) {
- return info.loadLabel(mContext).toString();
+ String label = mTvInputLabels.get(info.getId());
+ if (label == null) {
+ label = info.loadLabel(mContext).toString();
+ mTvInputLabels.put(info.getId(), label);
+ }
+ return label;
+ }
+
+ /**
+ * Loads custom label of {@code info}
+ */
+ public String loadCustomLabel(TvInputInfo info) {
+ String customLabel = mTvInputCustomLabels.get(info.getId());
+ if (customLabel == null) {
+ CharSequence customLabelCharSequence = info.loadCustomLabel(mContext);
+ if (customLabelCharSequence != null) {
+ customLabel = customLabelCharSequence.toString();
+ mTvInputCustomLabels.put(info.getId(), customLabel);
+ }
+ }
+ return customLabel;
+ }
+
+ /**
+ * Gets the tv input application's label.
+ */
+ public CharSequence getTvInputApplicationLabel(CharSequence inputId) {
+ return mTvInputApplicationLabels.get(inputId);
+ }
+
+ /**
+ * Stores the tv input application's label.
+ */
+ public void setTvInputApplicationLabel(String inputId, CharSequence label) {
+ mTvInputApplicationLabels.put(inputId, label);
+ }
+
+ /**
+ * Gets the tv input application's icon.
+ */
+ public Drawable getTvInputApplicationIcon(String inputId) {
+ return mTvInputApplicationIcons.get(inputId);
+ }
+
+ /**
+ * Stores the tv input application's icon.
+ */
+ public void setTvInputApplicationIcon(String inputId, Drawable icon) {
+ mTvInputApplicationIcons.put(inputId, icon);
+ }
+
+ /**
+ * Gets the tv input application's banner.
+ */
+ public Drawable getTvInputApplicationBanner(String inputId) {
+ return mTvInputAppliactionBanners.get(inputId);
+ }
+
+ /**
+ * Stores the tv input application's banner.
+ */
+ public void setTvInputApplicationBanner(String inputId, Drawable banner) {
+ mTvInputAppliactionBanners.put(inputId, banner);
}
/**
@@ -321,14 +490,54 @@ public class TvInputManagerHelper {
return mContentRatingsManager;
}
- private boolean isInBlackList(String inputId) {
- if (!Features.USE_PARTNER_INPUT_BLACKLIST.isEnabled(mContext)) {
+ private int getInputSortKey(TvInputInfo input) {
+ return input.getServiceInfo().metaData.getInt(META_LABEL_SORT_KEY,
+ Integer.MAX_VALUE);
+ }
+
+ private boolean isInputPhysicalTuner(TvInputInfo input) {
+ String packageName = input.getServiceInfo().packageName;
+ if (Arrays.asList(mPhysicalTunerBlackList).contains(packageName)) {
return false;
}
- for (String disabledTunerInputPrefix : PARTNER_TUNER_INPUT_PREFIX_BLACKLIST) {
- if (inputId.contains(disabledTunerInputPrefix)) {
- return true;
+
+ if (input.createSetupIntent() == null) {
+ return false;
+ } else {
+ boolean mayBeTunerInput = mPackageManager.checkPermission(
+ PERMISSION_ACCESS_ALL_EPG_DATA, input.getServiceInfo().packageName)
+ == PackageManager.PERMISSION_GRANTED;
+ if (!mayBeTunerInput) {
+ try {
+ ApplicationInfo ai = mPackageManager.getApplicationInfo(
+ input.getServiceInfo().packageName, 0);
+ if ((ai.flags & (ApplicationInfo.FLAG_SYSTEM
+ | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) == 0) {
+ return false;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean isInBlackList(String inputId) {
+ if (Features.USE_PARTNER_INPUT_BLACKLIST.isEnabled(mContext)) {
+ for (String disabledTunerInputPrefix : PARTNER_TUNER_INPUT_PREFIX_BLACKLIST) {
+ if (inputId.contains(disabledTunerInputPrefix)) {
+ return true;
+ }
+ }
+ }
+ if (TvCommonUtils.isRunningInTest()) {
+ for (String testableInput : TESTABLE_INPUTS) {
+ if (testableInput.equals(inputId)) {
+ return false;
+ }
}
+ return true;
}
return false;
}
@@ -342,10 +551,10 @@ public class TvInputManagerHelper {
* (i.e. Mockito's spy doesn't work)
*/
@VisibleForTesting
- static class TvInputInfoComparator implements Comparator<TvInputInfo> {
+ static class InputComparatorInternal implements Comparator<TvInputInfo> {
private final TvInputManagerHelper mInputManager;
- public TvInputInfoComparator(TvInputManagerHelper inputManager) {
+ public InputComparatorInternal(TvInputManagerHelper inputManager) {
mInputManager = inputManager;
}
@@ -357,4 +566,123 @@ public class TvInputManagerHelper {
return mInputManager.loadLabel(lhs).compareTo(mInputManager.loadLabel(rhs));
}
}
+
+ /**
+ * A comparator used for {@link com.android.tv.ui.SelectInputView} to show the list of
+ * TV inputs.
+ */
+ public static class HardwareInputComparator implements Comparator<TvInputInfo> {
+ private Map<Integer, Integer> mTypePriorities = new HashMap<>();
+ private final TvInputManagerHelper mTvInputManagerHelper;
+ private final Context mContext;
+
+ public HardwareInputComparator(Context context, TvInputManagerHelper tvInputManagerHelper) {
+ mContext = context;
+ mTvInputManagerHelper = tvInputManagerHelper;
+ setupDeviceTypePriorities();
+ }
+
+ @Override
+ public int compare(TvInputInfo lhs, TvInputInfo rhs) {
+ if (lhs == null) {
+ return (rhs == null) ? 0 : 1;
+ }
+ if (rhs == null) {
+ return -1;
+ }
+
+ boolean enabledL = (mTvInputManagerHelper.getInputState(lhs)
+ != TvInputManager.INPUT_STATE_DISCONNECTED);
+ boolean enabledR = (mTvInputManagerHelper.getInputState(rhs)
+ != TvInputManager.INPUT_STATE_DISCONNECTED);
+ if (enabledL != enabledR) {
+ return enabledL ? -1 : 1;
+ }
+
+ int priorityL = getPriority(lhs);
+ int priorityR = getPriority(rhs);
+ if (priorityL != priorityR) {
+ return priorityL - priorityR;
+ }
+
+ if (lhs.getType() == TvInputInfo.TYPE_TUNER
+ && rhs.getType() == TvInputInfo.TYPE_TUNER) {
+ boolean isPhysicalL = mTvInputManagerHelper.isInputPhysicalTuner(lhs);
+ boolean isPhysicalR = mTvInputManagerHelper.isInputPhysicalTuner(rhs);
+ if (isPhysicalL != isPhysicalR) {
+ return isPhysicalL ? -1 : 1;
+ }
+ }
+
+ int sortKeyL = mTvInputManagerHelper.getInputSortKey(lhs);
+ int sortKeyR = mTvInputManagerHelper.getInputSortKey(rhs);
+ if (sortKeyL != sortKeyR) {
+ return sortKeyR - sortKeyL;
+ }
+
+ String parentLabelL = lhs.getParentId() != null
+ ? getLabel(mTvInputManagerHelper.getTvInputInfo(lhs.getParentId()))
+ : getLabel(mTvInputManagerHelper.getTvInputInfo(lhs.getId()));
+ String parentLabelR = rhs.getParentId() != null
+ ? getLabel(mTvInputManagerHelper.getTvInputInfo(rhs.getParentId()))
+ : getLabel(mTvInputManagerHelper.getTvInputInfo(rhs.getId()));
+
+ if (!TextUtils.equals(parentLabelL, parentLabelR)) {
+ return parentLabelL.compareToIgnoreCase(parentLabelR);
+ }
+ return getLabel(lhs).compareToIgnoreCase(getLabel(rhs));
+ }
+
+ private String getLabel(TvInputInfo input) {
+ if (input == null) {
+ return "";
+ }
+ String label = mTvInputManagerHelper.loadCustomLabel(input);
+ if (TextUtils.isEmpty(label)) {
+ label = mTvInputManagerHelper.loadLabel(input);
+ }
+ return label;
+ }
+
+ private int getPriority(TvInputInfo info) {
+ Integer priority = null;
+ if (mTypePriorities != null) {
+ priority = mTypePriorities.get(getTvInputTypeForPriority(info));
+ }
+ if (priority != null) {
+ return priority;
+ }
+ return Integer.MAX_VALUE;
+ }
+
+ private void setupDeviceTypePriorities() {
+ mTypePriorities = Partner.getInstance(mContext).getInputsOrderMap();
+
+ // Fill in any missing priorities in the map we got from the OEM
+ int priority = mTypePriorities.size();
+ for (int type : DEFAULT_TV_INPUT_PRIORITY) {
+ if (!mTypePriorities.containsKey(type)) {
+ mTypePriorities.put(type, priority++);
+ }
+ }
+ }
+
+ private int getTvInputTypeForPriority(TvInputInfo info) {
+ if (info.getHdmiDeviceInfo() != null) {
+ if (info.getHdmiDeviceInfo().isCecDevice()) {
+ switch (info.getHdmiDeviceInfo().getDeviceType()) {
+ case HdmiDeviceInfo.DEVICE_RECORDER:
+ return TYPE_CEC_DEVICE_RECORDER;
+ case HdmiDeviceInfo.DEVICE_PLAYBACK:
+ return TYPE_CEC_DEVICE_PLAYBACK;
+ default:
+ return TYPE_CEC_DEVICE;
+ }
+ } else if (info.getHdmiDeviceInfo().isMhlDevice()) {
+ return TYPE_MHL_MOBILE;
+ }
+ }
+ return info.getType();
+ }
+ }
}
diff --git a/src/com/android/tv/util/TvProviderUriMatcher.java b/src/com/android/tv/util/TvProviderUriMatcher.java
deleted file mode 100644
index 749e4aa3..00000000
--- a/src/com/android/tv/util/TvProviderUriMatcher.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.util;
-
-import android.content.UriMatcher;
-import android.media.tv.TvContract;
-import android.net.Uri;
-import android.support.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Utility class to aid in matching URIs in TvProvider.
- */
-public class TvProviderUriMatcher {
- private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({MATCH_CHANNEL, MATCH_CHANNEL_ID, MATCH_PROGRAM, MATCH_PROGRAM_ID,
- MATCH_RECORDED_PROGRAM, MATCH_RECORDED_PROGRAM_ID, MATCH_WATCHED_PROGRAM_ID})
- private @interface TvProviderUriMatchCode {}
- /** The code for the channels URI. */
- public static final int MATCH_CHANNEL = 1;
- /** The code for the channel URI. */
- public static final int MATCH_CHANNEL_ID = 2;
- /** The code for the programs URI. */
- public static final int MATCH_PROGRAM = 3;
- /** The code for the program URI. */
- public static final int MATCH_PROGRAM_ID = 4;
- /** The code for the recorded programs URI. */
- public static final int MATCH_RECORDED_PROGRAM = 5;
- /** The code for the recorded program URI. */
- public static final int MATCH_RECORDED_PROGRAM_ID = 6;
- /** The code for the watched program URI. */
- public static final int MATCH_WATCHED_PROGRAM_ID = 7;
- static {
- URI_MATCHER.addURI(TvContract.AUTHORITY, "channel", MATCH_CHANNEL);
- URI_MATCHER.addURI(TvContract.AUTHORITY, "channel/#", MATCH_CHANNEL_ID);
- URI_MATCHER.addURI(TvContract.AUTHORITY, "program", MATCH_PROGRAM);
- URI_MATCHER.addURI(TvContract.AUTHORITY, "program/#", MATCH_PROGRAM_ID);
- URI_MATCHER.addURI(TvContract.AUTHORITY, "recorded_program", MATCH_RECORDED_PROGRAM);
- URI_MATCHER.addURI(TvContract.AUTHORITY, "recorded_program/#", MATCH_RECORDED_PROGRAM_ID);
- URI_MATCHER.addURI(TvContract.AUTHORITY, "watched_program/#", MATCH_WATCHED_PROGRAM_ID);
- }
-
- private TvProviderUriMatcher() { }
-
- /**
- * Try to match against the path in a url.
- *
- * @see UriMatcher#match
- */
- @SuppressWarnings("WrongConstant")
- @TvProviderUriMatchCode public static int match(Uri uri) {
- return URI_MATCHER.match(uri);
- }
-}
diff --git a/src/com/android/tv/util/TvSettings.java b/src/com/android/tv/util/TvSettings.java
index 97ff59d6..c5fde317 100644
--- a/src/com/android/tv/util/TvSettings.java
+++ b/src/com/android/tv/util/TvSettings.java
@@ -17,6 +17,8 @@
package com.android.tv.util;
import android.content.Context;
+import android.content.SharedPreferences;
+import android.media.tv.TvTrackInfo;
import android.preference.PreferenceManager;
import android.support.annotation.IntDef;
@@ -26,53 +28,27 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
-
/**
* A class about the constants for TV settings.
* Objects that are returned from the various {@code get} methods must be treated as immutable.
*/
public final class TvSettings {
- private TvSettings() {}
-
public static final String PREF_DISPLAY_MODE = "display_mode"; // int value
- public static final String PREF_PIP_LAYOUT = "pip_layout"; // int value
- public static final String PREF_PIP_SIZE = "pip_size"; // int value
public static final String PREF_PIN = "pin"; // 4-digit string value. Otherwise, it's not set.
- // PIP sounds
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({
- PIP_SOUND_MAIN, PIP_SOUND_PIP_WINDOW })
- public @interface PipSound {}
- public static final int PIP_SOUND_MAIN = 0;
- public static final int PIP_SOUND_PIP_WINDOW = PIP_SOUND_MAIN + 1;
-
- // PIP layouts
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({
- PIP_LAYOUT_BOTTOM_RIGHT, PIP_LAYOUT_TOP_RIGHT, PIP_LAYOUT_TOP_LEFT,
- PIP_LAYOUT_BOTTOM_LEFT, PIP_LAYOUT_SIDE_BY_SIDE })
- public @interface PipLayout {}
- public static final int PIP_LAYOUT_BOTTOM_RIGHT = 0;
- public static final int PIP_LAYOUT_TOP_RIGHT = PIP_LAYOUT_BOTTOM_RIGHT + 1;
- public static final int PIP_LAYOUT_TOP_LEFT = PIP_LAYOUT_TOP_RIGHT + 1;
- public static final int PIP_LAYOUT_BOTTOM_LEFT = PIP_LAYOUT_TOP_LEFT + 1;
- public static final int PIP_LAYOUT_SIDE_BY_SIDE = PIP_LAYOUT_BOTTOM_LEFT + 1;
- public static final int PIP_LAYOUT_LAST = PIP_LAYOUT_SIDE_BY_SIDE;
-
- // PIP sizes
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({ PIP_SIZE_SMALL, PIP_SIZE_BIG })
- public @interface PipSize {}
- public static final int PIP_SIZE_SMALL = 0;
- public static final int PIP_SIZE_BIG = PIP_SIZE_SMALL + 1;
- public static final int PIP_SIZE_LAST = PIP_SIZE_BIG;
-
// Multi-track audio settings
private static final String PREF_MULTI_AUDIO_ID = "pref.multi_audio_id";
private static final String PREF_MULTI_AUDIO_LANGUAGE = "pref.multi_audio_language";
private static final String PREF_MULTI_AUDIO_CHANNEL_COUNT = "pref.multi_audio_channel_count";
+ // DVR Multi-audio and subtitle settings
+ private static final String PREF_DVR_MULTI_AUDIO_ID = "pref.dvr_multi_audio_id";
+ private static final String PREF_DVR_MULTI_AUDIO_LANGUAGE = "pref.dvr_multi_audio_language";
+ private static final String PREF_DVR_MULTI_AUDIO_CHANNEL_COUNT =
+ "pref.dvr_multi_audio_channel_count";
+ private static final String PREF_DVR_SUBTITLE_ID = "pref.dvr_subtitle_id";
+ private static final String PREF_DVR_SUBTITLE_LANGUAGE = "pref.dvr_subtitle_language";
+
// Parental Control settings
private static final String PREF_CONTENT_RATING_SYSTEMS = "pref.content_rating_systems";
private static final String PREF_CONTENT_RATING_LEVEL = "pref.content_rating_level";
@@ -89,58 +65,7 @@ public final class TvSettings {
public static final int CONTENT_RATING_LEVEL_LOW = 3;
public static final int CONTENT_RATING_LEVEL_CUSTOM = 4;
- // PIP settings
- /**
- * Returns the layout of the PIP window stored in the shared preferences.
- *
- * @return the saved layout of the PIP window. This value is one of
- * {@link #PIP_LAYOUT_TOP_LEFT}, {@link #PIP_LAYOUT_TOP_RIGHT},
- * {@link #PIP_LAYOUT_BOTTOM_LEFT}, {@link #PIP_LAYOUT_BOTTOM_RIGHT} and
- * {@link #PIP_LAYOUT_SIDE_BY_SIDE}. If the preference value does not exist,
- * {@link #PIP_LAYOUT_BOTTOM_RIGHT} is returned.
- */
- @SuppressWarnings("ResourceType")
- @PipLayout
- public static int getPipLayout(Context context) {
- return PreferenceManager.getDefaultSharedPreferences(context).getInt(
- PREF_PIP_LAYOUT, PIP_LAYOUT_BOTTOM_RIGHT);
- }
-
- /**
- * Stores the layout of PIP window to the shared preferences.
- *
- * @param pipLayout This value should be one of {@link #PIP_LAYOUT_TOP_LEFT},
- * {@link #PIP_LAYOUT_TOP_RIGHT}, {@link #PIP_LAYOUT_BOTTOM_LEFT},
- * {@link #PIP_LAYOUT_BOTTOM_RIGHT} and {@link #PIP_LAYOUT_SIDE_BY_SIDE}.
- */
- public static void setPipLayout(Context context, @PipLayout int pipLayout) {
- PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(
- PREF_PIP_LAYOUT, pipLayout).apply();
- }
-
- /**
- * Returns the size of the PIP view stored in the shared preferences.
- *
- * @return the saved size of the PIP view. This value is one of
- * {@link #PIP_SIZE_SMALL} and {@link #PIP_SIZE_BIG}. If the preference value does not
- * exist, {@link #PIP_SIZE_SMALL} is returned.
- */
- @SuppressWarnings("ResourceType")
- @PipSize
- public static int getPipSize(Context context) {
- return PreferenceManager.getDefaultSharedPreferences(context).getInt(
- PREF_PIP_SIZE, PIP_SIZE_SMALL);
- }
-
- /**
- * Stores the size of PIP view to the shared preferences.
- *
- * @param pipSize This value should be one of {@link #PIP_SIZE_SMALL} and {@link #PIP_SIZE_BIG}.
- */
- public static void setPipSize(Context context, @PipSize int pipSize) {
- PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(
- PREF_PIP_SIZE, pipSize).apply();
- }
+ private TvSettings() {}
// Multi-track audio settings
public static String getMultiAudioId(Context context) {
@@ -173,26 +98,61 @@ public final class TvSettings {
PREF_MULTI_AUDIO_CHANNEL_COUNT, channelCount).apply();
}
- // Parental Control settings
- public static void addContentRatingSystems(Context context, Set<String> ids) {
- Set<String> contentRatingSystemSet = getContentRatingSystemSet(context);
- if (contentRatingSystemSet.addAll(ids)) {
- PreferenceManager.getDefaultSharedPreferences(context).edit()
- .putStringSet(PREF_CONTENT_RATING_SYSTEMS, contentRatingSystemSet).apply();
+ public static void setDvrPlaybackTrackSettings(Context context, int trackType,
+ TvTrackInfo info) {
+ if (trackType == TvTrackInfo.TYPE_AUDIO) {
+ if (info == null) {
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .remove(PREF_DVR_MULTI_AUDIO_ID).apply();
+ } else {
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .putString(PREF_DVR_MULTI_AUDIO_LANGUAGE, info.getLanguage())
+ .putInt(PREF_DVR_MULTI_AUDIO_CHANNEL_COUNT, info.getAudioChannelCount())
+ .putString(PREF_DVR_MULTI_AUDIO_ID, info.getId()).apply();
+ }
+ } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
+ if (info == null) {
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .remove(PREF_DVR_SUBTITLE_ID).apply();
+ } else {
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .putString(PREF_DVR_SUBTITLE_LANGUAGE, info.getLanguage())
+ .putString(PREF_DVR_SUBTITLE_ID, info.getId()).apply();
+ }
}
}
- public static void addContentRatingSystem(Context context, String id) {
- Set<String> contentRatingSystemSet = getContentRatingSystemSet(context);
- if (contentRatingSystemSet.add(id)) {
- PreferenceManager.getDefaultSharedPreferences(context).edit()
- .putStringSet(PREF_CONTENT_RATING_SYSTEMS, contentRatingSystemSet).apply();
+ public static TvTrackInfo getDvrPlaybackTrackSettings(Context context,
+ int trackType) {
+ String language;
+ String trackId;
+ int channelCount;
+ SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
+ if (trackType == TvTrackInfo.TYPE_AUDIO) {
+ trackId = pref.getString(PREF_DVR_MULTI_AUDIO_ID, null);
+ if (trackId == null) {
+ return null;
+ }
+ language = pref.getString(PREF_DVR_MULTI_AUDIO_LANGUAGE, null);
+ channelCount = pref.getInt(PREF_DVR_MULTI_AUDIO_CHANNEL_COUNT, 0);
+ return new TvTrackInfo.Builder(trackType, trackId)
+ .setLanguage(language).setAudioChannelCount(channelCount).build();
+ } else if (trackType == TvTrackInfo.TYPE_SUBTITLE) {
+ trackId = pref.getString(PREF_DVR_SUBTITLE_ID, null);
+ if (trackId == null) {
+ return null;
+ }
+ language = pref.getString(PREF_DVR_SUBTITLE_LANGUAGE, null);
+ return new TvTrackInfo.Builder(trackType, trackId).setLanguage(language).build();
+ } else {
+ return null;
}
}
- public static void removeContentRatingSystems(Context context, Set<String> ids) {
+ // Parental Control settings
+ public static void addContentRatingSystem(Context context, String id) {
Set<String> contentRatingSystemSet = getContentRatingSystemSet(context);
- if (contentRatingSystemSet.removeAll(ids)) {
+ if (contentRatingSystemSet.add(id)) {
PreferenceManager.getDefaultSharedPreferences(context).edit()
.putStringSet(PREF_CONTENT_RATING_SYSTEMS, contentRatingSystemSet).apply();
}
@@ -254,4 +214,4 @@ public final class TvSettings {
PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(
PREF_DISABLE_PIN_UNTIL, timeMillis).apply();
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/util/TvTrackInfoUtils.java b/src/com/android/tv/util/TvTrackInfoUtils.java
index c004f001..667cc9bf 100644
--- a/src/com/android/tv/util/TvTrackInfoUtils.java
+++ b/src/com/android/tv/util/TvTrackInfoUtils.java
@@ -52,35 +52,22 @@ public class TvTrackInfoUtils {
}
// Assumes {@code null} language matches to any language since it means user hasn't
// selected any track before or selected a track without language information.
- boolean rhsLangMatch = language == null || Utils.isEqualLanguage(rhs.getLanguage(),
- language);
boolean lhsLangMatch = language == null || Utils.isEqualLanguage(lhs.getLanguage(),
language);
- if (rhsLangMatch) {
- if (lhsLangMatch) {
- boolean rhsCountMatch = rhs.getAudioChannelCount() == channelCount;
- boolean lhsCountMatch = lhs.getAudioChannelCount() == channelCount;
- if (rhsCountMatch) {
- if (lhsCountMatch) {
- boolean rhsIdMatch = rhs.getId().equals(id);
- boolean lhsIdMatch = lhs.getId().equals(id);
- if (rhsIdMatch) {
- return lhsIdMatch ? 0 : -1;
- } else {
- return lhsIdMatch ? 1 : 0;
- }
-
- } else {
- return -1;
- }
- } else {
- return lhsCountMatch ? 1 : 0;
- }
+ boolean rhsLangMatch = language == null || Utils.isEqualLanguage(rhs.getLanguage(),
+ language);
+ if (lhsLangMatch && rhsLangMatch) {
+ boolean lhsCountMatch = lhs.getType() != TvTrackInfo.TYPE_AUDIO
+ || lhs.getAudioChannelCount() == channelCount;
+ boolean rhsCountMatch = rhs.getType() != TvTrackInfo.TYPE_AUDIO
+ || rhs.getAudioChannelCount() == channelCount;
+ if (lhsCountMatch && rhsCountMatch) {
+ return Boolean.compare(lhs.getId().equals(id), rhs.getId().equals(id));
} else {
- return -1;
+ return Boolean.compare(lhsCountMatch, rhsCountMatch);
}
} else {
- return lhsLangMatch ? 1 : 0;
+ return Boolean.compare(lhsLangMatch, rhsLangMatch);
}
}
};
@@ -112,4 +99,4 @@ public class TvTrackInfoUtils {
private TvTrackInfoUtils() {
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/tv/util/TvUriMatcher.java b/src/com/android/tv/util/TvUriMatcher.java
new file mode 100644
index 00000000..3d91cdad
--- /dev/null
+++ b/src/com/android/tv/util/TvUriMatcher.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 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.tv.util;
+
+import android.app.SearchManager;
+import android.content.UriMatcher;
+import android.media.tv.TvContract;
+import android.net.Uri;
+import android.support.annotation.IntDef;
+
+import com.android.tv.search.LocalSearchProvider;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Utility class to aid in matching URIs in TvProvider.
+ */
+public class TvUriMatcher {
+ private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({MATCH_CHANNEL, MATCH_CHANNEL_ID, MATCH_PROGRAM, MATCH_PROGRAM_ID,
+ MATCH_RECORDED_PROGRAM, MATCH_RECORDED_PROGRAM_ID, MATCH_WATCHED_PROGRAM_ID,
+ MATCH_ON_DEVICE_SEARCH})
+ private @interface TvProviderUriMatchCode {}
+ /** The code for the channels URI. */
+ public static final int MATCH_CHANNEL = 1;
+ /** The code for the channel URI. */
+ public static final int MATCH_CHANNEL_ID = 2;
+ /** The code for the programs URI. */
+ public static final int MATCH_PROGRAM = 3;
+ /** The code for the program URI. */
+ public static final int MATCH_PROGRAM_ID = 4;
+ /** The code for the recorded programs URI. */
+ public static final int MATCH_RECORDED_PROGRAM = 5;
+ /** The code for the recorded program URI. */
+ public static final int MATCH_RECORDED_PROGRAM_ID = 6;
+ /** The code for the watched program URI. */
+ public static final int MATCH_WATCHED_PROGRAM_ID = 7;
+ /** The code for the on-device search URI. */
+ public static final int MATCH_ON_DEVICE_SEARCH = 8;
+ static {
+ URI_MATCHER.addURI(TvContract.AUTHORITY, "channel", MATCH_CHANNEL);
+ URI_MATCHER.addURI(TvContract.AUTHORITY, "channel/#", MATCH_CHANNEL_ID);
+ URI_MATCHER.addURI(TvContract.AUTHORITY, "program", MATCH_PROGRAM);
+ URI_MATCHER.addURI(TvContract.AUTHORITY, "program/#", MATCH_PROGRAM_ID);
+ URI_MATCHER.addURI(TvContract.AUTHORITY, "recorded_program", MATCH_RECORDED_PROGRAM);
+ URI_MATCHER.addURI(TvContract.AUTHORITY, "recorded_program/#", MATCH_RECORDED_PROGRAM_ID);
+ URI_MATCHER.addURI(TvContract.AUTHORITY, "watched_program/#", MATCH_WATCHED_PROGRAM_ID);
+ URI_MATCHER.addURI(LocalSearchProvider.AUTHORITY,
+ SearchManager.SUGGEST_URI_PATH_QUERY + "/*", MATCH_ON_DEVICE_SEARCH);
+ }
+
+ private TvUriMatcher() { }
+
+ /**
+ * Try to match against the path in a url.
+ *
+ * @see UriMatcher#match
+ */
+ @SuppressWarnings("WrongConstant")
+ @TvProviderUriMatchCode public static int match(Uri uri) {
+ return URI_MATCHER.match(uri);
+ }
+}
diff --git a/src/com/android/tv/util/Utils.java b/src/com/android/tv/util/Utils.java
index 99d34431..d11bab3c 100644
--- a/src/com/android/tv/util/Utils.java
+++ b/src/com/android/tv/util/Utils.java
@@ -31,6 +31,7 @@ import android.media.tv.TvContract.Programs.Genres;
import android.media.tv.TvInputInfo;
import android.media.tv.TvTrackInfo;
import android.net.Uri;
+import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
@@ -44,11 +45,13 @@ import android.view.View;
import com.android.tv.ApplicationSingletons;
import com.android.tv.R;
import com.android.tv.TvApplication;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.data.GenreItems;
import com.android.tv.data.Program;
import com.android.tv.data.StreamInfo;
+import com.android.tv.experiments.Experiments;
import java.io.File;
import java.text.SimpleDateFormat;
@@ -62,6 +65,8 @@ import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
@@ -74,7 +79,6 @@ public class Utils {
private static final SimpleDateFormat ISO_8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ",
Locale.US);
- public static final String EXTRA_KEY_KEYCODE = "keycode";
public static final String EXTRA_KEY_ACTION = "action";
public static final String EXTRA_ACTION_SHOW_TV_INPUT ="show_tv_input";
public static final String EXTRA_KEY_FROM_LAUNCHER = "from_launcher";
@@ -83,11 +87,9 @@ public class Utils {
public static final String EXTRA_KEY_RECORDED_PROGRAM_PIN_CHECKED =
"recorded_program_pin_checked";
- // Query parameter in the intent of starting MainActivity.
- public static final String PARAM_SOURCE = "source";
-
private static final String PATH_CHANNEL = "channel";
private static final String PATH_PROGRAM = "program";
+ private static final String PATH_RECORDED_PROGRAM = "recorded_program";
private static final String PREF_KEY_LAST_WATCHED_CHANNEL_ID = "last_watched_channel_id";
private static final String PREF_KEY_LAST_WATCHED_CHANNEL_ID_FOR_INPUT =
@@ -97,6 +99,8 @@ public class Utils {
"last_watched_tuner_input_id";
private static final String PREF_KEY_RECORDING_FAILED_REASONS =
"recording_failed_reasons";
+ private static final String PREF_KEY_FAILED_SCHEDULED_RECORDING_INFO_SET =
+ "failed_scheduled_recording_info_set";
private static final int VIDEO_SD_WIDTH = 704;
private static final int VIDEO_SD_HEIGHT = 480;
@@ -114,6 +118,7 @@ public class Utils {
private static final int AUDIO_CHANNEL_SURROUND_8 = 8;
private static final long RECORDING_FAILED_REASON_NONE = 0;
+ private static final long HALF_MINUTE_MS = TimeUnit.SECONDS.toMillis(30);
private static final long ONE_DAY_MS = TimeUnit.DAYS.toMillis(1);
// Hardcoded list for known bundled inputs not written by OEM/SOCs.
@@ -207,6 +212,28 @@ public class Utils {
}
/**
+ * Adds the info of failed scheduled recording.
+ */
+ public static void addFailedScheduledRecordingInfo(Context context,
+ String scheduledRecordingInfo) {
+ Set<String> failedScheduledRecordingInfoSet = getFailedScheduledRecordingInfoSet(context);
+ failedScheduledRecordingInfoSet.add(scheduledRecordingInfo);
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .putStringSet(PREF_KEY_FAILED_SCHEDULED_RECORDING_INFO_SET,
+ failedScheduledRecordingInfoSet)
+ .apply();
+ }
+
+ /**
+ * Clears the failed scheduled recording info set.
+ */
+ public static void clearFailedScheduledRecordingInfoSet(Context context) {
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .remove(PREF_KEY_FAILED_SCHEDULED_RECORDING_INFO_SET)
+ .apply();
+ }
+
+ /**
* Clears recording failed reason.
*/
public static void clearRecordingFailedReason(Context context, int reason) {
@@ -246,6 +273,14 @@ public class Utils {
}
/**
+ * Returns the failed scheduled recordings info set.
+ */
+ public static Set<String> getFailedScheduledRecordingInfoSet(Context context) {
+ return PreferenceManager.getDefaultSharedPreferences(context)
+ .getStringSet(PREF_KEY_FAILED_SCHEDULED_RECORDING_INFO_SET, new HashSet<>());
+ }
+
+ /**
* Checks do recording failed reason exist.
*/
public static boolean hasRecordingFailedReason(Context context, int reason) {
@@ -296,6 +331,13 @@ public class Utils {
}
/**
+ * Returns {@code true}, if {@code uri} is a programs URI.
+ */
+ public static boolean isRecordedProgramsUri(Uri uri) {
+ return isTvUri(uri) && PATH_RECORDED_PROGRAM.equals(uri.getPathSegments().get(0));
+ }
+
+ /**
* Gets the info of the program on particular time.
*/
@WorkerThread
@@ -333,6 +375,14 @@ public class Utils {
}
/**
+ * Returns the round off minutes when convert milliseconds to minutes.
+ */
+ public static int getRoundOffMinsFromMs(long millis) {
+ // Round off the result by adding half minute to the original ms.
+ return (int) TimeUnit.MILLISECONDS.toMinutes(millis + HALF_MINUTE_MS);
+ }
+
+ /**
* Returns duration string according to the date & time format.
* If {@code startUtcMillis} and {@code endUtcMills} are equal,
* formatted time will be returned instead.
@@ -392,16 +442,18 @@ public class Utils {
: DateUtils.formatDateRange(context, startUtcMillis, endUtcMillis + 1, flag);
}
- @VisibleForTesting
+ /**
+ * Checks if two given time (in milliseconds) are in the same day with regard to the
+ * locale timezone.
+ */
public static boolean isInGivenDay(long dayToMatchInMillis, long subjectTimeInMillis) {
- final long DAY_IN_MS = TimeUnit.DAYS.toMillis(1);
TimeZone timeZone = Calendar.getInstance().getTimeZone();
long offset = timeZone.getRawOffset();
if (timeZone.inDaylightTime(new Date(dayToMatchInMillis))) {
offset += timeZone.getDSTSavings();
}
- return Utils.floorTime(dayToMatchInMillis + offset, DAY_IN_MS)
- == Utils.floorTime(subjectTimeInMillis + offset, DAY_IN_MS);
+ return Utils.floorTime(dayToMatchInMillis + offset, ONE_DAY_MS)
+ == Utils.floorTime(subjectTimeInMillis + offset, ONE_DAY_MS);
}
/**
@@ -523,7 +575,7 @@ public class Utils {
if (track.getType() != TvTrackInfo.TYPE_AUDIO) {
throw new IllegalArgumentException("Not an audio track: " + track);
}
- String language = context.getString(R.string.default_language);
+ String language = context.getString(R.string.multi_audio_unknown_language);
if (!TextUtils.isEmpty(track.getLanguage())) {
language = new Locale(track.getLanguage()).getDisplayName();
} else {
@@ -606,10 +658,12 @@ public class Utils {
if (input == null) {
return null;
}
- CharSequence customLabel = input.loadCustomLabel(context);
+ TvInputManagerHelper inputManager =
+ TvApplication.getSingletons(context).getTvInputManagerHelper();
+ CharSequence customLabel = inputManager.loadCustomLabel(input);
String label = (customLabel == null) ? null : customLabel.toString();
if (TextUtils.isEmpty(label)) {
- label = input.loadLabel(context).toString();
+ label = inputManager.loadLabel(input).toString();
}
return label;
}
@@ -860,4 +914,28 @@ public class Utils {
}
return Genres.encode(genres);
}
+
+ /**
+ * Returns true if the current user is a developer.
+ */
+ public static boolean isDeveloper() {
+ return BuildConfig.ENG || Experiments.ENABLE_DEVELOPER_FEATURES.get();
+ }
+
+ /**
+ * Runs the method in main thread. If the current thread is not main thread, block it util
+ * the method is finished.
+ */
+ public static void runInMainThreadAndWait(Runnable runnable) {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ runnable.run();
+ } else {
+ Future<?> temp = MainThreadExecutor.getInstance().submit(runnable);
+ try {
+ temp.get();
+ } catch (InterruptedException | ExecutionException e) {
+ Log.e(TAG, "failed to finish the execution", e);
+ }
+ }
+ }
}
diff --git a/src/com/android/tv/util/ViewCache.java b/src/com/android/tv/util/ViewCache.java
new file mode 100644
index 00000000..ed9a8ff6
--- /dev/null
+++ b/src/com/android/tv/util/ViewCache.java
@@ -0,0 +1,100 @@
+package com.android.tv.util;
+
+import android.content.Context;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+
+/**
+ * A cache for the views.
+ */
+public class ViewCache {
+ private final static SparseArray<ArrayList<View>> mViews = new SparseArray();
+
+ private static ViewCache sViewCache;
+
+ private ViewCache() { }
+
+ /**
+ * Returns an instance of the view cache.
+ */
+ public static ViewCache getInstance() {
+ if (sViewCache == null) {
+ sViewCache = new ViewCache();
+ }
+ return sViewCache;
+ }
+
+ /**
+ * Returns if the view cache is empty.
+ */
+ public boolean isEmpty() {
+ return mViews.size() == 0;
+ }
+
+ /**
+ * Stores a view into this view cache.
+ */
+ public void putView(int resId, View view) {
+ ArrayList<View> views = mViews.get(resId);
+ if (views == null) {
+ views = new ArrayList();
+ mViews.put(resId, views);
+ }
+ views.add(view);
+ }
+
+ /**
+ * Stores multi specific views into the view cache.
+ */
+ public void putView(Context context, int resId, ViewGroup fakeParent, int num) {
+ LayoutInflater inflater =
+ (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ ArrayList<View> views = mViews.get(resId);
+ if (views == null) {
+ views = new ArrayList<>();
+ mViews.put(resId, views);
+ }
+ for (int i = 0; i < num; i++) {
+ View view = inflater.inflate(resId, fakeParent, false);
+ views.add(view);
+ }
+ }
+
+ /**
+ * Returns the view for specific resource id.
+ */
+ public View getView(int resId) {
+ ArrayList<View> views = mViews.get(resId);
+ if (views != null && !views.isEmpty()) {
+ View view = views.remove(views.size() - 1);
+ if (views.isEmpty()) {
+ mViews.remove(resId);
+ }
+ return view;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the view if exists, or create a new view for the specific resource id.
+ */
+ public View getOrCreateView(LayoutInflater inflater, int resId, ViewGroup container) {
+ View view = getView(resId);
+ if (view == null) {
+ view = inflater.inflate(resId, container, false);
+ }
+ return view;
+ }
+
+ /**
+ * Clears the view cache.
+ */
+ public void clear() {
+ mViews.clear();
+ }
+}
diff --git a/tests/OWNERS b/tests/OWNERS
new file mode 100644
index 00000000..4aa5fe52
--- /dev/null
+++ b/tests/OWNERS
@@ -0,0 +1,2 @@
+nchalko@google.com
+shubang@google.com
diff --git a/tests/common/Android.mk b/tests/common/Android.mk
index aecd15bc..27c9f031 100644
--- a/tests/common/Android.mk
+++ b/tests/common/Android.mk
@@ -17,7 +17,7 @@ LOCAL_JAVA_LIBRARIES := tv-common
LOCAL_INSTRUMENTATION_FOR := LiveTv
LOCAL_MODULE := tv-test-common
LOCAL_MODULE_TAGS := optional
-LOCAL_SDK_VERSION := system_current
+LOCAL_SDK_VERSION := current
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_AIDL_INCLUDES += $(LOCAL_PATH)/src
diff --git a/tests/common/OWNERS b/tests/common/OWNERS
new file mode 100644
index 00000000..4aa5fe52
--- /dev/null
+++ b/tests/common/OWNERS
@@ -0,0 +1,2 @@
+nchalko@google.com
+shubang@google.com
diff --git a/tests/input/res/drawable-xhdpi/ch_1000_logo.png b/tests/common/res/drawable-xhdpi/ch_1000_logo.png
index eec6d373..eec6d373 100644
--- a/tests/input/res/drawable-xhdpi/ch_1000_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_1000_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_100_logo.png b/tests/common/res/drawable-xhdpi/ch_100_logo.png
index 3a8b6731..3a8b6731 100644
--- a/tests/input/res/drawable-xhdpi/ch_100_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_100_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_101_logo.png b/tests/common/res/drawable-xhdpi/ch_101_logo.png
index 2977ef1d..2977ef1d 100644
--- a/tests/input/res/drawable-xhdpi/ch_101_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_101_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_102_logo.png b/tests/common/res/drawable-xhdpi/ch_102_logo.png
index 978112e1..978112e1 100644
--- a/tests/input/res/drawable-xhdpi/ch_102_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_102_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_103_logo.png b/tests/common/res/drawable-xhdpi/ch_103_logo.png
index ceb1fd6a..ceb1fd6a 100644
--- a/tests/input/res/drawable-xhdpi/ch_103_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_103_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_104_logo.png b/tests/common/res/drawable-xhdpi/ch_104_logo.png
index c927568d..c927568d 100644
--- a/tests/input/res/drawable-xhdpi/ch_104_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_104_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_105_logo.png b/tests/common/res/drawable-xhdpi/ch_105_logo.png
index 8e1be19d..8e1be19d 100644
--- a/tests/input/res/drawable-xhdpi/ch_105_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_105_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_106_logo.png b/tests/common/res/drawable-xhdpi/ch_106_logo.png
index a19c9ef8..a19c9ef8 100644
--- a/tests/input/res/drawable-xhdpi/ch_106_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_106_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_107_logo.png b/tests/common/res/drawable-xhdpi/ch_107_logo.png
index 9d36a488..9d36a488 100644
--- a/tests/input/res/drawable-xhdpi/ch_107_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_107_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_108_logo.png b/tests/common/res/drawable-xhdpi/ch_108_logo.png
index 700ae189..700ae189 100644
--- a/tests/input/res/drawable-xhdpi/ch_108_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_108_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_109_logo.png b/tests/common/res/drawable-xhdpi/ch_109_logo.png
index 209e3b47..209e3b47 100644
--- a/tests/input/res/drawable-xhdpi/ch_109_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_109_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_10_logo.png b/tests/common/res/drawable-xhdpi/ch_10_logo.png
index 76b3a9b2..76b3a9b2 100644
--- a/tests/input/res/drawable-xhdpi/ch_10_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_10_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_110_logo.png b/tests/common/res/drawable-xhdpi/ch_110_logo.png
index 0c0c1920..0c0c1920 100644
--- a/tests/input/res/drawable-xhdpi/ch_110_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_110_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_111_logo.png b/tests/common/res/drawable-xhdpi/ch_111_logo.png
index 07c7ee83..07c7ee83 100644
--- a/tests/input/res/drawable-xhdpi/ch_111_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_111_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_112_logo.png b/tests/common/res/drawable-xhdpi/ch_112_logo.png
index 1675e54d..1675e54d 100644
--- a/tests/input/res/drawable-xhdpi/ch_112_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_112_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_113_logo.png b/tests/common/res/drawable-xhdpi/ch_113_logo.png
index 57cc81ce..57cc81ce 100644
--- a/tests/input/res/drawable-xhdpi/ch_113_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_113_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_114_logo.png b/tests/common/res/drawable-xhdpi/ch_114_logo.png
index 3d57f201..3d57f201 100644
--- a/tests/input/res/drawable-xhdpi/ch_114_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_114_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_115_logo.png b/tests/common/res/drawable-xhdpi/ch_115_logo.png
index 3897f5c9..3897f5c9 100644
--- a/tests/input/res/drawable-xhdpi/ch_115_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_115_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_116_logo.png b/tests/common/res/drawable-xhdpi/ch_116_logo.png
index 83a55a67..83a55a67 100644
--- a/tests/input/res/drawable-xhdpi/ch_116_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_116_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_117_logo.png b/tests/common/res/drawable-xhdpi/ch_117_logo.png
index 4b4eccf0..4b4eccf0 100644
--- a/tests/input/res/drawable-xhdpi/ch_117_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_117_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_118_logo.png b/tests/common/res/drawable-xhdpi/ch_118_logo.png
index 4a682f67..4a682f67 100644
--- a/tests/input/res/drawable-xhdpi/ch_118_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_118_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_119_logo.png b/tests/common/res/drawable-xhdpi/ch_119_logo.png
index 2a2aed5e..2a2aed5e 100644
--- a/tests/input/res/drawable-xhdpi/ch_119_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_119_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_11_logo.png b/tests/common/res/drawable-xhdpi/ch_11_logo.png
index 62268929..62268929 100644
--- a/tests/input/res/drawable-xhdpi/ch_11_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_11_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_120_logo.png b/tests/common/res/drawable-xhdpi/ch_120_logo.png
index 46c5f97a..46c5f97a 100644
--- a/tests/input/res/drawable-xhdpi/ch_120_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_120_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_121_logo.png b/tests/common/res/drawable-xhdpi/ch_121_logo.png
index 650bd3e4..650bd3e4 100644
--- a/tests/input/res/drawable-xhdpi/ch_121_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_121_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_122_logo.png b/tests/common/res/drawable-xhdpi/ch_122_logo.png
index 5a3c5d7b..5a3c5d7b 100644
--- a/tests/input/res/drawable-xhdpi/ch_122_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_122_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_123_logo.png b/tests/common/res/drawable-xhdpi/ch_123_logo.png
index ade9ab29..ade9ab29 100644
--- a/tests/input/res/drawable-xhdpi/ch_123_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_123_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_124_logo.png b/tests/common/res/drawable-xhdpi/ch_124_logo.png
index 62d15c06..62d15c06 100644
--- a/tests/input/res/drawable-xhdpi/ch_124_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_124_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_125_logo.png b/tests/common/res/drawable-xhdpi/ch_125_logo.png
index 34af08a9..34af08a9 100644
--- a/tests/input/res/drawable-xhdpi/ch_125_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_125_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_126_logo.png b/tests/common/res/drawable-xhdpi/ch_126_logo.png
index 8d10d163..8d10d163 100644
--- a/tests/input/res/drawable-xhdpi/ch_126_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_126_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_127_logo.png b/tests/common/res/drawable-xhdpi/ch_127_logo.png
index 428f8e0d..428f8e0d 100644
--- a/tests/input/res/drawable-xhdpi/ch_127_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_127_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_128_logo.png b/tests/common/res/drawable-xhdpi/ch_128_logo.png
index 536e04fa..536e04fa 100644
--- a/tests/input/res/drawable-xhdpi/ch_128_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_128_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_129_logo.png b/tests/common/res/drawable-xhdpi/ch_129_logo.png
index 79fc8dc8..79fc8dc8 100644
--- a/tests/input/res/drawable-xhdpi/ch_129_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_129_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_12_logo.png b/tests/common/res/drawable-xhdpi/ch_12_logo.png
index 5f155f41..5f155f41 100644
--- a/tests/input/res/drawable-xhdpi/ch_12_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_12_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_130_logo.png b/tests/common/res/drawable-xhdpi/ch_130_logo.png
index b2bc041f..b2bc041f 100644
--- a/tests/input/res/drawable-xhdpi/ch_130_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_130_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_131_logo.png b/tests/common/res/drawable-xhdpi/ch_131_logo.png
index 06081906..06081906 100644
--- a/tests/input/res/drawable-xhdpi/ch_131_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_131_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_132_logo.png b/tests/common/res/drawable-xhdpi/ch_132_logo.png
index 18a0bdef..18a0bdef 100644
--- a/tests/input/res/drawable-xhdpi/ch_132_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_132_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_133_logo.png b/tests/common/res/drawable-xhdpi/ch_133_logo.png
index 312027b2..312027b2 100644
--- a/tests/input/res/drawable-xhdpi/ch_133_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_133_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_134_logo.png b/tests/common/res/drawable-xhdpi/ch_134_logo.png
index c551922e..c551922e 100644
--- a/tests/input/res/drawable-xhdpi/ch_134_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_134_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_135_logo.png b/tests/common/res/drawable-xhdpi/ch_135_logo.png
index 64d7b889..64d7b889 100644
--- a/tests/input/res/drawable-xhdpi/ch_135_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_135_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_136_logo.png b/tests/common/res/drawable-xhdpi/ch_136_logo.png
index 31021239..31021239 100644
--- a/tests/input/res/drawable-xhdpi/ch_136_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_136_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_137_logo.png b/tests/common/res/drawable-xhdpi/ch_137_logo.png
index a7f8cfb8..a7f8cfb8 100644
--- a/tests/input/res/drawable-xhdpi/ch_137_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_137_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_138_logo.png b/tests/common/res/drawable-xhdpi/ch_138_logo.png
index 981425f0..981425f0 100644
--- a/tests/input/res/drawable-xhdpi/ch_138_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_138_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_139_logo.png b/tests/common/res/drawable-xhdpi/ch_139_logo.png
index 03170e5e..03170e5e 100644
--- a/tests/input/res/drawable-xhdpi/ch_139_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_139_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_13_logo.png b/tests/common/res/drawable-xhdpi/ch_13_logo.png
index 817922f8..817922f8 100644
--- a/tests/input/res/drawable-xhdpi/ch_13_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_13_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_140_logo.png b/tests/common/res/drawable-xhdpi/ch_140_logo.png
index f26cf917..f26cf917 100644
--- a/tests/input/res/drawable-xhdpi/ch_140_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_140_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_141_logo.png b/tests/common/res/drawable-xhdpi/ch_141_logo.png
index 0064d436..0064d436 100644
--- a/tests/input/res/drawable-xhdpi/ch_141_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_141_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_142_logo.png b/tests/common/res/drawable-xhdpi/ch_142_logo.png
index 1d28785e..1d28785e 100644
--- a/tests/input/res/drawable-xhdpi/ch_142_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_142_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_143_logo.png b/tests/common/res/drawable-xhdpi/ch_143_logo.png
index 6f6bb7ea..6f6bb7ea 100644
--- a/tests/input/res/drawable-xhdpi/ch_143_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_143_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_144_logo.png b/tests/common/res/drawable-xhdpi/ch_144_logo.png
index afa678cc..afa678cc 100644
--- a/tests/input/res/drawable-xhdpi/ch_144_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_144_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_145_logo.png b/tests/common/res/drawable-xhdpi/ch_145_logo.png
index 0e989ba5..0e989ba5 100644
--- a/tests/input/res/drawable-xhdpi/ch_145_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_145_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_146_logo.png b/tests/common/res/drawable-xhdpi/ch_146_logo.png
index 4ee0082c..4ee0082c 100644
--- a/tests/input/res/drawable-xhdpi/ch_146_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_146_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_147_logo.png b/tests/common/res/drawable-xhdpi/ch_147_logo.png
index ddcc91dd..ddcc91dd 100644
--- a/tests/input/res/drawable-xhdpi/ch_147_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_147_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_148_logo.png b/tests/common/res/drawable-xhdpi/ch_148_logo.png
index c7f0c42a..c7f0c42a 100644
--- a/tests/input/res/drawable-xhdpi/ch_148_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_148_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_149_logo.png b/tests/common/res/drawable-xhdpi/ch_149_logo.png
index f2d38ace..f2d38ace 100644
--- a/tests/input/res/drawable-xhdpi/ch_149_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_149_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_14_logo.png b/tests/common/res/drawable-xhdpi/ch_14_logo.png
index f66db228..f66db228 100644
--- a/tests/input/res/drawable-xhdpi/ch_14_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_14_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_150_logo.png b/tests/common/res/drawable-xhdpi/ch_150_logo.png
index 6efad527..6efad527 100644
--- a/tests/input/res/drawable-xhdpi/ch_150_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_150_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_151_logo.png b/tests/common/res/drawable-xhdpi/ch_151_logo.png
index b37e11ea..b37e11ea 100644
--- a/tests/input/res/drawable-xhdpi/ch_151_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_151_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_152_logo.png b/tests/common/res/drawable-xhdpi/ch_152_logo.png
index 81f872a5..81f872a5 100644
--- a/tests/input/res/drawable-xhdpi/ch_152_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_152_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_153_logo.png b/tests/common/res/drawable-xhdpi/ch_153_logo.png
index e564739d..e564739d 100644
--- a/tests/input/res/drawable-xhdpi/ch_153_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_153_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_154_logo.png b/tests/common/res/drawable-xhdpi/ch_154_logo.png
index 331498e8..331498e8 100644
--- a/tests/input/res/drawable-xhdpi/ch_154_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_154_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_155_logo.png b/tests/common/res/drawable-xhdpi/ch_155_logo.png
index da8c34d4..da8c34d4 100644
--- a/tests/input/res/drawable-xhdpi/ch_155_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_155_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_156_logo.png b/tests/common/res/drawable-xhdpi/ch_156_logo.png
index 5ca6d550..5ca6d550 100644
--- a/tests/input/res/drawable-xhdpi/ch_156_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_156_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_157_logo.png b/tests/common/res/drawable-xhdpi/ch_157_logo.png
index 460ece79..460ece79 100644
--- a/tests/input/res/drawable-xhdpi/ch_157_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_157_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_158_logo.png b/tests/common/res/drawable-xhdpi/ch_158_logo.png
index 8d11e42e..8d11e42e 100644
--- a/tests/input/res/drawable-xhdpi/ch_158_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_158_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_159_logo.png b/tests/common/res/drawable-xhdpi/ch_159_logo.png
index a10cf881..a10cf881 100644
--- a/tests/input/res/drawable-xhdpi/ch_159_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_159_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_15_logo.png b/tests/common/res/drawable-xhdpi/ch_15_logo.png
index ae4fc936..ae4fc936 100644
--- a/tests/input/res/drawable-xhdpi/ch_15_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_15_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_160_logo.png b/tests/common/res/drawable-xhdpi/ch_160_logo.png
index c219ea72..c219ea72 100644
--- a/tests/input/res/drawable-xhdpi/ch_160_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_160_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_161_logo.png b/tests/common/res/drawable-xhdpi/ch_161_logo.png
index 2b13ad83..2b13ad83 100644
--- a/tests/input/res/drawable-xhdpi/ch_161_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_161_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_162_logo.png b/tests/common/res/drawable-xhdpi/ch_162_logo.png
index 11bfadca..11bfadca 100644
--- a/tests/input/res/drawable-xhdpi/ch_162_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_162_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_163_logo.png b/tests/common/res/drawable-xhdpi/ch_163_logo.png
index 9c41b03a..9c41b03a 100644
--- a/tests/input/res/drawable-xhdpi/ch_163_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_163_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_164_logo.png b/tests/common/res/drawable-xhdpi/ch_164_logo.png
index ec4a101e..ec4a101e 100644
--- a/tests/input/res/drawable-xhdpi/ch_164_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_164_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_165_logo.png b/tests/common/res/drawable-xhdpi/ch_165_logo.png
index 1aceac38..1aceac38 100644
--- a/tests/input/res/drawable-xhdpi/ch_165_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_165_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_166_logo.png b/tests/common/res/drawable-xhdpi/ch_166_logo.png
index f731014f..f731014f 100644
--- a/tests/input/res/drawable-xhdpi/ch_166_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_166_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_167_logo.png b/tests/common/res/drawable-xhdpi/ch_167_logo.png
index 08c82fbf..08c82fbf 100644
--- a/tests/input/res/drawable-xhdpi/ch_167_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_167_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_168_logo.png b/tests/common/res/drawable-xhdpi/ch_168_logo.png
index 0c5707bc..0c5707bc 100644
--- a/tests/input/res/drawable-xhdpi/ch_168_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_168_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_169_logo.png b/tests/common/res/drawable-xhdpi/ch_169_logo.png
index a9710cec..a9710cec 100644
--- a/tests/input/res/drawable-xhdpi/ch_169_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_169_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_16_logo.png b/tests/common/res/drawable-xhdpi/ch_16_logo.png
index 76aee2de..76aee2de 100644
--- a/tests/input/res/drawable-xhdpi/ch_16_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_16_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_170_logo.png b/tests/common/res/drawable-xhdpi/ch_170_logo.png
index 1bf43fa7..1bf43fa7 100644
--- a/tests/input/res/drawable-xhdpi/ch_170_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_170_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_171_logo.png b/tests/common/res/drawable-xhdpi/ch_171_logo.png
index 8c6d6fde..8c6d6fde 100644
--- a/tests/input/res/drawable-xhdpi/ch_171_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_171_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_172_logo.png b/tests/common/res/drawable-xhdpi/ch_172_logo.png
index 13d73ec7..13d73ec7 100644
--- a/tests/input/res/drawable-xhdpi/ch_172_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_172_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_173_logo.png b/tests/common/res/drawable-xhdpi/ch_173_logo.png
index 2423b0ab..2423b0ab 100644
--- a/tests/input/res/drawable-xhdpi/ch_173_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_173_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_174_logo.png b/tests/common/res/drawable-xhdpi/ch_174_logo.png
index 2f752dce..2f752dce 100644
--- a/tests/input/res/drawable-xhdpi/ch_174_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_174_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_175_logo.png b/tests/common/res/drawable-xhdpi/ch_175_logo.png
index ffe3b45e..ffe3b45e 100644
--- a/tests/input/res/drawable-xhdpi/ch_175_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_175_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_176_logo.png b/tests/common/res/drawable-xhdpi/ch_176_logo.png
index d35592de..d35592de 100644
--- a/tests/input/res/drawable-xhdpi/ch_176_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_176_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_177_logo.png b/tests/common/res/drawable-xhdpi/ch_177_logo.png
index c50df44f..c50df44f 100644
--- a/tests/input/res/drawable-xhdpi/ch_177_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_177_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_178_logo.png b/tests/common/res/drawable-xhdpi/ch_178_logo.png
index 22539784..22539784 100644
--- a/tests/input/res/drawable-xhdpi/ch_178_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_178_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_179_logo.png b/tests/common/res/drawable-xhdpi/ch_179_logo.png
index a2c1946b..a2c1946b 100644
--- a/tests/input/res/drawable-xhdpi/ch_179_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_179_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_17_logo.png b/tests/common/res/drawable-xhdpi/ch_17_logo.png
index 0189498f..0189498f 100644
--- a/tests/input/res/drawable-xhdpi/ch_17_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_17_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_180_logo.png b/tests/common/res/drawable-xhdpi/ch_180_logo.png
index 9c72f2ab..9c72f2ab 100644
--- a/tests/input/res/drawable-xhdpi/ch_180_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_180_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_181_logo.png b/tests/common/res/drawable-xhdpi/ch_181_logo.png
index 23610936..23610936 100644
--- a/tests/input/res/drawable-xhdpi/ch_181_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_181_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_182_logo.png b/tests/common/res/drawable-xhdpi/ch_182_logo.png
index c36bc811..c36bc811 100644
--- a/tests/input/res/drawable-xhdpi/ch_182_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_182_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_183_logo.png b/tests/common/res/drawable-xhdpi/ch_183_logo.png
index e0e75a41..e0e75a41 100644
--- a/tests/input/res/drawable-xhdpi/ch_183_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_183_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_184_logo.png b/tests/common/res/drawable-xhdpi/ch_184_logo.png
index 334598f7..334598f7 100644
--- a/tests/input/res/drawable-xhdpi/ch_184_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_184_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_185_logo.png b/tests/common/res/drawable-xhdpi/ch_185_logo.png
index 6891720d..6891720d 100644
--- a/tests/input/res/drawable-xhdpi/ch_185_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_185_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_186_logo.png b/tests/common/res/drawable-xhdpi/ch_186_logo.png
index 58fc146a..58fc146a 100644
--- a/tests/input/res/drawable-xhdpi/ch_186_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_186_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_187_logo.png b/tests/common/res/drawable-xhdpi/ch_187_logo.png
index 6d4f46fc..6d4f46fc 100644
--- a/tests/input/res/drawable-xhdpi/ch_187_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_187_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_188_logo.png b/tests/common/res/drawable-xhdpi/ch_188_logo.png
index 96fc401c..96fc401c 100644
--- a/tests/input/res/drawable-xhdpi/ch_188_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_188_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_189_logo.png b/tests/common/res/drawable-xhdpi/ch_189_logo.png
index 93dd4050..93dd4050 100644
--- a/tests/input/res/drawable-xhdpi/ch_189_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_189_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_18_logo.png b/tests/common/res/drawable-xhdpi/ch_18_logo.png
index 2025821b..2025821b 100644
--- a/tests/input/res/drawable-xhdpi/ch_18_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_18_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_190_logo.png b/tests/common/res/drawable-xhdpi/ch_190_logo.png
index ea257681..ea257681 100644
--- a/tests/input/res/drawable-xhdpi/ch_190_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_190_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_191_logo.png b/tests/common/res/drawable-xhdpi/ch_191_logo.png
index 2ac4c189..2ac4c189 100644
--- a/tests/input/res/drawable-xhdpi/ch_191_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_191_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_192_logo.png b/tests/common/res/drawable-xhdpi/ch_192_logo.png
index 14728cd3..14728cd3 100644
--- a/tests/input/res/drawable-xhdpi/ch_192_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_192_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_193_logo.png b/tests/common/res/drawable-xhdpi/ch_193_logo.png
index dbbf2a1f..dbbf2a1f 100644
--- a/tests/input/res/drawable-xhdpi/ch_193_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_193_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_194_logo.png b/tests/common/res/drawable-xhdpi/ch_194_logo.png
index aabcefda..aabcefda 100644
--- a/tests/input/res/drawable-xhdpi/ch_194_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_194_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_195_logo.png b/tests/common/res/drawable-xhdpi/ch_195_logo.png
index e0158d09..e0158d09 100644
--- a/tests/input/res/drawable-xhdpi/ch_195_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_195_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_196_logo.png b/tests/common/res/drawable-xhdpi/ch_196_logo.png
index a1087785..a1087785 100644
--- a/tests/input/res/drawable-xhdpi/ch_196_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_196_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_197_logo.png b/tests/common/res/drawable-xhdpi/ch_197_logo.png
index 5644e83c..5644e83c 100644
--- a/tests/input/res/drawable-xhdpi/ch_197_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_197_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_198_logo.png b/tests/common/res/drawable-xhdpi/ch_198_logo.png
index c06acf55..c06acf55 100644
--- a/tests/input/res/drawable-xhdpi/ch_198_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_198_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_199_logo.png b/tests/common/res/drawable-xhdpi/ch_199_logo.png
index 6d5ec3ab..6d5ec3ab 100644
--- a/tests/input/res/drawable-xhdpi/ch_199_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_199_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_19_logo.png b/tests/common/res/drawable-xhdpi/ch_19_logo.png
index 5e729625..5e729625 100644
--- a/tests/input/res/drawable-xhdpi/ch_19_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_19_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_1_logo.png b/tests/common/res/drawable-xhdpi/ch_1_logo.png
index 0a39d154..0a39d154 100644
--- a/tests/input/res/drawable-xhdpi/ch_1_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_1_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_200_logo.png b/tests/common/res/drawable-xhdpi/ch_200_logo.png
index 7999b2f6..7999b2f6 100644
--- a/tests/input/res/drawable-xhdpi/ch_200_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_200_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_201_logo.png b/tests/common/res/drawable-xhdpi/ch_201_logo.png
index 68c868e9..68c868e9 100644
--- a/tests/input/res/drawable-xhdpi/ch_201_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_201_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_202_logo.png b/tests/common/res/drawable-xhdpi/ch_202_logo.png
index abd838fa..abd838fa 100644
--- a/tests/input/res/drawable-xhdpi/ch_202_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_202_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_203_logo.png b/tests/common/res/drawable-xhdpi/ch_203_logo.png
index f91c34cc..f91c34cc 100644
--- a/tests/input/res/drawable-xhdpi/ch_203_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_203_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_204_logo.png b/tests/common/res/drawable-xhdpi/ch_204_logo.png
index 8e8582c6..8e8582c6 100644
--- a/tests/input/res/drawable-xhdpi/ch_204_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_204_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_205_logo.png b/tests/common/res/drawable-xhdpi/ch_205_logo.png
index 4e3f4d94..4e3f4d94 100644
--- a/tests/input/res/drawable-xhdpi/ch_205_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_205_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_206_logo.png b/tests/common/res/drawable-xhdpi/ch_206_logo.png
index 584bb98c..584bb98c 100644
--- a/tests/input/res/drawable-xhdpi/ch_206_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_206_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_207_logo.png b/tests/common/res/drawable-xhdpi/ch_207_logo.png
index e6b2748e..e6b2748e 100644
--- a/tests/input/res/drawable-xhdpi/ch_207_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_207_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_208_logo.png b/tests/common/res/drawable-xhdpi/ch_208_logo.png
index 5a18dcad..5a18dcad 100644
--- a/tests/input/res/drawable-xhdpi/ch_208_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_208_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_209_logo.png b/tests/common/res/drawable-xhdpi/ch_209_logo.png
index c4de3050..c4de3050 100644
--- a/tests/input/res/drawable-xhdpi/ch_209_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_209_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_20_logo.png b/tests/common/res/drawable-xhdpi/ch_20_logo.png
index 6b4d6104..6b4d6104 100644
--- a/tests/input/res/drawable-xhdpi/ch_20_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_20_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_210_logo.png b/tests/common/res/drawable-xhdpi/ch_210_logo.png
index e4eed085..e4eed085 100644
--- a/tests/input/res/drawable-xhdpi/ch_210_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_210_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_211_logo.png b/tests/common/res/drawable-xhdpi/ch_211_logo.png
index d5881047..d5881047 100644
--- a/tests/input/res/drawable-xhdpi/ch_211_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_211_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_212_logo.png b/tests/common/res/drawable-xhdpi/ch_212_logo.png
index c849f6f2..c849f6f2 100644
--- a/tests/input/res/drawable-xhdpi/ch_212_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_212_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_213_logo.png b/tests/common/res/drawable-xhdpi/ch_213_logo.png
index 92def1c5..92def1c5 100644
--- a/tests/input/res/drawable-xhdpi/ch_213_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_213_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_214_logo.png b/tests/common/res/drawable-xhdpi/ch_214_logo.png
index 51f749fd..51f749fd 100644
--- a/tests/input/res/drawable-xhdpi/ch_214_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_214_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_215_logo.png b/tests/common/res/drawable-xhdpi/ch_215_logo.png
index 5425aaad..5425aaad 100644
--- a/tests/input/res/drawable-xhdpi/ch_215_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_215_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_216_logo.png b/tests/common/res/drawable-xhdpi/ch_216_logo.png
index 53fed3c2..53fed3c2 100644
--- a/tests/input/res/drawable-xhdpi/ch_216_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_216_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_217_logo.png b/tests/common/res/drawable-xhdpi/ch_217_logo.png
index d253f9cd..d253f9cd 100644
--- a/tests/input/res/drawable-xhdpi/ch_217_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_217_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_218_logo.png b/tests/common/res/drawable-xhdpi/ch_218_logo.png
index 3c7b0698..3c7b0698 100644
--- a/tests/input/res/drawable-xhdpi/ch_218_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_218_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_219_logo.png b/tests/common/res/drawable-xhdpi/ch_219_logo.png
index 7b96dd6e..7b96dd6e 100644
--- a/tests/input/res/drawable-xhdpi/ch_219_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_219_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_21_logo.png b/tests/common/res/drawable-xhdpi/ch_21_logo.png
index f2848346..f2848346 100644
--- a/tests/input/res/drawable-xhdpi/ch_21_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_21_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_220_logo.png b/tests/common/res/drawable-xhdpi/ch_220_logo.png
index f9d20884..f9d20884 100644
--- a/tests/input/res/drawable-xhdpi/ch_220_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_220_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_221_logo.png b/tests/common/res/drawable-xhdpi/ch_221_logo.png
index 9213142d..9213142d 100644
--- a/tests/input/res/drawable-xhdpi/ch_221_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_221_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_222_logo.png b/tests/common/res/drawable-xhdpi/ch_222_logo.png
index 66cb9a8b..66cb9a8b 100644
--- a/tests/input/res/drawable-xhdpi/ch_222_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_222_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_223_logo.png b/tests/common/res/drawable-xhdpi/ch_223_logo.png
index 11a44724..11a44724 100644
--- a/tests/input/res/drawable-xhdpi/ch_223_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_223_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_224_logo.png b/tests/common/res/drawable-xhdpi/ch_224_logo.png
index cdba6bf5..cdba6bf5 100644
--- a/tests/input/res/drawable-xhdpi/ch_224_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_224_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_225_logo.png b/tests/common/res/drawable-xhdpi/ch_225_logo.png
index e9416bfd..e9416bfd 100644
--- a/tests/input/res/drawable-xhdpi/ch_225_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_225_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_226_logo.png b/tests/common/res/drawable-xhdpi/ch_226_logo.png
index 88792532..88792532 100644
--- a/tests/input/res/drawable-xhdpi/ch_226_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_226_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_227_logo.png b/tests/common/res/drawable-xhdpi/ch_227_logo.png
index 7ae8205b..7ae8205b 100644
--- a/tests/input/res/drawable-xhdpi/ch_227_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_227_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_228_logo.png b/tests/common/res/drawable-xhdpi/ch_228_logo.png
index 718d93e2..718d93e2 100644
--- a/tests/input/res/drawable-xhdpi/ch_228_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_228_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_229_logo.png b/tests/common/res/drawable-xhdpi/ch_229_logo.png
index eb4f9129..eb4f9129 100644
--- a/tests/input/res/drawable-xhdpi/ch_229_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_229_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_22_logo.png b/tests/common/res/drawable-xhdpi/ch_22_logo.png
index 9aa987d1..9aa987d1 100644
--- a/tests/input/res/drawable-xhdpi/ch_22_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_22_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_230_logo.png b/tests/common/res/drawable-xhdpi/ch_230_logo.png
index a1bb57d3..a1bb57d3 100644
--- a/tests/input/res/drawable-xhdpi/ch_230_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_230_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_231_logo.png b/tests/common/res/drawable-xhdpi/ch_231_logo.png
index e748e868..e748e868 100644
--- a/tests/input/res/drawable-xhdpi/ch_231_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_231_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_232_logo.png b/tests/common/res/drawable-xhdpi/ch_232_logo.png
index 5d4f1d69..5d4f1d69 100644
--- a/tests/input/res/drawable-xhdpi/ch_232_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_232_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_233_logo.png b/tests/common/res/drawable-xhdpi/ch_233_logo.png
index 7ff780ab..7ff780ab 100644
--- a/tests/input/res/drawable-xhdpi/ch_233_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_233_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_234_logo.png b/tests/common/res/drawable-xhdpi/ch_234_logo.png
index a4e10dfb..a4e10dfb 100644
--- a/tests/input/res/drawable-xhdpi/ch_234_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_234_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_235_logo.png b/tests/common/res/drawable-xhdpi/ch_235_logo.png
index c318ac0b..c318ac0b 100644
--- a/tests/input/res/drawable-xhdpi/ch_235_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_235_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_236_logo.png b/tests/common/res/drawable-xhdpi/ch_236_logo.png
index 2ab86fd6..2ab86fd6 100644
--- a/tests/input/res/drawable-xhdpi/ch_236_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_236_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_237_logo.png b/tests/common/res/drawable-xhdpi/ch_237_logo.png
index 04fa9d61..04fa9d61 100644
--- a/tests/input/res/drawable-xhdpi/ch_237_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_237_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_238_logo.png b/tests/common/res/drawable-xhdpi/ch_238_logo.png
index 6649b9db..6649b9db 100644
--- a/tests/input/res/drawable-xhdpi/ch_238_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_238_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_239_logo.png b/tests/common/res/drawable-xhdpi/ch_239_logo.png
index 6eaf887d..6eaf887d 100644
--- a/tests/input/res/drawable-xhdpi/ch_239_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_239_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_23_logo.png b/tests/common/res/drawable-xhdpi/ch_23_logo.png
index c3dcf172..c3dcf172 100644
--- a/tests/input/res/drawable-xhdpi/ch_23_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_23_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_240_logo.png b/tests/common/res/drawable-xhdpi/ch_240_logo.png
index 50d0d0df..50d0d0df 100644
--- a/tests/input/res/drawable-xhdpi/ch_240_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_240_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_241_logo.png b/tests/common/res/drawable-xhdpi/ch_241_logo.png
index 779d53b5..779d53b5 100644
--- a/tests/input/res/drawable-xhdpi/ch_241_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_241_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_242_logo.png b/tests/common/res/drawable-xhdpi/ch_242_logo.png
index 717aaae5..717aaae5 100644
--- a/tests/input/res/drawable-xhdpi/ch_242_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_242_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_243_logo.png b/tests/common/res/drawable-xhdpi/ch_243_logo.png
index fd04b2a2..fd04b2a2 100644
--- a/tests/input/res/drawable-xhdpi/ch_243_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_243_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_244_logo.png b/tests/common/res/drawable-xhdpi/ch_244_logo.png
index d8b1b710..d8b1b710 100644
--- a/tests/input/res/drawable-xhdpi/ch_244_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_244_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_245_logo.png b/tests/common/res/drawable-xhdpi/ch_245_logo.png
index 3a08f595..3a08f595 100644
--- a/tests/input/res/drawable-xhdpi/ch_245_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_245_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_246_logo.png b/tests/common/res/drawable-xhdpi/ch_246_logo.png
index 404bd8f0..404bd8f0 100644
--- a/tests/input/res/drawable-xhdpi/ch_246_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_246_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_247_logo.png b/tests/common/res/drawable-xhdpi/ch_247_logo.png
index 46ee0163..46ee0163 100644
--- a/tests/input/res/drawable-xhdpi/ch_247_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_247_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_248_logo.png b/tests/common/res/drawable-xhdpi/ch_248_logo.png
index ebfeb6d8..ebfeb6d8 100644
--- a/tests/input/res/drawable-xhdpi/ch_248_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_248_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_249_logo.png b/tests/common/res/drawable-xhdpi/ch_249_logo.png
index f49dc8c4..f49dc8c4 100644
--- a/tests/input/res/drawable-xhdpi/ch_249_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_249_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_24_logo.png b/tests/common/res/drawable-xhdpi/ch_24_logo.png
index 8fda8dcc..8fda8dcc 100644
--- a/tests/input/res/drawable-xhdpi/ch_24_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_24_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_250_logo.png b/tests/common/res/drawable-xhdpi/ch_250_logo.png
index 3c464624..3c464624 100644
--- a/tests/input/res/drawable-xhdpi/ch_250_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_250_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_251_logo.png b/tests/common/res/drawable-xhdpi/ch_251_logo.png
index 58f3f7d2..58f3f7d2 100644
--- a/tests/input/res/drawable-xhdpi/ch_251_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_251_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_252_logo.png b/tests/common/res/drawable-xhdpi/ch_252_logo.png
index f0284549..f0284549 100644
--- a/tests/input/res/drawable-xhdpi/ch_252_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_252_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_253_logo.png b/tests/common/res/drawable-xhdpi/ch_253_logo.png
index 47a8f91d..47a8f91d 100644
--- a/tests/input/res/drawable-xhdpi/ch_253_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_253_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_254_logo.png b/tests/common/res/drawable-xhdpi/ch_254_logo.png
index e2505fc0..e2505fc0 100644
--- a/tests/input/res/drawable-xhdpi/ch_254_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_254_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_255_logo.png b/tests/common/res/drawable-xhdpi/ch_255_logo.png
index 55e7116b..55e7116b 100644
--- a/tests/input/res/drawable-xhdpi/ch_255_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_255_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_256_logo.png b/tests/common/res/drawable-xhdpi/ch_256_logo.png
index d31964ab..d31964ab 100644
--- a/tests/input/res/drawable-xhdpi/ch_256_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_256_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_257_logo.png b/tests/common/res/drawable-xhdpi/ch_257_logo.png
index cf850f90..cf850f90 100644
--- a/tests/input/res/drawable-xhdpi/ch_257_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_257_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_258_logo.png b/tests/common/res/drawable-xhdpi/ch_258_logo.png
index 148d0ee4..148d0ee4 100644
--- a/tests/input/res/drawable-xhdpi/ch_258_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_258_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_259_logo.png b/tests/common/res/drawable-xhdpi/ch_259_logo.png
index aa84697d..aa84697d 100644
--- a/tests/input/res/drawable-xhdpi/ch_259_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_259_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_25_logo.png b/tests/common/res/drawable-xhdpi/ch_25_logo.png
index 401e785e..401e785e 100644
--- a/tests/input/res/drawable-xhdpi/ch_25_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_25_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_260_logo.png b/tests/common/res/drawable-xhdpi/ch_260_logo.png
index dc4f67f7..dc4f67f7 100644
--- a/tests/input/res/drawable-xhdpi/ch_260_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_260_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_261_logo.png b/tests/common/res/drawable-xhdpi/ch_261_logo.png
index dfbecb37..dfbecb37 100644
--- a/tests/input/res/drawable-xhdpi/ch_261_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_261_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_262_logo.png b/tests/common/res/drawable-xhdpi/ch_262_logo.png
index 2fa3185b..2fa3185b 100644
--- a/tests/input/res/drawable-xhdpi/ch_262_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_262_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_263_logo.png b/tests/common/res/drawable-xhdpi/ch_263_logo.png
index d1e84b38..d1e84b38 100644
--- a/tests/input/res/drawable-xhdpi/ch_263_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_263_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_264_logo.png b/tests/common/res/drawable-xhdpi/ch_264_logo.png
index 3f52decb..3f52decb 100644
--- a/tests/input/res/drawable-xhdpi/ch_264_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_264_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_265_logo.png b/tests/common/res/drawable-xhdpi/ch_265_logo.png
index f60c362a..f60c362a 100644
--- a/tests/input/res/drawable-xhdpi/ch_265_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_265_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_266_logo.png b/tests/common/res/drawable-xhdpi/ch_266_logo.png
index 94dc4463..94dc4463 100644
--- a/tests/input/res/drawable-xhdpi/ch_266_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_266_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_267_logo.png b/tests/common/res/drawable-xhdpi/ch_267_logo.png
index 48ac79ed..48ac79ed 100644
--- a/tests/input/res/drawable-xhdpi/ch_267_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_267_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_268_logo.png b/tests/common/res/drawable-xhdpi/ch_268_logo.png
index b6f1ad64..b6f1ad64 100644
--- a/tests/input/res/drawable-xhdpi/ch_268_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_268_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_269_logo.png b/tests/common/res/drawable-xhdpi/ch_269_logo.png
index 0d98d378..0d98d378 100644
--- a/tests/input/res/drawable-xhdpi/ch_269_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_269_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_26_logo.png b/tests/common/res/drawable-xhdpi/ch_26_logo.png
index a8835e4a..a8835e4a 100644
--- a/tests/input/res/drawable-xhdpi/ch_26_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_26_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_270_logo.png b/tests/common/res/drawable-xhdpi/ch_270_logo.png
index 27a0aead..27a0aead 100644
--- a/tests/input/res/drawable-xhdpi/ch_270_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_270_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_271_logo.png b/tests/common/res/drawable-xhdpi/ch_271_logo.png
index 7fa6feb3..7fa6feb3 100644
--- a/tests/input/res/drawable-xhdpi/ch_271_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_271_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_272_logo.png b/tests/common/res/drawable-xhdpi/ch_272_logo.png
index af7e34e6..af7e34e6 100644
--- a/tests/input/res/drawable-xhdpi/ch_272_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_272_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_273_logo.png b/tests/common/res/drawable-xhdpi/ch_273_logo.png
index a8a041af..a8a041af 100644
--- a/tests/input/res/drawable-xhdpi/ch_273_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_273_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_274_logo.png b/tests/common/res/drawable-xhdpi/ch_274_logo.png
index 0f498f23..0f498f23 100644
--- a/tests/input/res/drawable-xhdpi/ch_274_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_274_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_275_logo.png b/tests/common/res/drawable-xhdpi/ch_275_logo.png
index d598fb35..d598fb35 100644
--- a/tests/input/res/drawable-xhdpi/ch_275_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_275_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_276_logo.png b/tests/common/res/drawable-xhdpi/ch_276_logo.png
index 7cbac69a..7cbac69a 100644
--- a/tests/input/res/drawable-xhdpi/ch_276_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_276_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_277_logo.png b/tests/common/res/drawable-xhdpi/ch_277_logo.png
index 70a7f3ea..70a7f3ea 100644
--- a/tests/input/res/drawable-xhdpi/ch_277_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_277_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_278_logo.png b/tests/common/res/drawable-xhdpi/ch_278_logo.png
index fcb332a5..fcb332a5 100644
--- a/tests/input/res/drawable-xhdpi/ch_278_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_278_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_279_logo.png b/tests/common/res/drawable-xhdpi/ch_279_logo.png
index a95b4a96..a95b4a96 100644
--- a/tests/input/res/drawable-xhdpi/ch_279_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_279_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_27_logo.png b/tests/common/res/drawable-xhdpi/ch_27_logo.png
index 138b7dc8..138b7dc8 100644
--- a/tests/input/res/drawable-xhdpi/ch_27_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_27_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_280_logo.png b/tests/common/res/drawable-xhdpi/ch_280_logo.png
index 2f862b39..2f862b39 100644
--- a/tests/input/res/drawable-xhdpi/ch_280_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_280_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_281_logo.png b/tests/common/res/drawable-xhdpi/ch_281_logo.png
index 6d888d16..6d888d16 100644
--- a/tests/input/res/drawable-xhdpi/ch_281_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_281_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_282_logo.png b/tests/common/res/drawable-xhdpi/ch_282_logo.png
index 81db1656..81db1656 100644
--- a/tests/input/res/drawable-xhdpi/ch_282_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_282_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_283_logo.png b/tests/common/res/drawable-xhdpi/ch_283_logo.png
index 4933bc3c..4933bc3c 100644
--- a/tests/input/res/drawable-xhdpi/ch_283_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_283_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_284_logo.png b/tests/common/res/drawable-xhdpi/ch_284_logo.png
index b4880b8b..b4880b8b 100644
--- a/tests/input/res/drawable-xhdpi/ch_284_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_284_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_285_logo.png b/tests/common/res/drawable-xhdpi/ch_285_logo.png
index eea6175e..eea6175e 100644
--- a/tests/input/res/drawable-xhdpi/ch_285_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_285_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_286_logo.png b/tests/common/res/drawable-xhdpi/ch_286_logo.png
index d2b5b5bd..d2b5b5bd 100644
--- a/tests/input/res/drawable-xhdpi/ch_286_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_286_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_287_logo.png b/tests/common/res/drawable-xhdpi/ch_287_logo.png
index f374d9d0..f374d9d0 100644
--- a/tests/input/res/drawable-xhdpi/ch_287_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_287_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_288_logo.png b/tests/common/res/drawable-xhdpi/ch_288_logo.png
index 16072cfa..16072cfa 100644
--- a/tests/input/res/drawable-xhdpi/ch_288_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_288_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_289_logo.png b/tests/common/res/drawable-xhdpi/ch_289_logo.png
index b76c2f48..b76c2f48 100644
--- a/tests/input/res/drawable-xhdpi/ch_289_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_289_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_28_logo.png b/tests/common/res/drawable-xhdpi/ch_28_logo.png
index 284301b0..284301b0 100644
--- a/tests/input/res/drawable-xhdpi/ch_28_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_28_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_290_logo.png b/tests/common/res/drawable-xhdpi/ch_290_logo.png
index 2778664f..2778664f 100644
--- a/tests/input/res/drawable-xhdpi/ch_290_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_290_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_291_logo.png b/tests/common/res/drawable-xhdpi/ch_291_logo.png
index 52da29f6..52da29f6 100644
--- a/tests/input/res/drawable-xhdpi/ch_291_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_291_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_292_logo.png b/tests/common/res/drawable-xhdpi/ch_292_logo.png
index a1d8e6f8..a1d8e6f8 100644
--- a/tests/input/res/drawable-xhdpi/ch_292_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_292_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_293_logo.png b/tests/common/res/drawable-xhdpi/ch_293_logo.png
index 74020c30..74020c30 100644
--- a/tests/input/res/drawable-xhdpi/ch_293_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_293_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_294_logo.png b/tests/common/res/drawable-xhdpi/ch_294_logo.png
index 49d72b5d..49d72b5d 100644
--- a/tests/input/res/drawable-xhdpi/ch_294_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_294_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_295_logo.png b/tests/common/res/drawable-xhdpi/ch_295_logo.png
index cae47aeb..cae47aeb 100644
--- a/tests/input/res/drawable-xhdpi/ch_295_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_295_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_296_logo.png b/tests/common/res/drawable-xhdpi/ch_296_logo.png
index 4b38d480..4b38d480 100644
--- a/tests/input/res/drawable-xhdpi/ch_296_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_296_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_297_logo.png b/tests/common/res/drawable-xhdpi/ch_297_logo.png
index 3edd15d0..3edd15d0 100644
--- a/tests/input/res/drawable-xhdpi/ch_297_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_297_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_298_logo.png b/tests/common/res/drawable-xhdpi/ch_298_logo.png
index cb472f31..cb472f31 100644
--- a/tests/input/res/drawable-xhdpi/ch_298_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_298_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_299_logo.png b/tests/common/res/drawable-xhdpi/ch_299_logo.png
index b672881e..b672881e 100644
--- a/tests/input/res/drawable-xhdpi/ch_299_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_299_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_29_logo.png b/tests/common/res/drawable-xhdpi/ch_29_logo.png
index 9f1c523f..9f1c523f 100644
--- a/tests/input/res/drawable-xhdpi/ch_29_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_29_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_2_logo.png b/tests/common/res/drawable-xhdpi/ch_2_logo.png
index d6887b05..d6887b05 100644
--- a/tests/input/res/drawable-xhdpi/ch_2_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_2_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_300_logo.png b/tests/common/res/drawable-xhdpi/ch_300_logo.png
index 9b842d77..9b842d77 100644
--- a/tests/input/res/drawable-xhdpi/ch_300_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_300_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_301_logo.png b/tests/common/res/drawable-xhdpi/ch_301_logo.png
index 4c7fda85..4c7fda85 100644
--- a/tests/input/res/drawable-xhdpi/ch_301_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_301_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_302_logo.png b/tests/common/res/drawable-xhdpi/ch_302_logo.png
index e39f5acb..e39f5acb 100644
--- a/tests/input/res/drawable-xhdpi/ch_302_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_302_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_303_logo.png b/tests/common/res/drawable-xhdpi/ch_303_logo.png
index 78f057f7..78f057f7 100644
--- a/tests/input/res/drawable-xhdpi/ch_303_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_303_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_304_logo.png b/tests/common/res/drawable-xhdpi/ch_304_logo.png
index b8a68630..b8a68630 100644
--- a/tests/input/res/drawable-xhdpi/ch_304_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_304_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_305_logo.png b/tests/common/res/drawable-xhdpi/ch_305_logo.png
index 7f698610..7f698610 100644
--- a/tests/input/res/drawable-xhdpi/ch_305_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_305_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_306_logo.png b/tests/common/res/drawable-xhdpi/ch_306_logo.png
index 0458b383..0458b383 100644
--- a/tests/input/res/drawable-xhdpi/ch_306_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_306_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_307_logo.png b/tests/common/res/drawable-xhdpi/ch_307_logo.png
index f2a35cd5..f2a35cd5 100644
--- a/tests/input/res/drawable-xhdpi/ch_307_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_307_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_308_logo.png b/tests/common/res/drawable-xhdpi/ch_308_logo.png
index 49d2b4b3..49d2b4b3 100644
--- a/tests/input/res/drawable-xhdpi/ch_308_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_308_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_309_logo.png b/tests/common/res/drawable-xhdpi/ch_309_logo.png
index 81da237b..81da237b 100644
--- a/tests/input/res/drawable-xhdpi/ch_309_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_309_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_30_logo.png b/tests/common/res/drawable-xhdpi/ch_30_logo.png
index 72db9c52..72db9c52 100644
--- a/tests/input/res/drawable-xhdpi/ch_30_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_30_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_310_logo.png b/tests/common/res/drawable-xhdpi/ch_310_logo.png
index 901a9113..901a9113 100644
--- a/tests/input/res/drawable-xhdpi/ch_310_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_310_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_311_logo.png b/tests/common/res/drawable-xhdpi/ch_311_logo.png
index 0aa3b284..0aa3b284 100644
--- a/tests/input/res/drawable-xhdpi/ch_311_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_311_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_312_logo.png b/tests/common/res/drawable-xhdpi/ch_312_logo.png
index 0cfead7e..0cfead7e 100644
--- a/tests/input/res/drawable-xhdpi/ch_312_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_312_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_313_logo.png b/tests/common/res/drawable-xhdpi/ch_313_logo.png
index b552c871..b552c871 100644
--- a/tests/input/res/drawable-xhdpi/ch_313_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_313_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_314_logo.png b/tests/common/res/drawable-xhdpi/ch_314_logo.png
index 354ab843..354ab843 100644
--- a/tests/input/res/drawable-xhdpi/ch_314_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_314_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_315_logo.png b/tests/common/res/drawable-xhdpi/ch_315_logo.png
index 2db60cca..2db60cca 100644
--- a/tests/input/res/drawable-xhdpi/ch_315_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_315_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_316_logo.png b/tests/common/res/drawable-xhdpi/ch_316_logo.png
index da4d32a3..da4d32a3 100644
--- a/tests/input/res/drawable-xhdpi/ch_316_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_316_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_317_logo.png b/tests/common/res/drawable-xhdpi/ch_317_logo.png
index d344ef36..d344ef36 100644
--- a/tests/input/res/drawable-xhdpi/ch_317_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_317_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_318_logo.png b/tests/common/res/drawable-xhdpi/ch_318_logo.png
index 9150c2b1..9150c2b1 100644
--- a/tests/input/res/drawable-xhdpi/ch_318_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_318_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_319_logo.png b/tests/common/res/drawable-xhdpi/ch_319_logo.png
index 4b1b7c9d..4b1b7c9d 100644
--- a/tests/input/res/drawable-xhdpi/ch_319_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_319_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_31_logo.png b/tests/common/res/drawable-xhdpi/ch_31_logo.png
index 5386601d..5386601d 100644
--- a/tests/input/res/drawable-xhdpi/ch_31_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_31_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_320_logo.png b/tests/common/res/drawable-xhdpi/ch_320_logo.png
index 4efe21d4..4efe21d4 100644
--- a/tests/input/res/drawable-xhdpi/ch_320_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_320_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_321_logo.png b/tests/common/res/drawable-xhdpi/ch_321_logo.png
index d523277d..d523277d 100644
--- a/tests/input/res/drawable-xhdpi/ch_321_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_321_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_322_logo.png b/tests/common/res/drawable-xhdpi/ch_322_logo.png
index cf2500dc..cf2500dc 100644
--- a/tests/input/res/drawable-xhdpi/ch_322_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_322_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_323_logo.png b/tests/common/res/drawable-xhdpi/ch_323_logo.png
index e838c0c1..e838c0c1 100644
--- a/tests/input/res/drawable-xhdpi/ch_323_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_323_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_324_logo.png b/tests/common/res/drawable-xhdpi/ch_324_logo.png
index cc0cf6d2..cc0cf6d2 100644
--- a/tests/input/res/drawable-xhdpi/ch_324_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_324_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_325_logo.png b/tests/common/res/drawable-xhdpi/ch_325_logo.png
index adfda884..adfda884 100644
--- a/tests/input/res/drawable-xhdpi/ch_325_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_325_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_326_logo.png b/tests/common/res/drawable-xhdpi/ch_326_logo.png
index 434d2cd6..434d2cd6 100644
--- a/tests/input/res/drawable-xhdpi/ch_326_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_326_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_327_logo.png b/tests/common/res/drawable-xhdpi/ch_327_logo.png
index 0a7f0b95..0a7f0b95 100644
--- a/tests/input/res/drawable-xhdpi/ch_327_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_327_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_328_logo.png b/tests/common/res/drawable-xhdpi/ch_328_logo.png
index 77129370..77129370 100644
--- a/tests/input/res/drawable-xhdpi/ch_328_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_328_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_329_logo.png b/tests/common/res/drawable-xhdpi/ch_329_logo.png
index 9ff0a89f..9ff0a89f 100644
--- a/tests/input/res/drawable-xhdpi/ch_329_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_329_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_32_logo.png b/tests/common/res/drawable-xhdpi/ch_32_logo.png
index 39351ac1..39351ac1 100644
--- a/tests/input/res/drawable-xhdpi/ch_32_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_32_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_330_logo.png b/tests/common/res/drawable-xhdpi/ch_330_logo.png
index 54adc2e7..54adc2e7 100644
--- a/tests/input/res/drawable-xhdpi/ch_330_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_330_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_331_logo.png b/tests/common/res/drawable-xhdpi/ch_331_logo.png
index 6c29286f..6c29286f 100644
--- a/tests/input/res/drawable-xhdpi/ch_331_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_331_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_332_logo.png b/tests/common/res/drawable-xhdpi/ch_332_logo.png
index ccab9144..ccab9144 100644
--- a/tests/input/res/drawable-xhdpi/ch_332_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_332_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_333_logo.png b/tests/common/res/drawable-xhdpi/ch_333_logo.png
index a35ce116..a35ce116 100644
--- a/tests/input/res/drawable-xhdpi/ch_333_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_333_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_334_logo.png b/tests/common/res/drawable-xhdpi/ch_334_logo.png
index a191d804..a191d804 100644
--- a/tests/input/res/drawable-xhdpi/ch_334_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_334_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_335_logo.png b/tests/common/res/drawable-xhdpi/ch_335_logo.png
index a5680b24..a5680b24 100644
--- a/tests/input/res/drawable-xhdpi/ch_335_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_335_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_336_logo.png b/tests/common/res/drawable-xhdpi/ch_336_logo.png
index 42292bf8..42292bf8 100644
--- a/tests/input/res/drawable-xhdpi/ch_336_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_336_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_337_logo.png b/tests/common/res/drawable-xhdpi/ch_337_logo.png
index d231fca3..d231fca3 100644
--- a/tests/input/res/drawable-xhdpi/ch_337_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_337_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_338_logo.png b/tests/common/res/drawable-xhdpi/ch_338_logo.png
index 000988ab..000988ab 100644
--- a/tests/input/res/drawable-xhdpi/ch_338_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_338_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_339_logo.png b/tests/common/res/drawable-xhdpi/ch_339_logo.png
index 3150c92c..3150c92c 100644
--- a/tests/input/res/drawable-xhdpi/ch_339_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_339_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_33_logo.png b/tests/common/res/drawable-xhdpi/ch_33_logo.png
index 4931e205..4931e205 100644
--- a/tests/input/res/drawable-xhdpi/ch_33_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_33_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_340_logo.png b/tests/common/res/drawable-xhdpi/ch_340_logo.png
index d35d772e..d35d772e 100644
--- a/tests/input/res/drawable-xhdpi/ch_340_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_340_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_341_logo.png b/tests/common/res/drawable-xhdpi/ch_341_logo.png
index 3ad19a0b..3ad19a0b 100644
--- a/tests/input/res/drawable-xhdpi/ch_341_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_341_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_342_logo.png b/tests/common/res/drawable-xhdpi/ch_342_logo.png
index 8d6cad2c..8d6cad2c 100644
--- a/tests/input/res/drawable-xhdpi/ch_342_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_342_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_343_logo.png b/tests/common/res/drawable-xhdpi/ch_343_logo.png
index 6e16dc96..6e16dc96 100644
--- a/tests/input/res/drawable-xhdpi/ch_343_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_343_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_344_logo.png b/tests/common/res/drawable-xhdpi/ch_344_logo.png
index e66c5a19..e66c5a19 100644
--- a/tests/input/res/drawable-xhdpi/ch_344_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_344_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_345_logo.png b/tests/common/res/drawable-xhdpi/ch_345_logo.png
index ed451fde..ed451fde 100644
--- a/tests/input/res/drawable-xhdpi/ch_345_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_345_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_346_logo.png b/tests/common/res/drawable-xhdpi/ch_346_logo.png
index 31059671..31059671 100644
--- a/tests/input/res/drawable-xhdpi/ch_346_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_346_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_347_logo.png b/tests/common/res/drawable-xhdpi/ch_347_logo.png
index 65ee51eb..65ee51eb 100644
--- a/tests/input/res/drawable-xhdpi/ch_347_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_347_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_348_logo.png b/tests/common/res/drawable-xhdpi/ch_348_logo.png
index 54e9cca7..54e9cca7 100644
--- a/tests/input/res/drawable-xhdpi/ch_348_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_348_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_349_logo.png b/tests/common/res/drawable-xhdpi/ch_349_logo.png
index 7a11ae34..7a11ae34 100644
--- a/tests/input/res/drawable-xhdpi/ch_349_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_349_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_34_logo.png b/tests/common/res/drawable-xhdpi/ch_34_logo.png
index 27a217e8..27a217e8 100644
--- a/tests/input/res/drawable-xhdpi/ch_34_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_34_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_350_logo.png b/tests/common/res/drawable-xhdpi/ch_350_logo.png
index 5c486ab7..5c486ab7 100644
--- a/tests/input/res/drawable-xhdpi/ch_350_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_350_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_351_logo.png b/tests/common/res/drawable-xhdpi/ch_351_logo.png
index 17fff276..17fff276 100644
--- a/tests/input/res/drawable-xhdpi/ch_351_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_351_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_352_logo.png b/tests/common/res/drawable-xhdpi/ch_352_logo.png
index 2d9c412c..2d9c412c 100644
--- a/tests/input/res/drawable-xhdpi/ch_352_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_352_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_353_logo.png b/tests/common/res/drawable-xhdpi/ch_353_logo.png
index 38c76b38..38c76b38 100644
--- a/tests/input/res/drawable-xhdpi/ch_353_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_353_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_354_logo.png b/tests/common/res/drawable-xhdpi/ch_354_logo.png
index 8ea7d467..8ea7d467 100644
--- a/tests/input/res/drawable-xhdpi/ch_354_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_354_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_355_logo.png b/tests/common/res/drawable-xhdpi/ch_355_logo.png
index 0c94dcf6..0c94dcf6 100644
--- a/tests/input/res/drawable-xhdpi/ch_355_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_355_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_356_logo.png b/tests/common/res/drawable-xhdpi/ch_356_logo.png
index 3f2b288a..3f2b288a 100644
--- a/tests/input/res/drawable-xhdpi/ch_356_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_356_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_357_logo.png b/tests/common/res/drawable-xhdpi/ch_357_logo.png
index 63d43c31..63d43c31 100644
--- a/tests/input/res/drawable-xhdpi/ch_357_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_357_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_358_logo.png b/tests/common/res/drawable-xhdpi/ch_358_logo.png
index 1f5771fe..1f5771fe 100644
--- a/tests/input/res/drawable-xhdpi/ch_358_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_358_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_359_logo.png b/tests/common/res/drawable-xhdpi/ch_359_logo.png
index 7a4114bd..7a4114bd 100644
--- a/tests/input/res/drawable-xhdpi/ch_359_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_359_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_35_logo.png b/tests/common/res/drawable-xhdpi/ch_35_logo.png
index af2cae5d..af2cae5d 100644
--- a/tests/input/res/drawable-xhdpi/ch_35_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_35_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_360_logo.png b/tests/common/res/drawable-xhdpi/ch_360_logo.png
index 4e49a1f9..4e49a1f9 100644
--- a/tests/input/res/drawable-xhdpi/ch_360_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_360_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_361_logo.png b/tests/common/res/drawable-xhdpi/ch_361_logo.png
index 43b16ac6..43b16ac6 100644
--- a/tests/input/res/drawable-xhdpi/ch_361_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_361_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_362_logo.png b/tests/common/res/drawable-xhdpi/ch_362_logo.png
index efb32dab..efb32dab 100644
--- a/tests/input/res/drawable-xhdpi/ch_362_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_362_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_363_logo.png b/tests/common/res/drawable-xhdpi/ch_363_logo.png
index c59eb0b3..c59eb0b3 100644
--- a/tests/input/res/drawable-xhdpi/ch_363_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_363_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_364_logo.png b/tests/common/res/drawable-xhdpi/ch_364_logo.png
index 9d649d47..9d649d47 100644
--- a/tests/input/res/drawable-xhdpi/ch_364_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_364_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_365_logo.png b/tests/common/res/drawable-xhdpi/ch_365_logo.png
index 96cae282..96cae282 100644
--- a/tests/input/res/drawable-xhdpi/ch_365_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_365_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_366_logo.png b/tests/common/res/drawable-xhdpi/ch_366_logo.png
index 3c3a5cf6..3c3a5cf6 100644
--- a/tests/input/res/drawable-xhdpi/ch_366_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_366_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_367_logo.png b/tests/common/res/drawable-xhdpi/ch_367_logo.png
index 7467625a..7467625a 100644
--- a/tests/input/res/drawable-xhdpi/ch_367_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_367_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_368_logo.png b/tests/common/res/drawable-xhdpi/ch_368_logo.png
index adb62ffc..adb62ffc 100644
--- a/tests/input/res/drawable-xhdpi/ch_368_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_368_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_369_logo.png b/tests/common/res/drawable-xhdpi/ch_369_logo.png
index 773f6c5c..773f6c5c 100644
--- a/tests/input/res/drawable-xhdpi/ch_369_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_369_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_36_logo.png b/tests/common/res/drawable-xhdpi/ch_36_logo.png
index 4580833f..4580833f 100644
--- a/tests/input/res/drawable-xhdpi/ch_36_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_36_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_370_logo.png b/tests/common/res/drawable-xhdpi/ch_370_logo.png
index d60583bc..d60583bc 100644
--- a/tests/input/res/drawable-xhdpi/ch_370_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_370_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_371_logo.png b/tests/common/res/drawable-xhdpi/ch_371_logo.png
index 91958a07..91958a07 100644
--- a/tests/input/res/drawable-xhdpi/ch_371_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_371_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_372_logo.png b/tests/common/res/drawable-xhdpi/ch_372_logo.png
index 4b2d757c..4b2d757c 100644
--- a/tests/input/res/drawable-xhdpi/ch_372_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_372_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_373_logo.png b/tests/common/res/drawable-xhdpi/ch_373_logo.png
index f8aae527..f8aae527 100644
--- a/tests/input/res/drawable-xhdpi/ch_373_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_373_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_374_logo.png b/tests/common/res/drawable-xhdpi/ch_374_logo.png
index 3549da94..3549da94 100644
--- a/tests/input/res/drawable-xhdpi/ch_374_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_374_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_375_logo.png b/tests/common/res/drawable-xhdpi/ch_375_logo.png
index c19806e8..c19806e8 100644
--- a/tests/input/res/drawable-xhdpi/ch_375_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_375_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_376_logo.png b/tests/common/res/drawable-xhdpi/ch_376_logo.png
index 86144b73..86144b73 100644
--- a/tests/input/res/drawable-xhdpi/ch_376_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_376_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_377_logo.png b/tests/common/res/drawable-xhdpi/ch_377_logo.png
index 74f693c1..74f693c1 100644
--- a/tests/input/res/drawable-xhdpi/ch_377_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_377_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_378_logo.png b/tests/common/res/drawable-xhdpi/ch_378_logo.png
index 40253dab..40253dab 100644
--- a/tests/input/res/drawable-xhdpi/ch_378_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_378_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_379_logo.png b/tests/common/res/drawable-xhdpi/ch_379_logo.png
index 5459058f..5459058f 100644
--- a/tests/input/res/drawable-xhdpi/ch_379_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_379_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_37_logo.png b/tests/common/res/drawable-xhdpi/ch_37_logo.png
index 7fce3b4d..7fce3b4d 100644
--- a/tests/input/res/drawable-xhdpi/ch_37_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_37_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_380_logo.png b/tests/common/res/drawable-xhdpi/ch_380_logo.png
index a47a40d8..a47a40d8 100644
--- a/tests/input/res/drawable-xhdpi/ch_380_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_380_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_381_logo.png b/tests/common/res/drawable-xhdpi/ch_381_logo.png
index 7059114c..7059114c 100644
--- a/tests/input/res/drawable-xhdpi/ch_381_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_381_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_382_logo.png b/tests/common/res/drawable-xhdpi/ch_382_logo.png
index a61201a5..a61201a5 100644
--- a/tests/input/res/drawable-xhdpi/ch_382_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_382_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_383_logo.png b/tests/common/res/drawable-xhdpi/ch_383_logo.png
index c126d6e3..c126d6e3 100644
--- a/tests/input/res/drawable-xhdpi/ch_383_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_383_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_384_logo.png b/tests/common/res/drawable-xhdpi/ch_384_logo.png
index 0bd5f454..0bd5f454 100644
--- a/tests/input/res/drawable-xhdpi/ch_384_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_384_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_385_logo.png b/tests/common/res/drawable-xhdpi/ch_385_logo.png
index 864ff5c6..864ff5c6 100644
--- a/tests/input/res/drawable-xhdpi/ch_385_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_385_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_386_logo.png b/tests/common/res/drawable-xhdpi/ch_386_logo.png
index 643db67a..643db67a 100644
--- a/tests/input/res/drawable-xhdpi/ch_386_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_386_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_387_logo.png b/tests/common/res/drawable-xhdpi/ch_387_logo.png
index 206ec14f..206ec14f 100644
--- a/tests/input/res/drawable-xhdpi/ch_387_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_387_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_388_logo.png b/tests/common/res/drawable-xhdpi/ch_388_logo.png
index 37c9dbae..37c9dbae 100644
--- a/tests/input/res/drawable-xhdpi/ch_388_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_388_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_389_logo.png b/tests/common/res/drawable-xhdpi/ch_389_logo.png
index 958ffb63..958ffb63 100644
--- a/tests/input/res/drawable-xhdpi/ch_389_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_389_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_38_logo.png b/tests/common/res/drawable-xhdpi/ch_38_logo.png
index 6e864bf8..6e864bf8 100644
--- a/tests/input/res/drawable-xhdpi/ch_38_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_38_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_390_logo.png b/tests/common/res/drawable-xhdpi/ch_390_logo.png
index a5a6547e..a5a6547e 100644
--- a/tests/input/res/drawable-xhdpi/ch_390_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_390_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_391_logo.png b/tests/common/res/drawable-xhdpi/ch_391_logo.png
index 0d1c076b..0d1c076b 100644
--- a/tests/input/res/drawable-xhdpi/ch_391_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_391_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_392_logo.png b/tests/common/res/drawable-xhdpi/ch_392_logo.png
index 25e3a87a..25e3a87a 100644
--- a/tests/input/res/drawable-xhdpi/ch_392_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_392_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_393_logo.png b/tests/common/res/drawable-xhdpi/ch_393_logo.png
index 92ebefe2..92ebefe2 100644
--- a/tests/input/res/drawable-xhdpi/ch_393_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_393_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_394_logo.png b/tests/common/res/drawable-xhdpi/ch_394_logo.png
index b220319a..b220319a 100644
--- a/tests/input/res/drawable-xhdpi/ch_394_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_394_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_395_logo.png b/tests/common/res/drawable-xhdpi/ch_395_logo.png
index 29df3f8f..29df3f8f 100644
--- a/tests/input/res/drawable-xhdpi/ch_395_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_395_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_396_logo.png b/tests/common/res/drawable-xhdpi/ch_396_logo.png
index f1e6f983..f1e6f983 100644
--- a/tests/input/res/drawable-xhdpi/ch_396_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_396_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_397_logo.png b/tests/common/res/drawable-xhdpi/ch_397_logo.png
index 7f44d63c..7f44d63c 100644
--- a/tests/input/res/drawable-xhdpi/ch_397_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_397_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_398_logo.png b/tests/common/res/drawable-xhdpi/ch_398_logo.png
index 03b14271..03b14271 100644
--- a/tests/input/res/drawable-xhdpi/ch_398_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_398_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_399_logo.png b/tests/common/res/drawable-xhdpi/ch_399_logo.png
index a15aaa4e..a15aaa4e 100644
--- a/tests/input/res/drawable-xhdpi/ch_399_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_399_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_39_logo.png b/tests/common/res/drawable-xhdpi/ch_39_logo.png
index 633a1172..633a1172 100644
--- a/tests/input/res/drawable-xhdpi/ch_39_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_39_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_3_logo.png b/tests/common/res/drawable-xhdpi/ch_3_logo.png
index 9c921385..9c921385 100644
--- a/tests/input/res/drawable-xhdpi/ch_3_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_3_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_400_logo.png b/tests/common/res/drawable-xhdpi/ch_400_logo.png
index 15442662..15442662 100644
--- a/tests/input/res/drawable-xhdpi/ch_400_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_400_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_401_logo.png b/tests/common/res/drawable-xhdpi/ch_401_logo.png
index c4d06916..c4d06916 100644
--- a/tests/input/res/drawable-xhdpi/ch_401_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_401_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_402_logo.png b/tests/common/res/drawable-xhdpi/ch_402_logo.png
index b8719f32..b8719f32 100644
--- a/tests/input/res/drawable-xhdpi/ch_402_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_402_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_403_logo.png b/tests/common/res/drawable-xhdpi/ch_403_logo.png
index 054b98b7..054b98b7 100644
--- a/tests/input/res/drawable-xhdpi/ch_403_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_403_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_404_logo.png b/tests/common/res/drawable-xhdpi/ch_404_logo.png
index 64566990..64566990 100644
--- a/tests/input/res/drawable-xhdpi/ch_404_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_404_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_405_logo.png b/tests/common/res/drawable-xhdpi/ch_405_logo.png
index 2ceab3fb..2ceab3fb 100644
--- a/tests/input/res/drawable-xhdpi/ch_405_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_405_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_406_logo.png b/tests/common/res/drawable-xhdpi/ch_406_logo.png
index f7557109..f7557109 100644
--- a/tests/input/res/drawable-xhdpi/ch_406_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_406_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_407_logo.png b/tests/common/res/drawable-xhdpi/ch_407_logo.png
index 8228e1c5..8228e1c5 100644
--- a/tests/input/res/drawable-xhdpi/ch_407_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_407_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_408_logo.png b/tests/common/res/drawable-xhdpi/ch_408_logo.png
index d9c09b85..d9c09b85 100644
--- a/tests/input/res/drawable-xhdpi/ch_408_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_408_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_409_logo.png b/tests/common/res/drawable-xhdpi/ch_409_logo.png
index fd2b76e5..fd2b76e5 100644
--- a/tests/input/res/drawable-xhdpi/ch_409_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_409_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_40_logo.png b/tests/common/res/drawable-xhdpi/ch_40_logo.png
index 63600168..63600168 100644
--- a/tests/input/res/drawable-xhdpi/ch_40_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_40_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_410_logo.png b/tests/common/res/drawable-xhdpi/ch_410_logo.png
index 8b05de2e..8b05de2e 100644
--- a/tests/input/res/drawable-xhdpi/ch_410_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_410_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_411_logo.png b/tests/common/res/drawable-xhdpi/ch_411_logo.png
index 7306991e..7306991e 100644
--- a/tests/input/res/drawable-xhdpi/ch_411_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_411_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_412_logo.png b/tests/common/res/drawable-xhdpi/ch_412_logo.png
index 55964214..55964214 100644
--- a/tests/input/res/drawable-xhdpi/ch_412_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_412_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_413_logo.png b/tests/common/res/drawable-xhdpi/ch_413_logo.png
index c744901d..c744901d 100644
--- a/tests/input/res/drawable-xhdpi/ch_413_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_413_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_414_logo.png b/tests/common/res/drawable-xhdpi/ch_414_logo.png
index 304dc7da..304dc7da 100644
--- a/tests/input/res/drawable-xhdpi/ch_414_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_414_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_415_logo.png b/tests/common/res/drawable-xhdpi/ch_415_logo.png
index 1a9b1f19..1a9b1f19 100644
--- a/tests/input/res/drawable-xhdpi/ch_415_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_415_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_416_logo.png b/tests/common/res/drawable-xhdpi/ch_416_logo.png
index 53318edf..53318edf 100644
--- a/tests/input/res/drawable-xhdpi/ch_416_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_416_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_417_logo.png b/tests/common/res/drawable-xhdpi/ch_417_logo.png
index 763bad1b..763bad1b 100644
--- a/tests/input/res/drawable-xhdpi/ch_417_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_417_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_418_logo.png b/tests/common/res/drawable-xhdpi/ch_418_logo.png
index afa06409..afa06409 100644
--- a/tests/input/res/drawable-xhdpi/ch_418_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_418_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_419_logo.png b/tests/common/res/drawable-xhdpi/ch_419_logo.png
index 4741b659..4741b659 100644
--- a/tests/input/res/drawable-xhdpi/ch_419_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_419_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_41_logo.png b/tests/common/res/drawable-xhdpi/ch_41_logo.png
index 6002ae31..6002ae31 100644
--- a/tests/input/res/drawable-xhdpi/ch_41_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_41_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_420_logo.png b/tests/common/res/drawable-xhdpi/ch_420_logo.png
index 22a72aec..22a72aec 100644
--- a/tests/input/res/drawable-xhdpi/ch_420_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_420_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_421_logo.png b/tests/common/res/drawable-xhdpi/ch_421_logo.png
index f4c301dd..f4c301dd 100644
--- a/tests/input/res/drawable-xhdpi/ch_421_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_421_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_422_logo.png b/tests/common/res/drawable-xhdpi/ch_422_logo.png
index e70d59ac..e70d59ac 100644
--- a/tests/input/res/drawable-xhdpi/ch_422_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_422_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_423_logo.png b/tests/common/res/drawable-xhdpi/ch_423_logo.png
index a4c96fbd..a4c96fbd 100644
--- a/tests/input/res/drawable-xhdpi/ch_423_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_423_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_424_logo.png b/tests/common/res/drawable-xhdpi/ch_424_logo.png
index 9dc1713e..9dc1713e 100644
--- a/tests/input/res/drawable-xhdpi/ch_424_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_424_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_425_logo.png b/tests/common/res/drawable-xhdpi/ch_425_logo.png
index a79e8f5c..a79e8f5c 100644
--- a/tests/input/res/drawable-xhdpi/ch_425_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_425_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_426_logo.png b/tests/common/res/drawable-xhdpi/ch_426_logo.png
index 34bcbef0..34bcbef0 100644
--- a/tests/input/res/drawable-xhdpi/ch_426_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_426_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_427_logo.png b/tests/common/res/drawable-xhdpi/ch_427_logo.png
index 6133494d..6133494d 100644
--- a/tests/input/res/drawable-xhdpi/ch_427_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_427_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_428_logo.png b/tests/common/res/drawable-xhdpi/ch_428_logo.png
index d91391a4..d91391a4 100644
--- a/tests/input/res/drawable-xhdpi/ch_428_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_428_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_429_logo.png b/tests/common/res/drawable-xhdpi/ch_429_logo.png
index f24a64f9..f24a64f9 100644
--- a/tests/input/res/drawable-xhdpi/ch_429_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_429_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_42_logo.png b/tests/common/res/drawable-xhdpi/ch_42_logo.png
index c2f641c0..c2f641c0 100644
--- a/tests/input/res/drawable-xhdpi/ch_42_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_42_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_430_logo.png b/tests/common/res/drawable-xhdpi/ch_430_logo.png
index e656d6da..e656d6da 100644
--- a/tests/input/res/drawable-xhdpi/ch_430_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_430_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_431_logo.png b/tests/common/res/drawable-xhdpi/ch_431_logo.png
index 4827d71d..4827d71d 100644
--- a/tests/input/res/drawable-xhdpi/ch_431_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_431_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_432_logo.png b/tests/common/res/drawable-xhdpi/ch_432_logo.png
index bb5493e2..bb5493e2 100644
--- a/tests/input/res/drawable-xhdpi/ch_432_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_432_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_433_logo.png b/tests/common/res/drawable-xhdpi/ch_433_logo.png
index f777f36a..f777f36a 100644
--- a/tests/input/res/drawable-xhdpi/ch_433_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_433_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_434_logo.png b/tests/common/res/drawable-xhdpi/ch_434_logo.png
index f342df85..f342df85 100644
--- a/tests/input/res/drawable-xhdpi/ch_434_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_434_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_435_logo.png b/tests/common/res/drawable-xhdpi/ch_435_logo.png
index 70667e7a..70667e7a 100644
--- a/tests/input/res/drawable-xhdpi/ch_435_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_435_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_436_logo.png b/tests/common/res/drawable-xhdpi/ch_436_logo.png
index 1895a238..1895a238 100644
--- a/tests/input/res/drawable-xhdpi/ch_436_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_436_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_437_logo.png b/tests/common/res/drawable-xhdpi/ch_437_logo.png
index 9b6b335b..9b6b335b 100644
--- a/tests/input/res/drawable-xhdpi/ch_437_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_437_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_438_logo.png b/tests/common/res/drawable-xhdpi/ch_438_logo.png
index 5070cdb1..5070cdb1 100644
--- a/tests/input/res/drawable-xhdpi/ch_438_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_438_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_439_logo.png b/tests/common/res/drawable-xhdpi/ch_439_logo.png
index adcad27b..adcad27b 100644
--- a/tests/input/res/drawable-xhdpi/ch_439_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_439_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_43_logo.png b/tests/common/res/drawable-xhdpi/ch_43_logo.png
index 5ea7d814..5ea7d814 100644
--- a/tests/input/res/drawable-xhdpi/ch_43_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_43_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_440_logo.png b/tests/common/res/drawable-xhdpi/ch_440_logo.png
index 0b1f76c6..0b1f76c6 100644
--- a/tests/input/res/drawable-xhdpi/ch_440_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_440_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_441_logo.png b/tests/common/res/drawable-xhdpi/ch_441_logo.png
index 65870b6e..65870b6e 100644
--- a/tests/input/res/drawable-xhdpi/ch_441_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_441_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_442_logo.png b/tests/common/res/drawable-xhdpi/ch_442_logo.png
index 9812a1cb..9812a1cb 100644
--- a/tests/input/res/drawable-xhdpi/ch_442_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_442_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_443_logo.png b/tests/common/res/drawable-xhdpi/ch_443_logo.png
index d539f5c1..d539f5c1 100644
--- a/tests/input/res/drawable-xhdpi/ch_443_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_443_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_444_logo.png b/tests/common/res/drawable-xhdpi/ch_444_logo.png
index fbf615d9..fbf615d9 100644
--- a/tests/input/res/drawable-xhdpi/ch_444_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_444_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_445_logo.png b/tests/common/res/drawable-xhdpi/ch_445_logo.png
index 440085aa..440085aa 100644
--- a/tests/input/res/drawable-xhdpi/ch_445_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_445_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_446_logo.png b/tests/common/res/drawable-xhdpi/ch_446_logo.png
index d26f1c37..d26f1c37 100644
--- a/tests/input/res/drawable-xhdpi/ch_446_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_446_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_447_logo.png b/tests/common/res/drawable-xhdpi/ch_447_logo.png
index 0967878d..0967878d 100644
--- a/tests/input/res/drawable-xhdpi/ch_447_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_447_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_448_logo.png b/tests/common/res/drawable-xhdpi/ch_448_logo.png
index b979c062..b979c062 100644
--- a/tests/input/res/drawable-xhdpi/ch_448_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_448_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_449_logo.png b/tests/common/res/drawable-xhdpi/ch_449_logo.png
index 2232b90e..2232b90e 100644
--- a/tests/input/res/drawable-xhdpi/ch_449_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_449_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_44_logo.png b/tests/common/res/drawable-xhdpi/ch_44_logo.png
index be6cbd3b..be6cbd3b 100644
--- a/tests/input/res/drawable-xhdpi/ch_44_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_44_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_450_logo.png b/tests/common/res/drawable-xhdpi/ch_450_logo.png
index 8e25df9a..8e25df9a 100644
--- a/tests/input/res/drawable-xhdpi/ch_450_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_450_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_451_logo.png b/tests/common/res/drawable-xhdpi/ch_451_logo.png
index c744e56e..c744e56e 100644
--- a/tests/input/res/drawable-xhdpi/ch_451_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_451_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_452_logo.png b/tests/common/res/drawable-xhdpi/ch_452_logo.png
index 050b0196..050b0196 100644
--- a/tests/input/res/drawable-xhdpi/ch_452_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_452_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_453_logo.png b/tests/common/res/drawable-xhdpi/ch_453_logo.png
index 4ccdbf14..4ccdbf14 100644
--- a/tests/input/res/drawable-xhdpi/ch_453_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_453_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_454_logo.png b/tests/common/res/drawable-xhdpi/ch_454_logo.png
index 10aa3779..10aa3779 100644
--- a/tests/input/res/drawable-xhdpi/ch_454_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_454_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_455_logo.png b/tests/common/res/drawable-xhdpi/ch_455_logo.png
index 7b607a6c..7b607a6c 100644
--- a/tests/input/res/drawable-xhdpi/ch_455_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_455_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_456_logo.png b/tests/common/res/drawable-xhdpi/ch_456_logo.png
index f2d57066..f2d57066 100644
--- a/tests/input/res/drawable-xhdpi/ch_456_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_456_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_457_logo.png b/tests/common/res/drawable-xhdpi/ch_457_logo.png
index 483e5912..483e5912 100644
--- a/tests/input/res/drawable-xhdpi/ch_457_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_457_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_458_logo.png b/tests/common/res/drawable-xhdpi/ch_458_logo.png
index 447d5942..447d5942 100644
--- a/tests/input/res/drawable-xhdpi/ch_458_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_458_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_459_logo.png b/tests/common/res/drawable-xhdpi/ch_459_logo.png
index 80d6c5b6..80d6c5b6 100644
--- a/tests/input/res/drawable-xhdpi/ch_459_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_459_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_45_logo.png b/tests/common/res/drawable-xhdpi/ch_45_logo.png
index 0db467c8..0db467c8 100644
--- a/tests/input/res/drawable-xhdpi/ch_45_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_45_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_460_logo.png b/tests/common/res/drawable-xhdpi/ch_460_logo.png
index 22d785cb..22d785cb 100644
--- a/tests/input/res/drawable-xhdpi/ch_460_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_460_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_461_logo.png b/tests/common/res/drawable-xhdpi/ch_461_logo.png
index 658a1046..658a1046 100644
--- a/tests/input/res/drawable-xhdpi/ch_461_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_461_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_462_logo.png b/tests/common/res/drawable-xhdpi/ch_462_logo.png
index dd0c5d14..dd0c5d14 100644
--- a/tests/input/res/drawable-xhdpi/ch_462_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_462_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_463_logo.png b/tests/common/res/drawable-xhdpi/ch_463_logo.png
index 7b72b915..7b72b915 100644
--- a/tests/input/res/drawable-xhdpi/ch_463_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_463_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_464_logo.png b/tests/common/res/drawable-xhdpi/ch_464_logo.png
index cc15444c..cc15444c 100644
--- a/tests/input/res/drawable-xhdpi/ch_464_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_464_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_465_logo.png b/tests/common/res/drawable-xhdpi/ch_465_logo.png
index a17cb719..a17cb719 100644
--- a/tests/input/res/drawable-xhdpi/ch_465_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_465_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_466_logo.png b/tests/common/res/drawable-xhdpi/ch_466_logo.png
index 604644f4..604644f4 100644
--- a/tests/input/res/drawable-xhdpi/ch_466_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_466_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_467_logo.png b/tests/common/res/drawable-xhdpi/ch_467_logo.png
index 4c74b50d..4c74b50d 100644
--- a/tests/input/res/drawable-xhdpi/ch_467_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_467_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_468_logo.png b/tests/common/res/drawable-xhdpi/ch_468_logo.png
index 8e329206..8e329206 100644
--- a/tests/input/res/drawable-xhdpi/ch_468_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_468_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_469_logo.png b/tests/common/res/drawable-xhdpi/ch_469_logo.png
index 14a1d99e..14a1d99e 100644
--- a/tests/input/res/drawable-xhdpi/ch_469_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_469_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_46_logo.png b/tests/common/res/drawable-xhdpi/ch_46_logo.png
index f9d83ea9..f9d83ea9 100644
--- a/tests/input/res/drawable-xhdpi/ch_46_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_46_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_470_logo.png b/tests/common/res/drawable-xhdpi/ch_470_logo.png
index 567e879a..567e879a 100644
--- a/tests/input/res/drawable-xhdpi/ch_470_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_470_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_471_logo.png b/tests/common/res/drawable-xhdpi/ch_471_logo.png
index 4a128a0e..4a128a0e 100644
--- a/tests/input/res/drawable-xhdpi/ch_471_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_471_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_472_logo.png b/tests/common/res/drawable-xhdpi/ch_472_logo.png
index f00d1cb0..f00d1cb0 100644
--- a/tests/input/res/drawable-xhdpi/ch_472_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_472_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_473_logo.png b/tests/common/res/drawable-xhdpi/ch_473_logo.png
index ee7bbfc9..ee7bbfc9 100644
--- a/tests/input/res/drawable-xhdpi/ch_473_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_473_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_474_logo.png b/tests/common/res/drawable-xhdpi/ch_474_logo.png
index a1b7e0eb..a1b7e0eb 100644
--- a/tests/input/res/drawable-xhdpi/ch_474_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_474_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_475_logo.png b/tests/common/res/drawable-xhdpi/ch_475_logo.png
index 14db7abe..14db7abe 100644
--- a/tests/input/res/drawable-xhdpi/ch_475_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_475_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_476_logo.png b/tests/common/res/drawable-xhdpi/ch_476_logo.png
index 89c71e80..89c71e80 100644
--- a/tests/input/res/drawable-xhdpi/ch_476_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_476_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_477_logo.png b/tests/common/res/drawable-xhdpi/ch_477_logo.png
index 60509130..60509130 100644
--- a/tests/input/res/drawable-xhdpi/ch_477_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_477_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_478_logo.png b/tests/common/res/drawable-xhdpi/ch_478_logo.png
index a2c3069b..a2c3069b 100644
--- a/tests/input/res/drawable-xhdpi/ch_478_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_478_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_479_logo.png b/tests/common/res/drawable-xhdpi/ch_479_logo.png
index 2be6ae4f..2be6ae4f 100644
--- a/tests/input/res/drawable-xhdpi/ch_479_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_479_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_47_logo.png b/tests/common/res/drawable-xhdpi/ch_47_logo.png
index ed4b464a..ed4b464a 100644
--- a/tests/input/res/drawable-xhdpi/ch_47_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_47_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_480_logo.png b/tests/common/res/drawable-xhdpi/ch_480_logo.png
index f2a2d6fa..f2a2d6fa 100644
--- a/tests/input/res/drawable-xhdpi/ch_480_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_480_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_481_logo.png b/tests/common/res/drawable-xhdpi/ch_481_logo.png
index b71fcfa8..b71fcfa8 100644
--- a/tests/input/res/drawable-xhdpi/ch_481_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_481_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_482_logo.png b/tests/common/res/drawable-xhdpi/ch_482_logo.png
index 8d317e47..8d317e47 100644
--- a/tests/input/res/drawable-xhdpi/ch_482_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_482_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_483_logo.png b/tests/common/res/drawable-xhdpi/ch_483_logo.png
index ea417f9e..ea417f9e 100644
--- a/tests/input/res/drawable-xhdpi/ch_483_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_483_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_484_logo.png b/tests/common/res/drawable-xhdpi/ch_484_logo.png
index b46584a4..b46584a4 100644
--- a/tests/input/res/drawable-xhdpi/ch_484_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_484_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_485_logo.png b/tests/common/res/drawable-xhdpi/ch_485_logo.png
index 3564dcd5..3564dcd5 100644
--- a/tests/input/res/drawable-xhdpi/ch_485_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_485_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_486_logo.png b/tests/common/res/drawable-xhdpi/ch_486_logo.png
index 8227575f..8227575f 100644
--- a/tests/input/res/drawable-xhdpi/ch_486_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_486_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_487_logo.png b/tests/common/res/drawable-xhdpi/ch_487_logo.png
index edb15bee..edb15bee 100644
--- a/tests/input/res/drawable-xhdpi/ch_487_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_487_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_488_logo.png b/tests/common/res/drawable-xhdpi/ch_488_logo.png
index f358d335..f358d335 100644
--- a/tests/input/res/drawable-xhdpi/ch_488_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_488_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_489_logo.png b/tests/common/res/drawable-xhdpi/ch_489_logo.png
index 5122c67e..5122c67e 100644
--- a/tests/input/res/drawable-xhdpi/ch_489_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_489_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_48_logo.png b/tests/common/res/drawable-xhdpi/ch_48_logo.png
index e1be7313..e1be7313 100644
--- a/tests/input/res/drawable-xhdpi/ch_48_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_48_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_490_logo.png b/tests/common/res/drawable-xhdpi/ch_490_logo.png
index 1901d995..1901d995 100644
--- a/tests/input/res/drawable-xhdpi/ch_490_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_490_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_491_logo.png b/tests/common/res/drawable-xhdpi/ch_491_logo.png
index 04b0a021..04b0a021 100644
--- a/tests/input/res/drawable-xhdpi/ch_491_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_491_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_492_logo.png b/tests/common/res/drawable-xhdpi/ch_492_logo.png
index b18dea9b..b18dea9b 100644
--- a/tests/input/res/drawable-xhdpi/ch_492_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_492_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_493_logo.png b/tests/common/res/drawable-xhdpi/ch_493_logo.png
index 19044655..19044655 100644
--- a/tests/input/res/drawable-xhdpi/ch_493_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_493_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_494_logo.png b/tests/common/res/drawable-xhdpi/ch_494_logo.png
index b5b0f76c..b5b0f76c 100644
--- a/tests/input/res/drawable-xhdpi/ch_494_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_494_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_495_logo.png b/tests/common/res/drawable-xhdpi/ch_495_logo.png
index 6124dc83..6124dc83 100644
--- a/tests/input/res/drawable-xhdpi/ch_495_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_495_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_496_logo.png b/tests/common/res/drawable-xhdpi/ch_496_logo.png
index 6b0e472b..6b0e472b 100644
--- a/tests/input/res/drawable-xhdpi/ch_496_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_496_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_497_logo.png b/tests/common/res/drawable-xhdpi/ch_497_logo.png
index 31fcd048..31fcd048 100644
--- a/tests/input/res/drawable-xhdpi/ch_497_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_497_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_498_logo.png b/tests/common/res/drawable-xhdpi/ch_498_logo.png
index 472c09b6..472c09b6 100644
--- a/tests/input/res/drawable-xhdpi/ch_498_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_498_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_499_logo.png b/tests/common/res/drawable-xhdpi/ch_499_logo.png
index 2d653f61..2d653f61 100644
--- a/tests/input/res/drawable-xhdpi/ch_499_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_499_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_49_logo.png b/tests/common/res/drawable-xhdpi/ch_49_logo.png
index 46bc774d..46bc774d 100644
--- a/tests/input/res/drawable-xhdpi/ch_49_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_49_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_4_logo.png b/tests/common/res/drawable-xhdpi/ch_4_logo.png
index d5e6517c..d5e6517c 100644
--- a/tests/input/res/drawable-xhdpi/ch_4_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_4_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_500_logo.png b/tests/common/res/drawable-xhdpi/ch_500_logo.png
index ecfa17ec..ecfa17ec 100644
--- a/tests/input/res/drawable-xhdpi/ch_500_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_500_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_501_logo.png b/tests/common/res/drawable-xhdpi/ch_501_logo.png
index 0c81a787..0c81a787 100644
--- a/tests/input/res/drawable-xhdpi/ch_501_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_501_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_502_logo.png b/tests/common/res/drawable-xhdpi/ch_502_logo.png
index 5dd20644..5dd20644 100644
--- a/tests/input/res/drawable-xhdpi/ch_502_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_502_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_503_logo.png b/tests/common/res/drawable-xhdpi/ch_503_logo.png
index a48ec52d..a48ec52d 100644
--- a/tests/input/res/drawable-xhdpi/ch_503_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_503_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_504_logo.png b/tests/common/res/drawable-xhdpi/ch_504_logo.png
index 999a641e..999a641e 100644
--- a/tests/input/res/drawable-xhdpi/ch_504_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_504_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_505_logo.png b/tests/common/res/drawable-xhdpi/ch_505_logo.png
index d7c600e4..d7c600e4 100644
--- a/tests/input/res/drawable-xhdpi/ch_505_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_505_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_506_logo.png b/tests/common/res/drawable-xhdpi/ch_506_logo.png
index ac80e6dd..ac80e6dd 100644
--- a/tests/input/res/drawable-xhdpi/ch_506_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_506_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_507_logo.png b/tests/common/res/drawable-xhdpi/ch_507_logo.png
index c4d434f8..c4d434f8 100644
--- a/tests/input/res/drawable-xhdpi/ch_507_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_507_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_508_logo.png b/tests/common/res/drawable-xhdpi/ch_508_logo.png
index 35330059..35330059 100644
--- a/tests/input/res/drawable-xhdpi/ch_508_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_508_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_509_logo.png b/tests/common/res/drawable-xhdpi/ch_509_logo.png
index 2077eac5..2077eac5 100644
--- a/tests/input/res/drawable-xhdpi/ch_509_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_509_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_50_logo.png b/tests/common/res/drawable-xhdpi/ch_50_logo.png
index 901373e6..901373e6 100644
--- a/tests/input/res/drawable-xhdpi/ch_50_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_50_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_510_logo.png b/tests/common/res/drawable-xhdpi/ch_510_logo.png
index 469bf77d..469bf77d 100644
--- a/tests/input/res/drawable-xhdpi/ch_510_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_510_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_511_logo.png b/tests/common/res/drawable-xhdpi/ch_511_logo.png
index 80d727bb..80d727bb 100644
--- a/tests/input/res/drawable-xhdpi/ch_511_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_511_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_512_logo.png b/tests/common/res/drawable-xhdpi/ch_512_logo.png
index 37ba7e2b..37ba7e2b 100644
--- a/tests/input/res/drawable-xhdpi/ch_512_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_512_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_513_logo.png b/tests/common/res/drawable-xhdpi/ch_513_logo.png
index ef7c4f2a..ef7c4f2a 100644
--- a/tests/input/res/drawable-xhdpi/ch_513_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_513_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_514_logo.png b/tests/common/res/drawable-xhdpi/ch_514_logo.png
index 450f5963..450f5963 100644
--- a/tests/input/res/drawable-xhdpi/ch_514_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_514_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_515_logo.png b/tests/common/res/drawable-xhdpi/ch_515_logo.png
index 6533b2fd..6533b2fd 100644
--- a/tests/input/res/drawable-xhdpi/ch_515_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_515_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_516_logo.png b/tests/common/res/drawable-xhdpi/ch_516_logo.png
index 08cd2f0d..08cd2f0d 100644
--- a/tests/input/res/drawable-xhdpi/ch_516_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_516_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_517_logo.png b/tests/common/res/drawable-xhdpi/ch_517_logo.png
index 1935d709..1935d709 100644
--- a/tests/input/res/drawable-xhdpi/ch_517_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_517_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_518_logo.png b/tests/common/res/drawable-xhdpi/ch_518_logo.png
index 806fbbbf..806fbbbf 100644
--- a/tests/input/res/drawable-xhdpi/ch_518_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_518_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_519_logo.png b/tests/common/res/drawable-xhdpi/ch_519_logo.png
index 938bb559..938bb559 100644
--- a/tests/input/res/drawable-xhdpi/ch_519_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_519_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_51_logo.png b/tests/common/res/drawable-xhdpi/ch_51_logo.png
index 07a5f4ad..07a5f4ad 100644
--- a/tests/input/res/drawable-xhdpi/ch_51_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_51_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_520_logo.png b/tests/common/res/drawable-xhdpi/ch_520_logo.png
index 7f9f68b2..7f9f68b2 100644
--- a/tests/input/res/drawable-xhdpi/ch_520_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_520_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_521_logo.png b/tests/common/res/drawable-xhdpi/ch_521_logo.png
index e8d0432c..e8d0432c 100644
--- a/tests/input/res/drawable-xhdpi/ch_521_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_521_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_522_logo.png b/tests/common/res/drawable-xhdpi/ch_522_logo.png
index d7345b8c..d7345b8c 100644
--- a/tests/input/res/drawable-xhdpi/ch_522_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_522_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_523_logo.png b/tests/common/res/drawable-xhdpi/ch_523_logo.png
index 61573120..61573120 100644
--- a/tests/input/res/drawable-xhdpi/ch_523_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_523_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_524_logo.png b/tests/common/res/drawable-xhdpi/ch_524_logo.png
index 9a8b2fdd..9a8b2fdd 100644
--- a/tests/input/res/drawable-xhdpi/ch_524_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_524_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_525_logo.png b/tests/common/res/drawable-xhdpi/ch_525_logo.png
index 9ed318fa..9ed318fa 100644
--- a/tests/input/res/drawable-xhdpi/ch_525_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_525_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_526_logo.png b/tests/common/res/drawable-xhdpi/ch_526_logo.png
index 5000af2a..5000af2a 100644
--- a/tests/input/res/drawable-xhdpi/ch_526_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_526_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_527_logo.png b/tests/common/res/drawable-xhdpi/ch_527_logo.png
index 38fbd9eb..38fbd9eb 100644
--- a/tests/input/res/drawable-xhdpi/ch_527_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_527_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_528_logo.png b/tests/common/res/drawable-xhdpi/ch_528_logo.png
index 565e8b2a..565e8b2a 100644
--- a/tests/input/res/drawable-xhdpi/ch_528_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_528_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_529_logo.png b/tests/common/res/drawable-xhdpi/ch_529_logo.png
index b0924df7..b0924df7 100644
--- a/tests/input/res/drawable-xhdpi/ch_529_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_529_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_52_logo.png b/tests/common/res/drawable-xhdpi/ch_52_logo.png
index 6faa9702..6faa9702 100644
--- a/tests/input/res/drawable-xhdpi/ch_52_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_52_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_530_logo.png b/tests/common/res/drawable-xhdpi/ch_530_logo.png
index 0eec0234..0eec0234 100644
--- a/tests/input/res/drawable-xhdpi/ch_530_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_530_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_531_logo.png b/tests/common/res/drawable-xhdpi/ch_531_logo.png
index 2f0243d1..2f0243d1 100644
--- a/tests/input/res/drawable-xhdpi/ch_531_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_531_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_532_logo.png b/tests/common/res/drawable-xhdpi/ch_532_logo.png
index a6ece89e..a6ece89e 100644
--- a/tests/input/res/drawable-xhdpi/ch_532_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_532_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_533_logo.png b/tests/common/res/drawable-xhdpi/ch_533_logo.png
index a1695158..a1695158 100644
--- a/tests/input/res/drawable-xhdpi/ch_533_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_533_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_534_logo.png b/tests/common/res/drawable-xhdpi/ch_534_logo.png
index 00ad0b07..00ad0b07 100644
--- a/tests/input/res/drawable-xhdpi/ch_534_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_534_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_535_logo.png b/tests/common/res/drawable-xhdpi/ch_535_logo.png
index a536ff32..a536ff32 100644
--- a/tests/input/res/drawable-xhdpi/ch_535_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_535_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_536_logo.png b/tests/common/res/drawable-xhdpi/ch_536_logo.png
index 60fcdf33..60fcdf33 100644
--- a/tests/input/res/drawable-xhdpi/ch_536_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_536_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_537_logo.png b/tests/common/res/drawable-xhdpi/ch_537_logo.png
index 0446d9bc..0446d9bc 100644
--- a/tests/input/res/drawable-xhdpi/ch_537_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_537_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_538_logo.png b/tests/common/res/drawable-xhdpi/ch_538_logo.png
index 6f98e08d..6f98e08d 100644
--- a/tests/input/res/drawable-xhdpi/ch_538_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_538_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_539_logo.png b/tests/common/res/drawable-xhdpi/ch_539_logo.png
index b6f17bbb..b6f17bbb 100644
--- a/tests/input/res/drawable-xhdpi/ch_539_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_539_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_53_logo.png b/tests/common/res/drawable-xhdpi/ch_53_logo.png
index 441e1d97..441e1d97 100644
--- a/tests/input/res/drawable-xhdpi/ch_53_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_53_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_540_logo.png b/tests/common/res/drawable-xhdpi/ch_540_logo.png
index 61950bff..61950bff 100644
--- a/tests/input/res/drawable-xhdpi/ch_540_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_540_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_541_logo.png b/tests/common/res/drawable-xhdpi/ch_541_logo.png
index eea9a988..eea9a988 100644
--- a/tests/input/res/drawable-xhdpi/ch_541_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_541_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_542_logo.png b/tests/common/res/drawable-xhdpi/ch_542_logo.png
index 684cf6d1..684cf6d1 100644
--- a/tests/input/res/drawable-xhdpi/ch_542_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_542_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_543_logo.png b/tests/common/res/drawable-xhdpi/ch_543_logo.png
index 44e4e6e0..44e4e6e0 100644
--- a/tests/input/res/drawable-xhdpi/ch_543_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_543_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_544_logo.png b/tests/common/res/drawable-xhdpi/ch_544_logo.png
index adf6c97a..adf6c97a 100644
--- a/tests/input/res/drawable-xhdpi/ch_544_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_544_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_545_logo.png b/tests/common/res/drawable-xhdpi/ch_545_logo.png
index 57f8edc6..57f8edc6 100644
--- a/tests/input/res/drawable-xhdpi/ch_545_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_545_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_546_logo.png b/tests/common/res/drawable-xhdpi/ch_546_logo.png
index 4ac92311..4ac92311 100644
--- a/tests/input/res/drawable-xhdpi/ch_546_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_546_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_547_logo.png b/tests/common/res/drawable-xhdpi/ch_547_logo.png
index ca857974..ca857974 100644
--- a/tests/input/res/drawable-xhdpi/ch_547_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_547_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_548_logo.png b/tests/common/res/drawable-xhdpi/ch_548_logo.png
index 1037011c..1037011c 100644
--- a/tests/input/res/drawable-xhdpi/ch_548_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_548_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_549_logo.png b/tests/common/res/drawable-xhdpi/ch_549_logo.png
index fd10a2ee..fd10a2ee 100644
--- a/tests/input/res/drawable-xhdpi/ch_549_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_549_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_54_logo.png b/tests/common/res/drawable-xhdpi/ch_54_logo.png
index 50f22f48..50f22f48 100644
--- a/tests/input/res/drawable-xhdpi/ch_54_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_54_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_550_logo.png b/tests/common/res/drawable-xhdpi/ch_550_logo.png
index 992666b6..992666b6 100644
--- a/tests/input/res/drawable-xhdpi/ch_550_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_550_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_551_logo.png b/tests/common/res/drawable-xhdpi/ch_551_logo.png
index 41369f0b..41369f0b 100644
--- a/tests/input/res/drawable-xhdpi/ch_551_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_551_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_552_logo.png b/tests/common/res/drawable-xhdpi/ch_552_logo.png
index 56be3e73..56be3e73 100644
--- a/tests/input/res/drawable-xhdpi/ch_552_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_552_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_553_logo.png b/tests/common/res/drawable-xhdpi/ch_553_logo.png
index 04812119..04812119 100644
--- a/tests/input/res/drawable-xhdpi/ch_553_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_553_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_554_logo.png b/tests/common/res/drawable-xhdpi/ch_554_logo.png
index b7e943a3..b7e943a3 100644
--- a/tests/input/res/drawable-xhdpi/ch_554_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_554_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_555_logo.png b/tests/common/res/drawable-xhdpi/ch_555_logo.png
index fb74741b..fb74741b 100644
--- a/tests/input/res/drawable-xhdpi/ch_555_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_555_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_556_logo.png b/tests/common/res/drawable-xhdpi/ch_556_logo.png
index 8c6d4046..8c6d4046 100644
--- a/tests/input/res/drawable-xhdpi/ch_556_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_556_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_557_logo.png b/tests/common/res/drawable-xhdpi/ch_557_logo.png
index fe65c25c..fe65c25c 100644
--- a/tests/input/res/drawable-xhdpi/ch_557_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_557_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_558_logo.png b/tests/common/res/drawable-xhdpi/ch_558_logo.png
index 598e6424..598e6424 100644
--- a/tests/input/res/drawable-xhdpi/ch_558_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_558_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_559_logo.png b/tests/common/res/drawable-xhdpi/ch_559_logo.png
index 68a46085..68a46085 100644
--- a/tests/input/res/drawable-xhdpi/ch_559_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_559_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_55_logo.png b/tests/common/res/drawable-xhdpi/ch_55_logo.png
index 59f21e84..59f21e84 100644
--- a/tests/input/res/drawable-xhdpi/ch_55_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_55_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_560_logo.png b/tests/common/res/drawable-xhdpi/ch_560_logo.png
index db6d6693..db6d6693 100644
--- a/tests/input/res/drawable-xhdpi/ch_560_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_560_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_561_logo.png b/tests/common/res/drawable-xhdpi/ch_561_logo.png
index b53f08f0..b53f08f0 100644
--- a/tests/input/res/drawable-xhdpi/ch_561_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_561_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_562_logo.png b/tests/common/res/drawable-xhdpi/ch_562_logo.png
index 970f0174..970f0174 100644
--- a/tests/input/res/drawable-xhdpi/ch_562_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_562_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_563_logo.png b/tests/common/res/drawable-xhdpi/ch_563_logo.png
index 1c426378..1c426378 100644
--- a/tests/input/res/drawable-xhdpi/ch_563_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_563_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_564_logo.png b/tests/common/res/drawable-xhdpi/ch_564_logo.png
index 61a89f16..61a89f16 100644
--- a/tests/input/res/drawable-xhdpi/ch_564_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_564_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_565_logo.png b/tests/common/res/drawable-xhdpi/ch_565_logo.png
index 956342b2..956342b2 100644
--- a/tests/input/res/drawable-xhdpi/ch_565_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_565_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_566_logo.png b/tests/common/res/drawable-xhdpi/ch_566_logo.png
index a935ec4a..a935ec4a 100644
--- a/tests/input/res/drawable-xhdpi/ch_566_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_566_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_567_logo.png b/tests/common/res/drawable-xhdpi/ch_567_logo.png
index 4d6e407e..4d6e407e 100644
--- a/tests/input/res/drawable-xhdpi/ch_567_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_567_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_568_logo.png b/tests/common/res/drawable-xhdpi/ch_568_logo.png
index f4578ed0..f4578ed0 100644
--- a/tests/input/res/drawable-xhdpi/ch_568_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_568_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_569_logo.png b/tests/common/res/drawable-xhdpi/ch_569_logo.png
index 807c7323..807c7323 100644
--- a/tests/input/res/drawable-xhdpi/ch_569_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_569_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_56_logo.png b/tests/common/res/drawable-xhdpi/ch_56_logo.png
index dc296510..dc296510 100644
--- a/tests/input/res/drawable-xhdpi/ch_56_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_56_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_570_logo.png b/tests/common/res/drawable-xhdpi/ch_570_logo.png
index ef03c654..ef03c654 100644
--- a/tests/input/res/drawable-xhdpi/ch_570_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_570_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_571_logo.png b/tests/common/res/drawable-xhdpi/ch_571_logo.png
index 422f9aa4..422f9aa4 100644
--- a/tests/input/res/drawable-xhdpi/ch_571_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_571_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_572_logo.png b/tests/common/res/drawable-xhdpi/ch_572_logo.png
index 68d08376..68d08376 100644
--- a/tests/input/res/drawable-xhdpi/ch_572_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_572_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_573_logo.png b/tests/common/res/drawable-xhdpi/ch_573_logo.png
index 1d8ca402..1d8ca402 100644
--- a/tests/input/res/drawable-xhdpi/ch_573_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_573_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_574_logo.png b/tests/common/res/drawable-xhdpi/ch_574_logo.png
index f582224a..f582224a 100644
--- a/tests/input/res/drawable-xhdpi/ch_574_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_574_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_575_logo.png b/tests/common/res/drawable-xhdpi/ch_575_logo.png
index 44fc827b..44fc827b 100644
--- a/tests/input/res/drawable-xhdpi/ch_575_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_575_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_576_logo.png b/tests/common/res/drawable-xhdpi/ch_576_logo.png
index a8c9b36d..a8c9b36d 100644
--- a/tests/input/res/drawable-xhdpi/ch_576_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_576_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_577_logo.png b/tests/common/res/drawable-xhdpi/ch_577_logo.png
index 328c67a9..328c67a9 100644
--- a/tests/input/res/drawable-xhdpi/ch_577_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_577_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_578_logo.png b/tests/common/res/drawable-xhdpi/ch_578_logo.png
index d856dac5..d856dac5 100644
--- a/tests/input/res/drawable-xhdpi/ch_578_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_578_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_579_logo.png b/tests/common/res/drawable-xhdpi/ch_579_logo.png
index 2a989c37..2a989c37 100644
--- a/tests/input/res/drawable-xhdpi/ch_579_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_579_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_57_logo.png b/tests/common/res/drawable-xhdpi/ch_57_logo.png
index 72981424..72981424 100644
--- a/tests/input/res/drawable-xhdpi/ch_57_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_57_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_580_logo.png b/tests/common/res/drawable-xhdpi/ch_580_logo.png
index 4c8034c8..4c8034c8 100644
--- a/tests/input/res/drawable-xhdpi/ch_580_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_580_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_581_logo.png b/tests/common/res/drawable-xhdpi/ch_581_logo.png
index 7423ef65..7423ef65 100644
--- a/tests/input/res/drawable-xhdpi/ch_581_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_581_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_582_logo.png b/tests/common/res/drawable-xhdpi/ch_582_logo.png
index ffbc803d..ffbc803d 100644
--- a/tests/input/res/drawable-xhdpi/ch_582_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_582_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_583_logo.png b/tests/common/res/drawable-xhdpi/ch_583_logo.png
index d6b92dce..d6b92dce 100644
--- a/tests/input/res/drawable-xhdpi/ch_583_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_583_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_584_logo.png b/tests/common/res/drawable-xhdpi/ch_584_logo.png
index cecbe6c7..cecbe6c7 100644
--- a/tests/input/res/drawable-xhdpi/ch_584_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_584_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_585_logo.png b/tests/common/res/drawable-xhdpi/ch_585_logo.png
index 99b994f7..99b994f7 100644
--- a/tests/input/res/drawable-xhdpi/ch_585_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_585_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_586_logo.png b/tests/common/res/drawable-xhdpi/ch_586_logo.png
index a54afdd4..a54afdd4 100644
--- a/tests/input/res/drawable-xhdpi/ch_586_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_586_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_587_logo.png b/tests/common/res/drawable-xhdpi/ch_587_logo.png
index e09f40ff..e09f40ff 100644
--- a/tests/input/res/drawable-xhdpi/ch_587_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_587_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_588_logo.png b/tests/common/res/drawable-xhdpi/ch_588_logo.png
index e4b3c192..e4b3c192 100644
--- a/tests/input/res/drawable-xhdpi/ch_588_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_588_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_589_logo.png b/tests/common/res/drawable-xhdpi/ch_589_logo.png
index 2c451a54..2c451a54 100644
--- a/tests/input/res/drawable-xhdpi/ch_589_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_589_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_58_logo.png b/tests/common/res/drawable-xhdpi/ch_58_logo.png
index 07f71a01..07f71a01 100644
--- a/tests/input/res/drawable-xhdpi/ch_58_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_58_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_590_logo.png b/tests/common/res/drawable-xhdpi/ch_590_logo.png
index 56e5e60c..56e5e60c 100644
--- a/tests/input/res/drawable-xhdpi/ch_590_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_590_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_591_logo.png b/tests/common/res/drawable-xhdpi/ch_591_logo.png
index 09e1a554..09e1a554 100644
--- a/tests/input/res/drawable-xhdpi/ch_591_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_591_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_592_logo.png b/tests/common/res/drawable-xhdpi/ch_592_logo.png
index 82635ce4..82635ce4 100644
--- a/tests/input/res/drawable-xhdpi/ch_592_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_592_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_593_logo.png b/tests/common/res/drawable-xhdpi/ch_593_logo.png
index 21f8e54c..21f8e54c 100644
--- a/tests/input/res/drawable-xhdpi/ch_593_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_593_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_594_logo.png b/tests/common/res/drawable-xhdpi/ch_594_logo.png
index 8de16c08..8de16c08 100644
--- a/tests/input/res/drawable-xhdpi/ch_594_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_594_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_595_logo.png b/tests/common/res/drawable-xhdpi/ch_595_logo.png
index 7fd01896..7fd01896 100644
--- a/tests/input/res/drawable-xhdpi/ch_595_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_595_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_596_logo.png b/tests/common/res/drawable-xhdpi/ch_596_logo.png
index 35452d61..35452d61 100644
--- a/tests/input/res/drawable-xhdpi/ch_596_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_596_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_597_logo.png b/tests/common/res/drawable-xhdpi/ch_597_logo.png
index c812338a..c812338a 100644
--- a/tests/input/res/drawable-xhdpi/ch_597_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_597_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_598_logo.png b/tests/common/res/drawable-xhdpi/ch_598_logo.png
index 6a7a4da0..6a7a4da0 100644
--- a/tests/input/res/drawable-xhdpi/ch_598_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_598_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_599_logo.png b/tests/common/res/drawable-xhdpi/ch_599_logo.png
index 9bb000ac..9bb000ac 100644
--- a/tests/input/res/drawable-xhdpi/ch_599_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_599_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_59_logo.png b/tests/common/res/drawable-xhdpi/ch_59_logo.png
index a7a0155f..a7a0155f 100644
--- a/tests/input/res/drawable-xhdpi/ch_59_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_59_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_5_logo.png b/tests/common/res/drawable-xhdpi/ch_5_logo.png
index 2de0c9cc..2de0c9cc 100644
--- a/tests/input/res/drawable-xhdpi/ch_5_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_5_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_600_logo.png b/tests/common/res/drawable-xhdpi/ch_600_logo.png
index e3b247e9..e3b247e9 100644
--- a/tests/input/res/drawable-xhdpi/ch_600_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_600_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_601_logo.png b/tests/common/res/drawable-xhdpi/ch_601_logo.png
index ff572b8c..ff572b8c 100644
--- a/tests/input/res/drawable-xhdpi/ch_601_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_601_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_602_logo.png b/tests/common/res/drawable-xhdpi/ch_602_logo.png
index 56d0505a..56d0505a 100644
--- a/tests/input/res/drawable-xhdpi/ch_602_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_602_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_603_logo.png b/tests/common/res/drawable-xhdpi/ch_603_logo.png
index e0d30043..e0d30043 100644
--- a/tests/input/res/drawable-xhdpi/ch_603_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_603_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_604_logo.png b/tests/common/res/drawable-xhdpi/ch_604_logo.png
index 4a592ff9..4a592ff9 100644
--- a/tests/input/res/drawable-xhdpi/ch_604_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_604_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_605_logo.png b/tests/common/res/drawable-xhdpi/ch_605_logo.png
index e415b276..e415b276 100644
--- a/tests/input/res/drawable-xhdpi/ch_605_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_605_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_606_logo.png b/tests/common/res/drawable-xhdpi/ch_606_logo.png
index 2c7b490b..2c7b490b 100644
--- a/tests/input/res/drawable-xhdpi/ch_606_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_606_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_607_logo.png b/tests/common/res/drawable-xhdpi/ch_607_logo.png
index 649d0327..649d0327 100644
--- a/tests/input/res/drawable-xhdpi/ch_607_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_607_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_608_logo.png b/tests/common/res/drawable-xhdpi/ch_608_logo.png
index 5581b4d9..5581b4d9 100644
--- a/tests/input/res/drawable-xhdpi/ch_608_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_608_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_609_logo.png b/tests/common/res/drawable-xhdpi/ch_609_logo.png
index da8f4bb3..da8f4bb3 100644
--- a/tests/input/res/drawable-xhdpi/ch_609_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_609_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_60_logo.png b/tests/common/res/drawable-xhdpi/ch_60_logo.png
index 0ee771f8..0ee771f8 100644
--- a/tests/input/res/drawable-xhdpi/ch_60_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_60_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_610_logo.png b/tests/common/res/drawable-xhdpi/ch_610_logo.png
index 7cdbcbd6..7cdbcbd6 100644
--- a/tests/input/res/drawable-xhdpi/ch_610_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_610_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_611_logo.png b/tests/common/res/drawable-xhdpi/ch_611_logo.png
index b14d3f54..b14d3f54 100644
--- a/tests/input/res/drawable-xhdpi/ch_611_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_611_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_612_logo.png b/tests/common/res/drawable-xhdpi/ch_612_logo.png
index d56de9ff..d56de9ff 100644
--- a/tests/input/res/drawable-xhdpi/ch_612_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_612_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_613_logo.png b/tests/common/res/drawable-xhdpi/ch_613_logo.png
index 7cfec8b5..7cfec8b5 100644
--- a/tests/input/res/drawable-xhdpi/ch_613_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_613_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_614_logo.png b/tests/common/res/drawable-xhdpi/ch_614_logo.png
index cc7841ce..cc7841ce 100644
--- a/tests/input/res/drawable-xhdpi/ch_614_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_614_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_615_logo.png b/tests/common/res/drawable-xhdpi/ch_615_logo.png
index 6c38d269..6c38d269 100644
--- a/tests/input/res/drawable-xhdpi/ch_615_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_615_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_616_logo.png b/tests/common/res/drawable-xhdpi/ch_616_logo.png
index e11b777d..e11b777d 100644
--- a/tests/input/res/drawable-xhdpi/ch_616_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_616_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_617_logo.png b/tests/common/res/drawable-xhdpi/ch_617_logo.png
index 78aeb608..78aeb608 100644
--- a/tests/input/res/drawable-xhdpi/ch_617_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_617_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_618_logo.png b/tests/common/res/drawable-xhdpi/ch_618_logo.png
index e1f883fb..e1f883fb 100644
--- a/tests/input/res/drawable-xhdpi/ch_618_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_618_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_619_logo.png b/tests/common/res/drawable-xhdpi/ch_619_logo.png
index 75f4eeba..75f4eeba 100644
--- a/tests/input/res/drawable-xhdpi/ch_619_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_619_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_61_logo.png b/tests/common/res/drawable-xhdpi/ch_61_logo.png
index 801cb923..801cb923 100644
--- a/tests/input/res/drawable-xhdpi/ch_61_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_61_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_620_logo.png b/tests/common/res/drawable-xhdpi/ch_620_logo.png
index b6380b73..b6380b73 100644
--- a/tests/input/res/drawable-xhdpi/ch_620_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_620_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_621_logo.png b/tests/common/res/drawable-xhdpi/ch_621_logo.png
index e6a53185..e6a53185 100644
--- a/tests/input/res/drawable-xhdpi/ch_621_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_621_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_622_logo.png b/tests/common/res/drawable-xhdpi/ch_622_logo.png
index 1cde4b8f..1cde4b8f 100644
--- a/tests/input/res/drawable-xhdpi/ch_622_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_622_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_623_logo.png b/tests/common/res/drawable-xhdpi/ch_623_logo.png
index f271e516..f271e516 100644
--- a/tests/input/res/drawable-xhdpi/ch_623_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_623_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_624_logo.png b/tests/common/res/drawable-xhdpi/ch_624_logo.png
index 21343a8c..21343a8c 100644
--- a/tests/input/res/drawable-xhdpi/ch_624_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_624_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_625_logo.png b/tests/common/res/drawable-xhdpi/ch_625_logo.png
index e15b9853..e15b9853 100644
--- a/tests/input/res/drawable-xhdpi/ch_625_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_625_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_626_logo.png b/tests/common/res/drawable-xhdpi/ch_626_logo.png
index c1f8e273..c1f8e273 100644
--- a/tests/input/res/drawable-xhdpi/ch_626_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_626_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_627_logo.png b/tests/common/res/drawable-xhdpi/ch_627_logo.png
index c07973b5..c07973b5 100644
--- a/tests/input/res/drawable-xhdpi/ch_627_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_627_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_628_logo.png b/tests/common/res/drawable-xhdpi/ch_628_logo.png
index 369240ca..369240ca 100644
--- a/tests/input/res/drawable-xhdpi/ch_628_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_628_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_629_logo.png b/tests/common/res/drawable-xhdpi/ch_629_logo.png
index ac9f7bd7..ac9f7bd7 100644
--- a/tests/input/res/drawable-xhdpi/ch_629_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_629_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_62_logo.png b/tests/common/res/drawable-xhdpi/ch_62_logo.png
index c4b48ea7..c4b48ea7 100644
--- a/tests/input/res/drawable-xhdpi/ch_62_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_62_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_630_logo.png b/tests/common/res/drawable-xhdpi/ch_630_logo.png
index 4959855a..4959855a 100644
--- a/tests/input/res/drawable-xhdpi/ch_630_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_630_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_631_logo.png b/tests/common/res/drawable-xhdpi/ch_631_logo.png
index e03e2706..e03e2706 100644
--- a/tests/input/res/drawable-xhdpi/ch_631_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_631_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_632_logo.png b/tests/common/res/drawable-xhdpi/ch_632_logo.png
index 5be9d478..5be9d478 100644
--- a/tests/input/res/drawable-xhdpi/ch_632_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_632_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_633_logo.png b/tests/common/res/drawable-xhdpi/ch_633_logo.png
index 9c51c4a7..9c51c4a7 100644
--- a/tests/input/res/drawable-xhdpi/ch_633_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_633_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_634_logo.png b/tests/common/res/drawable-xhdpi/ch_634_logo.png
index 72d30bc6..72d30bc6 100644
--- a/tests/input/res/drawable-xhdpi/ch_634_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_634_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_635_logo.png b/tests/common/res/drawable-xhdpi/ch_635_logo.png
index 6c03f3c5..6c03f3c5 100644
--- a/tests/input/res/drawable-xhdpi/ch_635_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_635_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_636_logo.png b/tests/common/res/drawable-xhdpi/ch_636_logo.png
index 928a67c2..928a67c2 100644
--- a/tests/input/res/drawable-xhdpi/ch_636_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_636_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_637_logo.png b/tests/common/res/drawable-xhdpi/ch_637_logo.png
index 4a07f186..4a07f186 100644
--- a/tests/input/res/drawable-xhdpi/ch_637_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_637_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_638_logo.png b/tests/common/res/drawable-xhdpi/ch_638_logo.png
index 33813958..33813958 100644
--- a/tests/input/res/drawable-xhdpi/ch_638_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_638_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_639_logo.png b/tests/common/res/drawable-xhdpi/ch_639_logo.png
index be6ba122..be6ba122 100644
--- a/tests/input/res/drawable-xhdpi/ch_639_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_639_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_63_logo.png b/tests/common/res/drawable-xhdpi/ch_63_logo.png
index dd84e2e6..dd84e2e6 100644
--- a/tests/input/res/drawable-xhdpi/ch_63_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_63_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_640_logo.png b/tests/common/res/drawable-xhdpi/ch_640_logo.png
index f6e1750c..f6e1750c 100644
--- a/tests/input/res/drawable-xhdpi/ch_640_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_640_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_641_logo.png b/tests/common/res/drawable-xhdpi/ch_641_logo.png
index 421019c8..421019c8 100644
--- a/tests/input/res/drawable-xhdpi/ch_641_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_641_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_642_logo.png b/tests/common/res/drawable-xhdpi/ch_642_logo.png
index e441876c..e441876c 100644
--- a/tests/input/res/drawable-xhdpi/ch_642_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_642_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_643_logo.png b/tests/common/res/drawable-xhdpi/ch_643_logo.png
index 29745014..29745014 100644
--- a/tests/input/res/drawable-xhdpi/ch_643_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_643_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_644_logo.png b/tests/common/res/drawable-xhdpi/ch_644_logo.png
index f5e4f2a0..f5e4f2a0 100644
--- a/tests/input/res/drawable-xhdpi/ch_644_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_644_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_645_logo.png b/tests/common/res/drawable-xhdpi/ch_645_logo.png
index bfa0d2cd..bfa0d2cd 100644
--- a/tests/input/res/drawable-xhdpi/ch_645_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_645_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_646_logo.png b/tests/common/res/drawable-xhdpi/ch_646_logo.png
index d148f910..d148f910 100644
--- a/tests/input/res/drawable-xhdpi/ch_646_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_646_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_647_logo.png b/tests/common/res/drawable-xhdpi/ch_647_logo.png
index cccc2c66..cccc2c66 100644
--- a/tests/input/res/drawable-xhdpi/ch_647_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_647_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_648_logo.png b/tests/common/res/drawable-xhdpi/ch_648_logo.png
index 1fa3cad7..1fa3cad7 100644
--- a/tests/input/res/drawable-xhdpi/ch_648_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_648_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_649_logo.png b/tests/common/res/drawable-xhdpi/ch_649_logo.png
index 0958fd36..0958fd36 100644
--- a/tests/input/res/drawable-xhdpi/ch_649_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_649_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_64_logo.png b/tests/common/res/drawable-xhdpi/ch_64_logo.png
index 9a6a84ec..9a6a84ec 100644
--- a/tests/input/res/drawable-xhdpi/ch_64_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_64_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_650_logo.png b/tests/common/res/drawable-xhdpi/ch_650_logo.png
index bd3ab1f0..bd3ab1f0 100644
--- a/tests/input/res/drawable-xhdpi/ch_650_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_650_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_651_logo.png b/tests/common/res/drawable-xhdpi/ch_651_logo.png
index 03e859a0..03e859a0 100644
--- a/tests/input/res/drawable-xhdpi/ch_651_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_651_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_652_logo.png b/tests/common/res/drawable-xhdpi/ch_652_logo.png
index 81b61689..81b61689 100644
--- a/tests/input/res/drawable-xhdpi/ch_652_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_652_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_653_logo.png b/tests/common/res/drawable-xhdpi/ch_653_logo.png
index f6665e5f..f6665e5f 100644
--- a/tests/input/res/drawable-xhdpi/ch_653_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_653_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_654_logo.png b/tests/common/res/drawable-xhdpi/ch_654_logo.png
index 6ca0e57c..6ca0e57c 100644
--- a/tests/input/res/drawable-xhdpi/ch_654_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_654_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_655_logo.png b/tests/common/res/drawable-xhdpi/ch_655_logo.png
index 51e7b392..51e7b392 100644
--- a/tests/input/res/drawable-xhdpi/ch_655_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_655_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_656_logo.png b/tests/common/res/drawable-xhdpi/ch_656_logo.png
index bae25480..bae25480 100644
--- a/tests/input/res/drawable-xhdpi/ch_656_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_656_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_657_logo.png b/tests/common/res/drawable-xhdpi/ch_657_logo.png
index 029e91c9..029e91c9 100644
--- a/tests/input/res/drawable-xhdpi/ch_657_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_657_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_658_logo.png b/tests/common/res/drawable-xhdpi/ch_658_logo.png
index 61a77eac..61a77eac 100644
--- a/tests/input/res/drawable-xhdpi/ch_658_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_658_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_659_logo.png b/tests/common/res/drawable-xhdpi/ch_659_logo.png
index f12e97ee..f12e97ee 100644
--- a/tests/input/res/drawable-xhdpi/ch_659_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_659_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_65_logo.png b/tests/common/res/drawable-xhdpi/ch_65_logo.png
index b770749e..b770749e 100644
--- a/tests/input/res/drawable-xhdpi/ch_65_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_65_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_660_logo.png b/tests/common/res/drawable-xhdpi/ch_660_logo.png
index 1408fb45..1408fb45 100644
--- a/tests/input/res/drawable-xhdpi/ch_660_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_660_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_661_logo.png b/tests/common/res/drawable-xhdpi/ch_661_logo.png
index f8224b76..f8224b76 100644
--- a/tests/input/res/drawable-xhdpi/ch_661_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_661_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_662_logo.png b/tests/common/res/drawable-xhdpi/ch_662_logo.png
index 08d36a1b..08d36a1b 100644
--- a/tests/input/res/drawable-xhdpi/ch_662_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_662_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_663_logo.png b/tests/common/res/drawable-xhdpi/ch_663_logo.png
index b95c596c..b95c596c 100644
--- a/tests/input/res/drawable-xhdpi/ch_663_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_663_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_664_logo.png b/tests/common/res/drawable-xhdpi/ch_664_logo.png
index 4c42427a..4c42427a 100644
--- a/tests/input/res/drawable-xhdpi/ch_664_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_664_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_665_logo.png b/tests/common/res/drawable-xhdpi/ch_665_logo.png
index c8918dce..c8918dce 100644
--- a/tests/input/res/drawable-xhdpi/ch_665_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_665_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_666_logo.png b/tests/common/res/drawable-xhdpi/ch_666_logo.png
index 6839f828..6839f828 100644
--- a/tests/input/res/drawable-xhdpi/ch_666_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_666_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_667_logo.png b/tests/common/res/drawable-xhdpi/ch_667_logo.png
index 28702195..28702195 100644
--- a/tests/input/res/drawable-xhdpi/ch_667_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_667_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_668_logo.png b/tests/common/res/drawable-xhdpi/ch_668_logo.png
index 944a8d46..944a8d46 100644
--- a/tests/input/res/drawable-xhdpi/ch_668_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_668_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_669_logo.png b/tests/common/res/drawable-xhdpi/ch_669_logo.png
index 2677744f..2677744f 100644
--- a/tests/input/res/drawable-xhdpi/ch_669_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_669_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_66_logo.png b/tests/common/res/drawable-xhdpi/ch_66_logo.png
index e298eb86..e298eb86 100644
--- a/tests/input/res/drawable-xhdpi/ch_66_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_66_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_670_logo.png b/tests/common/res/drawable-xhdpi/ch_670_logo.png
index bcb1d377..bcb1d377 100644
--- a/tests/input/res/drawable-xhdpi/ch_670_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_670_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_671_logo.png b/tests/common/res/drawable-xhdpi/ch_671_logo.png
index 3e01dba8..3e01dba8 100644
--- a/tests/input/res/drawable-xhdpi/ch_671_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_671_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_672_logo.png b/tests/common/res/drawable-xhdpi/ch_672_logo.png
index 478d3f22..478d3f22 100644
--- a/tests/input/res/drawable-xhdpi/ch_672_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_672_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_673_logo.png b/tests/common/res/drawable-xhdpi/ch_673_logo.png
index 123522db..123522db 100644
--- a/tests/input/res/drawable-xhdpi/ch_673_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_673_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_674_logo.png b/tests/common/res/drawable-xhdpi/ch_674_logo.png
index 25c44806..25c44806 100644
--- a/tests/input/res/drawable-xhdpi/ch_674_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_674_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_675_logo.png b/tests/common/res/drawable-xhdpi/ch_675_logo.png
index 223ba448..223ba448 100644
--- a/tests/input/res/drawable-xhdpi/ch_675_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_675_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_676_logo.png b/tests/common/res/drawable-xhdpi/ch_676_logo.png
index 12cca720..12cca720 100644
--- a/tests/input/res/drawable-xhdpi/ch_676_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_676_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_677_logo.png b/tests/common/res/drawable-xhdpi/ch_677_logo.png
index ec735de1..ec735de1 100644
--- a/tests/input/res/drawable-xhdpi/ch_677_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_677_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_678_logo.png b/tests/common/res/drawable-xhdpi/ch_678_logo.png
index 1eee9496..1eee9496 100644
--- a/tests/input/res/drawable-xhdpi/ch_678_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_678_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_679_logo.png b/tests/common/res/drawable-xhdpi/ch_679_logo.png
index 231b68eb..231b68eb 100644
--- a/tests/input/res/drawable-xhdpi/ch_679_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_679_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_67_logo.png b/tests/common/res/drawable-xhdpi/ch_67_logo.png
index 5fcf7946..5fcf7946 100644
--- a/tests/input/res/drawable-xhdpi/ch_67_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_67_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_680_logo.png b/tests/common/res/drawable-xhdpi/ch_680_logo.png
index 24c09b87..24c09b87 100644
--- a/tests/input/res/drawable-xhdpi/ch_680_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_680_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_681_logo.png b/tests/common/res/drawable-xhdpi/ch_681_logo.png
index 2bae5da6..2bae5da6 100644
--- a/tests/input/res/drawable-xhdpi/ch_681_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_681_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_682_logo.png b/tests/common/res/drawable-xhdpi/ch_682_logo.png
index 6bb1047f..6bb1047f 100644
--- a/tests/input/res/drawable-xhdpi/ch_682_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_682_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_683_logo.png b/tests/common/res/drawable-xhdpi/ch_683_logo.png
index 04be69f4..04be69f4 100644
--- a/tests/input/res/drawable-xhdpi/ch_683_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_683_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_684_logo.png b/tests/common/res/drawable-xhdpi/ch_684_logo.png
index 02e0666d..02e0666d 100644
--- a/tests/input/res/drawable-xhdpi/ch_684_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_684_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_685_logo.png b/tests/common/res/drawable-xhdpi/ch_685_logo.png
index ff410e54..ff410e54 100644
--- a/tests/input/res/drawable-xhdpi/ch_685_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_685_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_686_logo.png b/tests/common/res/drawable-xhdpi/ch_686_logo.png
index f93e7d7f..f93e7d7f 100644
--- a/tests/input/res/drawable-xhdpi/ch_686_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_686_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_687_logo.png b/tests/common/res/drawable-xhdpi/ch_687_logo.png
index a97a96f4..a97a96f4 100644
--- a/tests/input/res/drawable-xhdpi/ch_687_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_687_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_688_logo.png b/tests/common/res/drawable-xhdpi/ch_688_logo.png
index f094f64c..f094f64c 100644
--- a/tests/input/res/drawable-xhdpi/ch_688_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_688_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_689_logo.png b/tests/common/res/drawable-xhdpi/ch_689_logo.png
index c557b3f1..c557b3f1 100644
--- a/tests/input/res/drawable-xhdpi/ch_689_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_689_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_68_logo.png b/tests/common/res/drawable-xhdpi/ch_68_logo.png
index 957bcb55..957bcb55 100644
--- a/tests/input/res/drawable-xhdpi/ch_68_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_68_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_690_logo.png b/tests/common/res/drawable-xhdpi/ch_690_logo.png
index ee692d35..ee692d35 100644
--- a/tests/input/res/drawable-xhdpi/ch_690_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_690_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_691_logo.png b/tests/common/res/drawable-xhdpi/ch_691_logo.png
index 7087605e..7087605e 100644
--- a/tests/input/res/drawable-xhdpi/ch_691_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_691_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_692_logo.png b/tests/common/res/drawable-xhdpi/ch_692_logo.png
index 902b536f..902b536f 100644
--- a/tests/input/res/drawable-xhdpi/ch_692_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_692_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_693_logo.png b/tests/common/res/drawable-xhdpi/ch_693_logo.png
index 3fb1634e..3fb1634e 100644
--- a/tests/input/res/drawable-xhdpi/ch_693_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_693_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_694_logo.png b/tests/common/res/drawable-xhdpi/ch_694_logo.png
index baaa7b69..baaa7b69 100644
--- a/tests/input/res/drawable-xhdpi/ch_694_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_694_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_695_logo.png b/tests/common/res/drawable-xhdpi/ch_695_logo.png
index 1d957bfd..1d957bfd 100644
--- a/tests/input/res/drawable-xhdpi/ch_695_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_695_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_696_logo.png b/tests/common/res/drawable-xhdpi/ch_696_logo.png
index ca8ed9e8..ca8ed9e8 100644
--- a/tests/input/res/drawable-xhdpi/ch_696_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_696_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_697_logo.png b/tests/common/res/drawable-xhdpi/ch_697_logo.png
index e01c4825..e01c4825 100644
--- a/tests/input/res/drawable-xhdpi/ch_697_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_697_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_698_logo.png b/tests/common/res/drawable-xhdpi/ch_698_logo.png
index c6540359..c6540359 100644
--- a/tests/input/res/drawable-xhdpi/ch_698_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_698_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_699_logo.png b/tests/common/res/drawable-xhdpi/ch_699_logo.png
index 70a22946..70a22946 100644
--- a/tests/input/res/drawable-xhdpi/ch_699_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_699_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_69_logo.png b/tests/common/res/drawable-xhdpi/ch_69_logo.png
index 6ccbe33b..6ccbe33b 100644
--- a/tests/input/res/drawable-xhdpi/ch_69_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_69_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_6_logo.png b/tests/common/res/drawable-xhdpi/ch_6_logo.png
index 22887a6c..22887a6c 100644
--- a/tests/input/res/drawable-xhdpi/ch_6_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_6_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_700_logo.png b/tests/common/res/drawable-xhdpi/ch_700_logo.png
index 1cbf5379..1cbf5379 100644
--- a/tests/input/res/drawable-xhdpi/ch_700_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_700_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_701_logo.png b/tests/common/res/drawable-xhdpi/ch_701_logo.png
index 9b438c00..9b438c00 100644
--- a/tests/input/res/drawable-xhdpi/ch_701_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_701_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_702_logo.png b/tests/common/res/drawable-xhdpi/ch_702_logo.png
index 92bef76d..92bef76d 100644
--- a/tests/input/res/drawable-xhdpi/ch_702_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_702_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_703_logo.png b/tests/common/res/drawable-xhdpi/ch_703_logo.png
index 78d680b0..78d680b0 100644
--- a/tests/input/res/drawable-xhdpi/ch_703_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_703_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_704_logo.png b/tests/common/res/drawable-xhdpi/ch_704_logo.png
index fcb61adb..fcb61adb 100644
--- a/tests/input/res/drawable-xhdpi/ch_704_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_704_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_705_logo.png b/tests/common/res/drawable-xhdpi/ch_705_logo.png
index 87566617..87566617 100644
--- a/tests/input/res/drawable-xhdpi/ch_705_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_705_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_706_logo.png b/tests/common/res/drawable-xhdpi/ch_706_logo.png
index fe9d775b..fe9d775b 100644
--- a/tests/input/res/drawable-xhdpi/ch_706_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_706_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_707_logo.png b/tests/common/res/drawable-xhdpi/ch_707_logo.png
index b3b0451c..b3b0451c 100644
--- a/tests/input/res/drawable-xhdpi/ch_707_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_707_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_708_logo.png b/tests/common/res/drawable-xhdpi/ch_708_logo.png
index 2a95b3a4..2a95b3a4 100644
--- a/tests/input/res/drawable-xhdpi/ch_708_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_708_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_709_logo.png b/tests/common/res/drawable-xhdpi/ch_709_logo.png
index 55111fbe..55111fbe 100644
--- a/tests/input/res/drawable-xhdpi/ch_709_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_709_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_70_logo.png b/tests/common/res/drawable-xhdpi/ch_70_logo.png
index 1860ec9c..1860ec9c 100644
--- a/tests/input/res/drawable-xhdpi/ch_70_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_70_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_710_logo.png b/tests/common/res/drawable-xhdpi/ch_710_logo.png
index 6284e6ee..6284e6ee 100644
--- a/tests/input/res/drawable-xhdpi/ch_710_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_710_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_711_logo.png b/tests/common/res/drawable-xhdpi/ch_711_logo.png
index d55d32ca..d55d32ca 100644
--- a/tests/input/res/drawable-xhdpi/ch_711_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_711_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_712_logo.png b/tests/common/res/drawable-xhdpi/ch_712_logo.png
index 7268941c..7268941c 100644
--- a/tests/input/res/drawable-xhdpi/ch_712_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_712_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_713_logo.png b/tests/common/res/drawable-xhdpi/ch_713_logo.png
index 781301e4..781301e4 100644
--- a/tests/input/res/drawable-xhdpi/ch_713_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_713_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_714_logo.png b/tests/common/res/drawable-xhdpi/ch_714_logo.png
index 8145eaac..8145eaac 100644
--- a/tests/input/res/drawable-xhdpi/ch_714_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_714_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_715_logo.png b/tests/common/res/drawable-xhdpi/ch_715_logo.png
index b7715dc5..b7715dc5 100644
--- a/tests/input/res/drawable-xhdpi/ch_715_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_715_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_716_logo.png b/tests/common/res/drawable-xhdpi/ch_716_logo.png
index 0c1f26e4..0c1f26e4 100644
--- a/tests/input/res/drawable-xhdpi/ch_716_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_716_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_717_logo.png b/tests/common/res/drawable-xhdpi/ch_717_logo.png
index de20828f..de20828f 100644
--- a/tests/input/res/drawable-xhdpi/ch_717_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_717_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_718_logo.png b/tests/common/res/drawable-xhdpi/ch_718_logo.png
index 8d915ecc..8d915ecc 100644
--- a/tests/input/res/drawable-xhdpi/ch_718_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_718_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_719_logo.png b/tests/common/res/drawable-xhdpi/ch_719_logo.png
index bd1c668d..bd1c668d 100644
--- a/tests/input/res/drawable-xhdpi/ch_719_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_719_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_71_logo.png b/tests/common/res/drawable-xhdpi/ch_71_logo.png
index e3f8b550..e3f8b550 100644
--- a/tests/input/res/drawable-xhdpi/ch_71_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_71_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_720_logo.png b/tests/common/res/drawable-xhdpi/ch_720_logo.png
index 66a60923..66a60923 100644
--- a/tests/input/res/drawable-xhdpi/ch_720_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_720_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_721_logo.png b/tests/common/res/drawable-xhdpi/ch_721_logo.png
index c877d396..c877d396 100644
--- a/tests/input/res/drawable-xhdpi/ch_721_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_721_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_722_logo.png b/tests/common/res/drawable-xhdpi/ch_722_logo.png
index 9fe37161..9fe37161 100644
--- a/tests/input/res/drawable-xhdpi/ch_722_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_722_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_723_logo.png b/tests/common/res/drawable-xhdpi/ch_723_logo.png
index 94563ccd..94563ccd 100644
--- a/tests/input/res/drawable-xhdpi/ch_723_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_723_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_724_logo.png b/tests/common/res/drawable-xhdpi/ch_724_logo.png
index 52e5fcd9..52e5fcd9 100644
--- a/tests/input/res/drawable-xhdpi/ch_724_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_724_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_725_logo.png b/tests/common/res/drawable-xhdpi/ch_725_logo.png
index 518fefaa..518fefaa 100644
--- a/tests/input/res/drawable-xhdpi/ch_725_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_725_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_726_logo.png b/tests/common/res/drawable-xhdpi/ch_726_logo.png
index 1f28222e..1f28222e 100644
--- a/tests/input/res/drawable-xhdpi/ch_726_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_726_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_727_logo.png b/tests/common/res/drawable-xhdpi/ch_727_logo.png
index bffbc57f..bffbc57f 100644
--- a/tests/input/res/drawable-xhdpi/ch_727_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_727_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_728_logo.png b/tests/common/res/drawable-xhdpi/ch_728_logo.png
index f036778b..f036778b 100644
--- a/tests/input/res/drawable-xhdpi/ch_728_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_728_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_729_logo.png b/tests/common/res/drawable-xhdpi/ch_729_logo.png
index a2838d56..a2838d56 100644
--- a/tests/input/res/drawable-xhdpi/ch_729_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_729_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_72_logo.png b/tests/common/res/drawable-xhdpi/ch_72_logo.png
index 5b2f971c..5b2f971c 100644
--- a/tests/input/res/drawable-xhdpi/ch_72_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_72_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_730_logo.png b/tests/common/res/drawable-xhdpi/ch_730_logo.png
index 443d08b8..443d08b8 100644
--- a/tests/input/res/drawable-xhdpi/ch_730_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_730_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_731_logo.png b/tests/common/res/drawable-xhdpi/ch_731_logo.png
index d07e52a1..d07e52a1 100644
--- a/tests/input/res/drawable-xhdpi/ch_731_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_731_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_732_logo.png b/tests/common/res/drawable-xhdpi/ch_732_logo.png
index 56f51b3f..56f51b3f 100644
--- a/tests/input/res/drawable-xhdpi/ch_732_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_732_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_733_logo.png b/tests/common/res/drawable-xhdpi/ch_733_logo.png
index 18248b0a..18248b0a 100644
--- a/tests/input/res/drawable-xhdpi/ch_733_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_733_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_734_logo.png b/tests/common/res/drawable-xhdpi/ch_734_logo.png
index fb740e33..fb740e33 100644
--- a/tests/input/res/drawable-xhdpi/ch_734_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_734_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_735_logo.png b/tests/common/res/drawable-xhdpi/ch_735_logo.png
index 9f83309f..9f83309f 100644
--- a/tests/input/res/drawable-xhdpi/ch_735_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_735_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_736_logo.png b/tests/common/res/drawable-xhdpi/ch_736_logo.png
index 768fc5ef..768fc5ef 100644
--- a/tests/input/res/drawable-xhdpi/ch_736_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_736_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_737_logo.png b/tests/common/res/drawable-xhdpi/ch_737_logo.png
index 6af65c67..6af65c67 100644
--- a/tests/input/res/drawable-xhdpi/ch_737_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_737_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_738_logo.png b/tests/common/res/drawable-xhdpi/ch_738_logo.png
index 3b908312..3b908312 100644
--- a/tests/input/res/drawable-xhdpi/ch_738_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_738_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_739_logo.png b/tests/common/res/drawable-xhdpi/ch_739_logo.png
index fea61e37..fea61e37 100644
--- a/tests/input/res/drawable-xhdpi/ch_739_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_739_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_73_logo.png b/tests/common/res/drawable-xhdpi/ch_73_logo.png
index 13556e6d..13556e6d 100644
--- a/tests/input/res/drawable-xhdpi/ch_73_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_73_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_740_logo.png b/tests/common/res/drawable-xhdpi/ch_740_logo.png
index 7fe9aa19..7fe9aa19 100644
--- a/tests/input/res/drawable-xhdpi/ch_740_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_740_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_741_logo.png b/tests/common/res/drawable-xhdpi/ch_741_logo.png
index a437fd22..a437fd22 100644
--- a/tests/input/res/drawable-xhdpi/ch_741_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_741_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_742_logo.png b/tests/common/res/drawable-xhdpi/ch_742_logo.png
index 5674dccb..5674dccb 100644
--- a/tests/input/res/drawable-xhdpi/ch_742_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_742_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_743_logo.png b/tests/common/res/drawable-xhdpi/ch_743_logo.png
index dbfcaa51..dbfcaa51 100644
--- a/tests/input/res/drawable-xhdpi/ch_743_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_743_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_744_logo.png b/tests/common/res/drawable-xhdpi/ch_744_logo.png
index fe6dd633..fe6dd633 100644
--- a/tests/input/res/drawable-xhdpi/ch_744_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_744_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_745_logo.png b/tests/common/res/drawable-xhdpi/ch_745_logo.png
index 703bc014..703bc014 100644
--- a/tests/input/res/drawable-xhdpi/ch_745_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_745_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_746_logo.png b/tests/common/res/drawable-xhdpi/ch_746_logo.png
index 15775a4c..15775a4c 100644
--- a/tests/input/res/drawable-xhdpi/ch_746_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_746_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_747_logo.png b/tests/common/res/drawable-xhdpi/ch_747_logo.png
index d5666758..d5666758 100644
--- a/tests/input/res/drawable-xhdpi/ch_747_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_747_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_748_logo.png b/tests/common/res/drawable-xhdpi/ch_748_logo.png
index 3bb80444..3bb80444 100644
--- a/tests/input/res/drawable-xhdpi/ch_748_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_748_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_749_logo.png b/tests/common/res/drawable-xhdpi/ch_749_logo.png
index 92a6954a..92a6954a 100644
--- a/tests/input/res/drawable-xhdpi/ch_749_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_749_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_74_logo.png b/tests/common/res/drawable-xhdpi/ch_74_logo.png
index 484f4c0d..484f4c0d 100644
--- a/tests/input/res/drawable-xhdpi/ch_74_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_74_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_750_logo.png b/tests/common/res/drawable-xhdpi/ch_750_logo.png
index 96af0fa6..96af0fa6 100644
--- a/tests/input/res/drawable-xhdpi/ch_750_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_750_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_751_logo.png b/tests/common/res/drawable-xhdpi/ch_751_logo.png
index bddc6d97..bddc6d97 100644
--- a/tests/input/res/drawable-xhdpi/ch_751_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_751_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_752_logo.png b/tests/common/res/drawable-xhdpi/ch_752_logo.png
index 38d693f7..38d693f7 100644
--- a/tests/input/res/drawable-xhdpi/ch_752_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_752_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_753_logo.png b/tests/common/res/drawable-xhdpi/ch_753_logo.png
index 3c383de7..3c383de7 100644
--- a/tests/input/res/drawable-xhdpi/ch_753_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_753_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_754_logo.png b/tests/common/res/drawable-xhdpi/ch_754_logo.png
index 04d7b62b..04d7b62b 100644
--- a/tests/input/res/drawable-xhdpi/ch_754_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_754_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_755_logo.png b/tests/common/res/drawable-xhdpi/ch_755_logo.png
index d7846b43..d7846b43 100644
--- a/tests/input/res/drawable-xhdpi/ch_755_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_755_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_756_logo.png b/tests/common/res/drawable-xhdpi/ch_756_logo.png
index 6b51e7d1..6b51e7d1 100644
--- a/tests/input/res/drawable-xhdpi/ch_756_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_756_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_757_logo.png b/tests/common/res/drawable-xhdpi/ch_757_logo.png
index b396d7c3..b396d7c3 100644
--- a/tests/input/res/drawable-xhdpi/ch_757_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_757_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_758_logo.png b/tests/common/res/drawable-xhdpi/ch_758_logo.png
index d77783b7..d77783b7 100644
--- a/tests/input/res/drawable-xhdpi/ch_758_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_758_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_759_logo.png b/tests/common/res/drawable-xhdpi/ch_759_logo.png
index ca26792b..ca26792b 100644
--- a/tests/input/res/drawable-xhdpi/ch_759_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_759_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_75_logo.png b/tests/common/res/drawable-xhdpi/ch_75_logo.png
index aa78479e..aa78479e 100644
--- a/tests/input/res/drawable-xhdpi/ch_75_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_75_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_760_logo.png b/tests/common/res/drawable-xhdpi/ch_760_logo.png
index 5d56db66..5d56db66 100644
--- a/tests/input/res/drawable-xhdpi/ch_760_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_760_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_761_logo.png b/tests/common/res/drawable-xhdpi/ch_761_logo.png
index e505365d..e505365d 100644
--- a/tests/input/res/drawable-xhdpi/ch_761_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_761_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_762_logo.png b/tests/common/res/drawable-xhdpi/ch_762_logo.png
index 202b7572..202b7572 100644
--- a/tests/input/res/drawable-xhdpi/ch_762_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_762_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_763_logo.png b/tests/common/res/drawable-xhdpi/ch_763_logo.png
index 14af6ab4..14af6ab4 100644
--- a/tests/input/res/drawable-xhdpi/ch_763_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_763_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_764_logo.png b/tests/common/res/drawable-xhdpi/ch_764_logo.png
index c4e1ea66..c4e1ea66 100644
--- a/tests/input/res/drawable-xhdpi/ch_764_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_764_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_765_logo.png b/tests/common/res/drawable-xhdpi/ch_765_logo.png
index 3b5ded8e..3b5ded8e 100644
--- a/tests/input/res/drawable-xhdpi/ch_765_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_765_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_766_logo.png b/tests/common/res/drawable-xhdpi/ch_766_logo.png
index 61391524..61391524 100644
--- a/tests/input/res/drawable-xhdpi/ch_766_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_766_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_767_logo.png b/tests/common/res/drawable-xhdpi/ch_767_logo.png
index 4fa0441e..4fa0441e 100644
--- a/tests/input/res/drawable-xhdpi/ch_767_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_767_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_768_logo.png b/tests/common/res/drawable-xhdpi/ch_768_logo.png
index 80e8293b..80e8293b 100644
--- a/tests/input/res/drawable-xhdpi/ch_768_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_768_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_769_logo.png b/tests/common/res/drawable-xhdpi/ch_769_logo.png
index 63c2e6cc..63c2e6cc 100644
--- a/tests/input/res/drawable-xhdpi/ch_769_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_769_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_76_logo.png b/tests/common/res/drawable-xhdpi/ch_76_logo.png
index 3ebf6807..3ebf6807 100644
--- a/tests/input/res/drawable-xhdpi/ch_76_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_76_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_770_logo.png b/tests/common/res/drawable-xhdpi/ch_770_logo.png
index b2ee3584..b2ee3584 100644
--- a/tests/input/res/drawable-xhdpi/ch_770_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_770_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_771_logo.png b/tests/common/res/drawable-xhdpi/ch_771_logo.png
index 9a53a498..9a53a498 100644
--- a/tests/input/res/drawable-xhdpi/ch_771_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_771_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_772_logo.png b/tests/common/res/drawable-xhdpi/ch_772_logo.png
index 1da9e70d..1da9e70d 100644
--- a/tests/input/res/drawable-xhdpi/ch_772_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_772_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_773_logo.png b/tests/common/res/drawable-xhdpi/ch_773_logo.png
index 0f35e46a..0f35e46a 100644
--- a/tests/input/res/drawable-xhdpi/ch_773_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_773_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_774_logo.png b/tests/common/res/drawable-xhdpi/ch_774_logo.png
index acaa8857..acaa8857 100644
--- a/tests/input/res/drawable-xhdpi/ch_774_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_774_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_775_logo.png b/tests/common/res/drawable-xhdpi/ch_775_logo.png
index 70ca99e8..70ca99e8 100644
--- a/tests/input/res/drawable-xhdpi/ch_775_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_775_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_776_logo.png b/tests/common/res/drawable-xhdpi/ch_776_logo.png
index ab54947d..ab54947d 100644
--- a/tests/input/res/drawable-xhdpi/ch_776_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_776_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_777_logo.png b/tests/common/res/drawable-xhdpi/ch_777_logo.png
index ed378329..ed378329 100644
--- a/tests/input/res/drawable-xhdpi/ch_777_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_777_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_778_logo.png b/tests/common/res/drawable-xhdpi/ch_778_logo.png
index 01cdc4e8..01cdc4e8 100644
--- a/tests/input/res/drawable-xhdpi/ch_778_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_778_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_779_logo.png b/tests/common/res/drawable-xhdpi/ch_779_logo.png
index ca5175f7..ca5175f7 100644
--- a/tests/input/res/drawable-xhdpi/ch_779_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_779_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_77_logo.png b/tests/common/res/drawable-xhdpi/ch_77_logo.png
index c22abf24..c22abf24 100644
--- a/tests/input/res/drawable-xhdpi/ch_77_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_77_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_780_logo.png b/tests/common/res/drawable-xhdpi/ch_780_logo.png
index 2e5f24e2..2e5f24e2 100644
--- a/tests/input/res/drawable-xhdpi/ch_780_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_780_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_781_logo.png b/tests/common/res/drawable-xhdpi/ch_781_logo.png
index 81e5ed66..81e5ed66 100644
--- a/tests/input/res/drawable-xhdpi/ch_781_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_781_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_782_logo.png b/tests/common/res/drawable-xhdpi/ch_782_logo.png
index 3236afa9..3236afa9 100644
--- a/tests/input/res/drawable-xhdpi/ch_782_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_782_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_783_logo.png b/tests/common/res/drawable-xhdpi/ch_783_logo.png
index a600800e..a600800e 100644
--- a/tests/input/res/drawable-xhdpi/ch_783_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_783_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_784_logo.png b/tests/common/res/drawable-xhdpi/ch_784_logo.png
index cd97c5eb..cd97c5eb 100644
--- a/tests/input/res/drawable-xhdpi/ch_784_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_784_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_785_logo.png b/tests/common/res/drawable-xhdpi/ch_785_logo.png
index d50fd82a..d50fd82a 100644
--- a/tests/input/res/drawable-xhdpi/ch_785_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_785_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_786_logo.png b/tests/common/res/drawable-xhdpi/ch_786_logo.png
index 7a93ef71..7a93ef71 100644
--- a/tests/input/res/drawable-xhdpi/ch_786_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_786_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_787_logo.png b/tests/common/res/drawable-xhdpi/ch_787_logo.png
index 62b5cf6b..62b5cf6b 100644
--- a/tests/input/res/drawable-xhdpi/ch_787_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_787_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_788_logo.png b/tests/common/res/drawable-xhdpi/ch_788_logo.png
index c82602d3..c82602d3 100644
--- a/tests/input/res/drawable-xhdpi/ch_788_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_788_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_789_logo.png b/tests/common/res/drawable-xhdpi/ch_789_logo.png
index 7dfbeeb3..7dfbeeb3 100644
--- a/tests/input/res/drawable-xhdpi/ch_789_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_789_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_78_logo.png b/tests/common/res/drawable-xhdpi/ch_78_logo.png
index 03fb415f..03fb415f 100644
--- a/tests/input/res/drawable-xhdpi/ch_78_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_78_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_790_logo.png b/tests/common/res/drawable-xhdpi/ch_790_logo.png
index d44c2181..d44c2181 100644
--- a/tests/input/res/drawable-xhdpi/ch_790_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_790_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_791_logo.png b/tests/common/res/drawable-xhdpi/ch_791_logo.png
index ee81b961..ee81b961 100644
--- a/tests/input/res/drawable-xhdpi/ch_791_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_791_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_792_logo.png b/tests/common/res/drawable-xhdpi/ch_792_logo.png
index 37715025..37715025 100644
--- a/tests/input/res/drawable-xhdpi/ch_792_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_792_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_793_logo.png b/tests/common/res/drawable-xhdpi/ch_793_logo.png
index eca3a477..eca3a477 100644
--- a/tests/input/res/drawable-xhdpi/ch_793_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_793_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_794_logo.png b/tests/common/res/drawable-xhdpi/ch_794_logo.png
index fbbfc372..fbbfc372 100644
--- a/tests/input/res/drawable-xhdpi/ch_794_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_794_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_795_logo.png b/tests/common/res/drawable-xhdpi/ch_795_logo.png
index 0366a2bd..0366a2bd 100644
--- a/tests/input/res/drawable-xhdpi/ch_795_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_795_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_796_logo.png b/tests/common/res/drawable-xhdpi/ch_796_logo.png
index e13e6bc1..e13e6bc1 100644
--- a/tests/input/res/drawable-xhdpi/ch_796_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_796_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_797_logo.png b/tests/common/res/drawable-xhdpi/ch_797_logo.png
index e45decc0..e45decc0 100644
--- a/tests/input/res/drawable-xhdpi/ch_797_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_797_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_798_logo.png b/tests/common/res/drawable-xhdpi/ch_798_logo.png
index 6b9659e2..6b9659e2 100644
--- a/tests/input/res/drawable-xhdpi/ch_798_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_798_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_799_logo.png b/tests/common/res/drawable-xhdpi/ch_799_logo.png
index e8cb2ef8..e8cb2ef8 100644
--- a/tests/input/res/drawable-xhdpi/ch_799_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_799_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_79_logo.png b/tests/common/res/drawable-xhdpi/ch_79_logo.png
index 237fa7b2..237fa7b2 100644
--- a/tests/input/res/drawable-xhdpi/ch_79_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_79_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_7_logo.png b/tests/common/res/drawable-xhdpi/ch_7_logo.png
index df78066a..df78066a 100644
--- a/tests/input/res/drawable-xhdpi/ch_7_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_7_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_800_logo.png b/tests/common/res/drawable-xhdpi/ch_800_logo.png
index 6c775941..6c775941 100644
--- a/tests/input/res/drawable-xhdpi/ch_800_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_800_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_801_logo.png b/tests/common/res/drawable-xhdpi/ch_801_logo.png
index f0006515..f0006515 100644
--- a/tests/input/res/drawable-xhdpi/ch_801_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_801_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_802_logo.png b/tests/common/res/drawable-xhdpi/ch_802_logo.png
index 4c504b58..4c504b58 100644
--- a/tests/input/res/drawable-xhdpi/ch_802_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_802_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_803_logo.png b/tests/common/res/drawable-xhdpi/ch_803_logo.png
index edfa6869..edfa6869 100644
--- a/tests/input/res/drawable-xhdpi/ch_803_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_803_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_804_logo.png b/tests/common/res/drawable-xhdpi/ch_804_logo.png
index c7b0dba0..c7b0dba0 100644
--- a/tests/input/res/drawable-xhdpi/ch_804_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_804_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_805_logo.png b/tests/common/res/drawable-xhdpi/ch_805_logo.png
index bcd6ee28..bcd6ee28 100644
--- a/tests/input/res/drawable-xhdpi/ch_805_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_805_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_806_logo.png b/tests/common/res/drawable-xhdpi/ch_806_logo.png
index e926e9f4..e926e9f4 100644
--- a/tests/input/res/drawable-xhdpi/ch_806_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_806_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_807_logo.png b/tests/common/res/drawable-xhdpi/ch_807_logo.png
index 25334551..25334551 100644
--- a/tests/input/res/drawable-xhdpi/ch_807_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_807_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_808_logo.png b/tests/common/res/drawable-xhdpi/ch_808_logo.png
index 5d7b51a9..5d7b51a9 100644
--- a/tests/input/res/drawable-xhdpi/ch_808_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_808_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_809_logo.png b/tests/common/res/drawable-xhdpi/ch_809_logo.png
index 2f6a8e31..2f6a8e31 100644
--- a/tests/input/res/drawable-xhdpi/ch_809_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_809_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_80_logo.png b/tests/common/res/drawable-xhdpi/ch_80_logo.png
index ff7a55c1..ff7a55c1 100644
--- a/tests/input/res/drawable-xhdpi/ch_80_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_80_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_810_logo.png b/tests/common/res/drawable-xhdpi/ch_810_logo.png
index 1a083992..1a083992 100644
--- a/tests/input/res/drawable-xhdpi/ch_810_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_810_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_811_logo.png b/tests/common/res/drawable-xhdpi/ch_811_logo.png
index 070df630..070df630 100644
--- a/tests/input/res/drawable-xhdpi/ch_811_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_811_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_812_logo.png b/tests/common/res/drawable-xhdpi/ch_812_logo.png
index 376e68cb..376e68cb 100644
--- a/tests/input/res/drawable-xhdpi/ch_812_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_812_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_813_logo.png b/tests/common/res/drawable-xhdpi/ch_813_logo.png
index d72f0a8e..d72f0a8e 100644
--- a/tests/input/res/drawable-xhdpi/ch_813_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_813_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_814_logo.png b/tests/common/res/drawable-xhdpi/ch_814_logo.png
index b50d9ad1..b50d9ad1 100644
--- a/tests/input/res/drawable-xhdpi/ch_814_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_814_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_815_logo.png b/tests/common/res/drawable-xhdpi/ch_815_logo.png
index fdbc4cdd..fdbc4cdd 100644
--- a/tests/input/res/drawable-xhdpi/ch_815_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_815_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_816_logo.png b/tests/common/res/drawable-xhdpi/ch_816_logo.png
index f1212200..f1212200 100644
--- a/tests/input/res/drawable-xhdpi/ch_816_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_816_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_817_logo.png b/tests/common/res/drawable-xhdpi/ch_817_logo.png
index be4fa008..be4fa008 100644
--- a/tests/input/res/drawable-xhdpi/ch_817_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_817_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_818_logo.png b/tests/common/res/drawable-xhdpi/ch_818_logo.png
index c9d087d7..c9d087d7 100644
--- a/tests/input/res/drawable-xhdpi/ch_818_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_818_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_819_logo.png b/tests/common/res/drawable-xhdpi/ch_819_logo.png
index b8cab83d..b8cab83d 100644
--- a/tests/input/res/drawable-xhdpi/ch_819_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_819_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_81_logo.png b/tests/common/res/drawable-xhdpi/ch_81_logo.png
index 58f6fc00..58f6fc00 100644
--- a/tests/input/res/drawable-xhdpi/ch_81_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_81_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_820_logo.png b/tests/common/res/drawable-xhdpi/ch_820_logo.png
index 3bf591fb..3bf591fb 100644
--- a/tests/input/res/drawable-xhdpi/ch_820_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_820_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_821_logo.png b/tests/common/res/drawable-xhdpi/ch_821_logo.png
index 16046f46..16046f46 100644
--- a/tests/input/res/drawable-xhdpi/ch_821_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_821_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_822_logo.png b/tests/common/res/drawable-xhdpi/ch_822_logo.png
index 58d688c9..58d688c9 100644
--- a/tests/input/res/drawable-xhdpi/ch_822_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_822_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_823_logo.png b/tests/common/res/drawable-xhdpi/ch_823_logo.png
index 6b70ecc1..6b70ecc1 100644
--- a/tests/input/res/drawable-xhdpi/ch_823_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_823_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_824_logo.png b/tests/common/res/drawable-xhdpi/ch_824_logo.png
index 4c90c96e..4c90c96e 100644
--- a/tests/input/res/drawable-xhdpi/ch_824_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_824_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_825_logo.png b/tests/common/res/drawable-xhdpi/ch_825_logo.png
index 5111136c..5111136c 100644
--- a/tests/input/res/drawable-xhdpi/ch_825_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_825_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_826_logo.png b/tests/common/res/drawable-xhdpi/ch_826_logo.png
index f35941e8..f35941e8 100644
--- a/tests/input/res/drawable-xhdpi/ch_826_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_826_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_827_logo.png b/tests/common/res/drawable-xhdpi/ch_827_logo.png
index 49add1ab..49add1ab 100644
--- a/tests/input/res/drawable-xhdpi/ch_827_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_827_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_828_logo.png b/tests/common/res/drawable-xhdpi/ch_828_logo.png
index 67936aa4..67936aa4 100644
--- a/tests/input/res/drawable-xhdpi/ch_828_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_828_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_829_logo.png b/tests/common/res/drawable-xhdpi/ch_829_logo.png
index 7bc97945..7bc97945 100644
--- a/tests/input/res/drawable-xhdpi/ch_829_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_829_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_82_logo.png b/tests/common/res/drawable-xhdpi/ch_82_logo.png
index ddd21127..ddd21127 100644
--- a/tests/input/res/drawable-xhdpi/ch_82_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_82_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_830_logo.png b/tests/common/res/drawable-xhdpi/ch_830_logo.png
index 3aa669d8..3aa669d8 100644
--- a/tests/input/res/drawable-xhdpi/ch_830_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_830_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_831_logo.png b/tests/common/res/drawable-xhdpi/ch_831_logo.png
index f7c2cf1c..f7c2cf1c 100644
--- a/tests/input/res/drawable-xhdpi/ch_831_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_831_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_832_logo.png b/tests/common/res/drawable-xhdpi/ch_832_logo.png
index 19096734..19096734 100644
--- a/tests/input/res/drawable-xhdpi/ch_832_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_832_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_833_logo.png b/tests/common/res/drawable-xhdpi/ch_833_logo.png
index d0a1af2f..d0a1af2f 100644
--- a/tests/input/res/drawable-xhdpi/ch_833_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_833_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_834_logo.png b/tests/common/res/drawable-xhdpi/ch_834_logo.png
index 52e2ef58..52e2ef58 100644
--- a/tests/input/res/drawable-xhdpi/ch_834_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_834_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_835_logo.png b/tests/common/res/drawable-xhdpi/ch_835_logo.png
index 7ac421e1..7ac421e1 100644
--- a/tests/input/res/drawable-xhdpi/ch_835_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_835_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_836_logo.png b/tests/common/res/drawable-xhdpi/ch_836_logo.png
index 7f4577b4..7f4577b4 100644
--- a/tests/input/res/drawable-xhdpi/ch_836_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_836_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_837_logo.png b/tests/common/res/drawable-xhdpi/ch_837_logo.png
index df5e1c86..df5e1c86 100644
--- a/tests/input/res/drawable-xhdpi/ch_837_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_837_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_838_logo.png b/tests/common/res/drawable-xhdpi/ch_838_logo.png
index 579557ed..579557ed 100644
--- a/tests/input/res/drawable-xhdpi/ch_838_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_838_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_839_logo.png b/tests/common/res/drawable-xhdpi/ch_839_logo.png
index 3988cc5b..3988cc5b 100644
--- a/tests/input/res/drawable-xhdpi/ch_839_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_839_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_83_logo.png b/tests/common/res/drawable-xhdpi/ch_83_logo.png
index dd97e15c..dd97e15c 100644
--- a/tests/input/res/drawable-xhdpi/ch_83_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_83_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_840_logo.png b/tests/common/res/drawable-xhdpi/ch_840_logo.png
index 29e88d2a..29e88d2a 100644
--- a/tests/input/res/drawable-xhdpi/ch_840_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_840_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_841_logo.png b/tests/common/res/drawable-xhdpi/ch_841_logo.png
index 9ee069a4..9ee069a4 100644
--- a/tests/input/res/drawable-xhdpi/ch_841_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_841_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_842_logo.png b/tests/common/res/drawable-xhdpi/ch_842_logo.png
index edbd8c57..edbd8c57 100644
--- a/tests/input/res/drawable-xhdpi/ch_842_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_842_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_843_logo.png b/tests/common/res/drawable-xhdpi/ch_843_logo.png
index 7ee70de2..7ee70de2 100644
--- a/tests/input/res/drawable-xhdpi/ch_843_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_843_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_844_logo.png b/tests/common/res/drawable-xhdpi/ch_844_logo.png
index 6a0a95a8..6a0a95a8 100644
--- a/tests/input/res/drawable-xhdpi/ch_844_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_844_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_845_logo.png b/tests/common/res/drawable-xhdpi/ch_845_logo.png
index ae4aa7eb..ae4aa7eb 100644
--- a/tests/input/res/drawable-xhdpi/ch_845_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_845_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_846_logo.png b/tests/common/res/drawable-xhdpi/ch_846_logo.png
index 79eb61d9..79eb61d9 100644
--- a/tests/input/res/drawable-xhdpi/ch_846_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_846_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_847_logo.png b/tests/common/res/drawable-xhdpi/ch_847_logo.png
index 2a8fd743..2a8fd743 100644
--- a/tests/input/res/drawable-xhdpi/ch_847_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_847_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_848_logo.png b/tests/common/res/drawable-xhdpi/ch_848_logo.png
index c2e82237..c2e82237 100644
--- a/tests/input/res/drawable-xhdpi/ch_848_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_848_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_849_logo.png b/tests/common/res/drawable-xhdpi/ch_849_logo.png
index 44d58b8d..44d58b8d 100644
--- a/tests/input/res/drawable-xhdpi/ch_849_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_849_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_84_logo.png b/tests/common/res/drawable-xhdpi/ch_84_logo.png
index 5ad6a473..5ad6a473 100644
--- a/tests/input/res/drawable-xhdpi/ch_84_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_84_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_850_logo.png b/tests/common/res/drawable-xhdpi/ch_850_logo.png
index 358dc326..358dc326 100644
--- a/tests/input/res/drawable-xhdpi/ch_850_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_850_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_851_logo.png b/tests/common/res/drawable-xhdpi/ch_851_logo.png
index 7c5ef9cd..7c5ef9cd 100644
--- a/tests/input/res/drawable-xhdpi/ch_851_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_851_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_852_logo.png b/tests/common/res/drawable-xhdpi/ch_852_logo.png
index 0ab1e98b..0ab1e98b 100644
--- a/tests/input/res/drawable-xhdpi/ch_852_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_852_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_853_logo.png b/tests/common/res/drawable-xhdpi/ch_853_logo.png
index c5b6a11b..c5b6a11b 100644
--- a/tests/input/res/drawable-xhdpi/ch_853_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_853_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_854_logo.png b/tests/common/res/drawable-xhdpi/ch_854_logo.png
index 5c34d4e2..5c34d4e2 100644
--- a/tests/input/res/drawable-xhdpi/ch_854_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_854_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_855_logo.png b/tests/common/res/drawable-xhdpi/ch_855_logo.png
index b8f10da8..b8f10da8 100644
--- a/tests/input/res/drawable-xhdpi/ch_855_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_855_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_856_logo.png b/tests/common/res/drawable-xhdpi/ch_856_logo.png
index 1b790da7..1b790da7 100644
--- a/tests/input/res/drawable-xhdpi/ch_856_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_856_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_857_logo.png b/tests/common/res/drawable-xhdpi/ch_857_logo.png
index a7f3b55d..a7f3b55d 100644
--- a/tests/input/res/drawable-xhdpi/ch_857_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_857_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_858_logo.png b/tests/common/res/drawable-xhdpi/ch_858_logo.png
index e3555be6..e3555be6 100644
--- a/tests/input/res/drawable-xhdpi/ch_858_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_858_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_859_logo.png b/tests/common/res/drawable-xhdpi/ch_859_logo.png
index 970ee63e..970ee63e 100644
--- a/tests/input/res/drawable-xhdpi/ch_859_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_859_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_85_logo.png b/tests/common/res/drawable-xhdpi/ch_85_logo.png
index 35c5c992..35c5c992 100644
--- a/tests/input/res/drawable-xhdpi/ch_85_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_85_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_860_logo.png b/tests/common/res/drawable-xhdpi/ch_860_logo.png
index 72720501..72720501 100644
--- a/tests/input/res/drawable-xhdpi/ch_860_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_860_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_861_logo.png b/tests/common/res/drawable-xhdpi/ch_861_logo.png
index bf6d0be9..bf6d0be9 100644
--- a/tests/input/res/drawable-xhdpi/ch_861_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_861_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_862_logo.png b/tests/common/res/drawable-xhdpi/ch_862_logo.png
index ee6c88f2..ee6c88f2 100644
--- a/tests/input/res/drawable-xhdpi/ch_862_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_862_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_863_logo.png b/tests/common/res/drawable-xhdpi/ch_863_logo.png
index 9b92ef30..9b92ef30 100644
--- a/tests/input/res/drawable-xhdpi/ch_863_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_863_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_864_logo.png b/tests/common/res/drawable-xhdpi/ch_864_logo.png
index 2024e828..2024e828 100644
--- a/tests/input/res/drawable-xhdpi/ch_864_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_864_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_865_logo.png b/tests/common/res/drawable-xhdpi/ch_865_logo.png
index 80b87668..80b87668 100644
--- a/tests/input/res/drawable-xhdpi/ch_865_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_865_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_866_logo.png b/tests/common/res/drawable-xhdpi/ch_866_logo.png
index 6dfe8538..6dfe8538 100644
--- a/tests/input/res/drawable-xhdpi/ch_866_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_866_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_867_logo.png b/tests/common/res/drawable-xhdpi/ch_867_logo.png
index 6cb51f22..6cb51f22 100644
--- a/tests/input/res/drawable-xhdpi/ch_867_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_867_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_868_logo.png b/tests/common/res/drawable-xhdpi/ch_868_logo.png
index e179e5cf..e179e5cf 100644
--- a/tests/input/res/drawable-xhdpi/ch_868_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_868_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_869_logo.png b/tests/common/res/drawable-xhdpi/ch_869_logo.png
index 940780eb..940780eb 100644
--- a/tests/input/res/drawable-xhdpi/ch_869_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_869_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_86_logo.png b/tests/common/res/drawable-xhdpi/ch_86_logo.png
index 93bbad73..93bbad73 100644
--- a/tests/input/res/drawable-xhdpi/ch_86_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_86_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_870_logo.png b/tests/common/res/drawable-xhdpi/ch_870_logo.png
index caa05fe8..caa05fe8 100644
--- a/tests/input/res/drawable-xhdpi/ch_870_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_870_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_871_logo.png b/tests/common/res/drawable-xhdpi/ch_871_logo.png
index 9085b8a8..9085b8a8 100644
--- a/tests/input/res/drawable-xhdpi/ch_871_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_871_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_872_logo.png b/tests/common/res/drawable-xhdpi/ch_872_logo.png
index 695dabaf..695dabaf 100644
--- a/tests/input/res/drawable-xhdpi/ch_872_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_872_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_873_logo.png b/tests/common/res/drawable-xhdpi/ch_873_logo.png
index 21871509..21871509 100644
--- a/tests/input/res/drawable-xhdpi/ch_873_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_873_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_874_logo.png b/tests/common/res/drawable-xhdpi/ch_874_logo.png
index 2bbcf9cc..2bbcf9cc 100644
--- a/tests/input/res/drawable-xhdpi/ch_874_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_874_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_875_logo.png b/tests/common/res/drawable-xhdpi/ch_875_logo.png
index 494b8ebc..494b8ebc 100644
--- a/tests/input/res/drawable-xhdpi/ch_875_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_875_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_876_logo.png b/tests/common/res/drawable-xhdpi/ch_876_logo.png
index eded05e4..eded05e4 100644
--- a/tests/input/res/drawable-xhdpi/ch_876_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_876_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_877_logo.png b/tests/common/res/drawable-xhdpi/ch_877_logo.png
index cf22732d..cf22732d 100644
--- a/tests/input/res/drawable-xhdpi/ch_877_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_877_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_878_logo.png b/tests/common/res/drawable-xhdpi/ch_878_logo.png
index 3ca881cf..3ca881cf 100644
--- a/tests/input/res/drawable-xhdpi/ch_878_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_878_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_879_logo.png b/tests/common/res/drawable-xhdpi/ch_879_logo.png
index 8f629b25..8f629b25 100644
--- a/tests/input/res/drawable-xhdpi/ch_879_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_879_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_87_logo.png b/tests/common/res/drawable-xhdpi/ch_87_logo.png
index 1a661da8..1a661da8 100644
--- a/tests/input/res/drawable-xhdpi/ch_87_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_87_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_880_logo.png b/tests/common/res/drawable-xhdpi/ch_880_logo.png
index f23459d8..f23459d8 100644
--- a/tests/input/res/drawable-xhdpi/ch_880_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_880_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_881_logo.png b/tests/common/res/drawable-xhdpi/ch_881_logo.png
index 810320be..810320be 100644
--- a/tests/input/res/drawable-xhdpi/ch_881_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_881_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_882_logo.png b/tests/common/res/drawable-xhdpi/ch_882_logo.png
index cee19fc9..cee19fc9 100644
--- a/tests/input/res/drawable-xhdpi/ch_882_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_882_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_883_logo.png b/tests/common/res/drawable-xhdpi/ch_883_logo.png
index b7cd2a11..b7cd2a11 100644
--- a/tests/input/res/drawable-xhdpi/ch_883_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_883_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_884_logo.png b/tests/common/res/drawable-xhdpi/ch_884_logo.png
index ee24315c..ee24315c 100644
--- a/tests/input/res/drawable-xhdpi/ch_884_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_884_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_885_logo.png b/tests/common/res/drawable-xhdpi/ch_885_logo.png
index aac4f31f..aac4f31f 100644
--- a/tests/input/res/drawable-xhdpi/ch_885_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_885_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_886_logo.png b/tests/common/res/drawable-xhdpi/ch_886_logo.png
index d929436e..d929436e 100644
--- a/tests/input/res/drawable-xhdpi/ch_886_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_886_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_887_logo.png b/tests/common/res/drawable-xhdpi/ch_887_logo.png
index 4d38b4c9..4d38b4c9 100644
--- a/tests/input/res/drawable-xhdpi/ch_887_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_887_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_888_logo.png b/tests/common/res/drawable-xhdpi/ch_888_logo.png
index b8bf4191..b8bf4191 100644
--- a/tests/input/res/drawable-xhdpi/ch_888_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_888_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_889_logo.png b/tests/common/res/drawable-xhdpi/ch_889_logo.png
index e38f60dd..e38f60dd 100644
--- a/tests/input/res/drawable-xhdpi/ch_889_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_889_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_88_logo.png b/tests/common/res/drawable-xhdpi/ch_88_logo.png
index 9cf19a3b..9cf19a3b 100644
--- a/tests/input/res/drawable-xhdpi/ch_88_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_88_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_890_logo.png b/tests/common/res/drawable-xhdpi/ch_890_logo.png
index 46e8755c..46e8755c 100644
--- a/tests/input/res/drawable-xhdpi/ch_890_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_890_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_891_logo.png b/tests/common/res/drawable-xhdpi/ch_891_logo.png
index 8fcae156..8fcae156 100644
--- a/tests/input/res/drawable-xhdpi/ch_891_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_891_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_892_logo.png b/tests/common/res/drawable-xhdpi/ch_892_logo.png
index 4672b7e1..4672b7e1 100644
--- a/tests/input/res/drawable-xhdpi/ch_892_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_892_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_893_logo.png b/tests/common/res/drawable-xhdpi/ch_893_logo.png
index 170586f5..170586f5 100644
--- a/tests/input/res/drawable-xhdpi/ch_893_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_893_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_894_logo.png b/tests/common/res/drawable-xhdpi/ch_894_logo.png
index 4b366898..4b366898 100644
--- a/tests/input/res/drawable-xhdpi/ch_894_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_894_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_895_logo.png b/tests/common/res/drawable-xhdpi/ch_895_logo.png
index 1855d24c..1855d24c 100644
--- a/tests/input/res/drawable-xhdpi/ch_895_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_895_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_896_logo.png b/tests/common/res/drawable-xhdpi/ch_896_logo.png
index dc47d447..dc47d447 100644
--- a/tests/input/res/drawable-xhdpi/ch_896_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_896_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_897_logo.png b/tests/common/res/drawable-xhdpi/ch_897_logo.png
index 909a60e0..909a60e0 100644
--- a/tests/input/res/drawable-xhdpi/ch_897_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_897_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_898_logo.png b/tests/common/res/drawable-xhdpi/ch_898_logo.png
index a57a6344..a57a6344 100644
--- a/tests/input/res/drawable-xhdpi/ch_898_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_898_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_899_logo.png b/tests/common/res/drawable-xhdpi/ch_899_logo.png
index fa99418a..fa99418a 100644
--- a/tests/input/res/drawable-xhdpi/ch_899_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_899_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_89_logo.png b/tests/common/res/drawable-xhdpi/ch_89_logo.png
index 0c7edc8c..0c7edc8c 100644
--- a/tests/input/res/drawable-xhdpi/ch_89_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_89_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_8_logo.png b/tests/common/res/drawable-xhdpi/ch_8_logo.png
index 0886b851..0886b851 100644
--- a/tests/input/res/drawable-xhdpi/ch_8_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_8_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_900_logo.png b/tests/common/res/drawable-xhdpi/ch_900_logo.png
index cf6327bb..cf6327bb 100644
--- a/tests/input/res/drawable-xhdpi/ch_900_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_900_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_901_logo.png b/tests/common/res/drawable-xhdpi/ch_901_logo.png
index 17e1c9ef..17e1c9ef 100644
--- a/tests/input/res/drawable-xhdpi/ch_901_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_901_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_902_logo.png b/tests/common/res/drawable-xhdpi/ch_902_logo.png
index f98b40cb..f98b40cb 100644
--- a/tests/input/res/drawable-xhdpi/ch_902_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_902_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_903_logo.png b/tests/common/res/drawable-xhdpi/ch_903_logo.png
index d3d331d8..d3d331d8 100644
--- a/tests/input/res/drawable-xhdpi/ch_903_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_903_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_904_logo.png b/tests/common/res/drawable-xhdpi/ch_904_logo.png
index d3e29be6..d3e29be6 100644
--- a/tests/input/res/drawable-xhdpi/ch_904_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_904_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_905_logo.png b/tests/common/res/drawable-xhdpi/ch_905_logo.png
index 65ab0adc..65ab0adc 100644
--- a/tests/input/res/drawable-xhdpi/ch_905_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_905_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_906_logo.png b/tests/common/res/drawable-xhdpi/ch_906_logo.png
index 1cc924d7..1cc924d7 100644
--- a/tests/input/res/drawable-xhdpi/ch_906_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_906_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_907_logo.png b/tests/common/res/drawable-xhdpi/ch_907_logo.png
index 9fd37e6e..9fd37e6e 100644
--- a/tests/input/res/drawable-xhdpi/ch_907_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_907_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_908_logo.png b/tests/common/res/drawable-xhdpi/ch_908_logo.png
index 15597dba..15597dba 100644
--- a/tests/input/res/drawable-xhdpi/ch_908_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_908_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_909_logo.png b/tests/common/res/drawable-xhdpi/ch_909_logo.png
index db80fbef..db80fbef 100644
--- a/tests/input/res/drawable-xhdpi/ch_909_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_909_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_90_logo.png b/tests/common/res/drawable-xhdpi/ch_90_logo.png
index 2f2960da..2f2960da 100644
--- a/tests/input/res/drawable-xhdpi/ch_90_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_90_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_910_logo.png b/tests/common/res/drawable-xhdpi/ch_910_logo.png
index dd6f8a31..dd6f8a31 100644
--- a/tests/input/res/drawable-xhdpi/ch_910_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_910_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_911_logo.png b/tests/common/res/drawable-xhdpi/ch_911_logo.png
index 23266b64..23266b64 100644
--- a/tests/input/res/drawable-xhdpi/ch_911_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_911_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_912_logo.png b/tests/common/res/drawable-xhdpi/ch_912_logo.png
index 677197d5..677197d5 100644
--- a/tests/input/res/drawable-xhdpi/ch_912_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_912_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_913_logo.png b/tests/common/res/drawable-xhdpi/ch_913_logo.png
index 41c4ae03..41c4ae03 100644
--- a/tests/input/res/drawable-xhdpi/ch_913_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_913_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_914_logo.png b/tests/common/res/drawable-xhdpi/ch_914_logo.png
index 2a2b4a2d..2a2b4a2d 100644
--- a/tests/input/res/drawable-xhdpi/ch_914_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_914_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_915_logo.png b/tests/common/res/drawable-xhdpi/ch_915_logo.png
index 85941edf..85941edf 100644
--- a/tests/input/res/drawable-xhdpi/ch_915_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_915_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_916_logo.png b/tests/common/res/drawable-xhdpi/ch_916_logo.png
index fbf4a41e..fbf4a41e 100644
--- a/tests/input/res/drawable-xhdpi/ch_916_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_916_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_917_logo.png b/tests/common/res/drawable-xhdpi/ch_917_logo.png
index 018dff5e..018dff5e 100644
--- a/tests/input/res/drawable-xhdpi/ch_917_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_917_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_918_logo.png b/tests/common/res/drawable-xhdpi/ch_918_logo.png
index 2c8b0b80..2c8b0b80 100644
--- a/tests/input/res/drawable-xhdpi/ch_918_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_918_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_919_logo.png b/tests/common/res/drawable-xhdpi/ch_919_logo.png
index de2e6073..de2e6073 100644
--- a/tests/input/res/drawable-xhdpi/ch_919_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_919_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_91_logo.png b/tests/common/res/drawable-xhdpi/ch_91_logo.png
index 3992165b..3992165b 100644
--- a/tests/input/res/drawable-xhdpi/ch_91_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_91_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_920_logo.png b/tests/common/res/drawable-xhdpi/ch_920_logo.png
index 33839469..33839469 100644
--- a/tests/input/res/drawable-xhdpi/ch_920_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_920_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_921_logo.png b/tests/common/res/drawable-xhdpi/ch_921_logo.png
index 019c36f5..019c36f5 100644
--- a/tests/input/res/drawable-xhdpi/ch_921_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_921_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_922_logo.png b/tests/common/res/drawable-xhdpi/ch_922_logo.png
index 79e4e07d..79e4e07d 100644
--- a/tests/input/res/drawable-xhdpi/ch_922_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_922_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_923_logo.png b/tests/common/res/drawable-xhdpi/ch_923_logo.png
index 6738d938..6738d938 100644
--- a/tests/input/res/drawable-xhdpi/ch_923_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_923_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_924_logo.png b/tests/common/res/drawable-xhdpi/ch_924_logo.png
index 3cbc4e30..3cbc4e30 100644
--- a/tests/input/res/drawable-xhdpi/ch_924_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_924_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_925_logo.png b/tests/common/res/drawable-xhdpi/ch_925_logo.png
index 500111c1..500111c1 100644
--- a/tests/input/res/drawable-xhdpi/ch_925_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_925_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_926_logo.png b/tests/common/res/drawable-xhdpi/ch_926_logo.png
index bd3f94ad..bd3f94ad 100644
--- a/tests/input/res/drawable-xhdpi/ch_926_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_926_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_927_logo.png b/tests/common/res/drawable-xhdpi/ch_927_logo.png
index 51ad2eaa..51ad2eaa 100644
--- a/tests/input/res/drawable-xhdpi/ch_927_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_927_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_928_logo.png b/tests/common/res/drawable-xhdpi/ch_928_logo.png
index 6f579bb3..6f579bb3 100644
--- a/tests/input/res/drawable-xhdpi/ch_928_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_928_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_929_logo.png b/tests/common/res/drawable-xhdpi/ch_929_logo.png
index 79f11bb1..79f11bb1 100644
--- a/tests/input/res/drawable-xhdpi/ch_929_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_929_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_92_logo.png b/tests/common/res/drawable-xhdpi/ch_92_logo.png
index 25508036..25508036 100644
--- a/tests/input/res/drawable-xhdpi/ch_92_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_92_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_930_logo.png b/tests/common/res/drawable-xhdpi/ch_930_logo.png
index 4c06ad09..4c06ad09 100644
--- a/tests/input/res/drawable-xhdpi/ch_930_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_930_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_931_logo.png b/tests/common/res/drawable-xhdpi/ch_931_logo.png
index b7ac61ff..b7ac61ff 100644
--- a/tests/input/res/drawable-xhdpi/ch_931_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_931_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_932_logo.png b/tests/common/res/drawable-xhdpi/ch_932_logo.png
index cac5a477..cac5a477 100644
--- a/tests/input/res/drawable-xhdpi/ch_932_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_932_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_933_logo.png b/tests/common/res/drawable-xhdpi/ch_933_logo.png
index 959f957f..959f957f 100644
--- a/tests/input/res/drawable-xhdpi/ch_933_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_933_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_934_logo.png b/tests/common/res/drawable-xhdpi/ch_934_logo.png
index e9e5b263..e9e5b263 100644
--- a/tests/input/res/drawable-xhdpi/ch_934_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_934_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_935_logo.png b/tests/common/res/drawable-xhdpi/ch_935_logo.png
index 9741307e..9741307e 100644
--- a/tests/input/res/drawable-xhdpi/ch_935_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_935_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_936_logo.png b/tests/common/res/drawable-xhdpi/ch_936_logo.png
index 2c5964de..2c5964de 100644
--- a/tests/input/res/drawable-xhdpi/ch_936_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_936_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_937_logo.png b/tests/common/res/drawable-xhdpi/ch_937_logo.png
index 5392a73c..5392a73c 100644
--- a/tests/input/res/drawable-xhdpi/ch_937_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_937_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_938_logo.png b/tests/common/res/drawable-xhdpi/ch_938_logo.png
index 8350910c..8350910c 100644
--- a/tests/input/res/drawable-xhdpi/ch_938_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_938_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_939_logo.png b/tests/common/res/drawable-xhdpi/ch_939_logo.png
index f0635df0..f0635df0 100644
--- a/tests/input/res/drawable-xhdpi/ch_939_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_939_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_93_logo.png b/tests/common/res/drawable-xhdpi/ch_93_logo.png
index 976c07cb..976c07cb 100644
--- a/tests/input/res/drawable-xhdpi/ch_93_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_93_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_940_logo.png b/tests/common/res/drawable-xhdpi/ch_940_logo.png
index b9c76dbc..b9c76dbc 100644
--- a/tests/input/res/drawable-xhdpi/ch_940_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_940_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_941_logo.png b/tests/common/res/drawable-xhdpi/ch_941_logo.png
index d9e3361f..d9e3361f 100644
--- a/tests/input/res/drawable-xhdpi/ch_941_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_941_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_942_logo.png b/tests/common/res/drawable-xhdpi/ch_942_logo.png
index 997643c1..997643c1 100644
--- a/tests/input/res/drawable-xhdpi/ch_942_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_942_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_943_logo.png b/tests/common/res/drawable-xhdpi/ch_943_logo.png
index 4c6f1752..4c6f1752 100644
--- a/tests/input/res/drawable-xhdpi/ch_943_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_943_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_944_logo.png b/tests/common/res/drawable-xhdpi/ch_944_logo.png
index 40a11f40..40a11f40 100644
--- a/tests/input/res/drawable-xhdpi/ch_944_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_944_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_945_logo.png b/tests/common/res/drawable-xhdpi/ch_945_logo.png
index 9cc401a7..9cc401a7 100644
--- a/tests/input/res/drawable-xhdpi/ch_945_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_945_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_946_logo.png b/tests/common/res/drawable-xhdpi/ch_946_logo.png
index bdb5bab4..bdb5bab4 100644
--- a/tests/input/res/drawable-xhdpi/ch_946_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_946_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_947_logo.png b/tests/common/res/drawable-xhdpi/ch_947_logo.png
index 541b632d..541b632d 100644
--- a/tests/input/res/drawable-xhdpi/ch_947_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_947_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_948_logo.png b/tests/common/res/drawable-xhdpi/ch_948_logo.png
index 4db04738..4db04738 100644
--- a/tests/input/res/drawable-xhdpi/ch_948_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_948_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_949_logo.png b/tests/common/res/drawable-xhdpi/ch_949_logo.png
index 399a4e51..399a4e51 100644
--- a/tests/input/res/drawable-xhdpi/ch_949_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_949_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_94_logo.png b/tests/common/res/drawable-xhdpi/ch_94_logo.png
index e22800b8..e22800b8 100644
--- a/tests/input/res/drawable-xhdpi/ch_94_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_94_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_950_logo.png b/tests/common/res/drawable-xhdpi/ch_950_logo.png
index 5db6be41..5db6be41 100644
--- a/tests/input/res/drawable-xhdpi/ch_950_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_950_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_951_logo.png b/tests/common/res/drawable-xhdpi/ch_951_logo.png
index 6fbf5951..6fbf5951 100644
--- a/tests/input/res/drawable-xhdpi/ch_951_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_951_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_952_logo.png b/tests/common/res/drawable-xhdpi/ch_952_logo.png
index 0e5e39aa..0e5e39aa 100644
--- a/tests/input/res/drawable-xhdpi/ch_952_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_952_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_953_logo.png b/tests/common/res/drawable-xhdpi/ch_953_logo.png
index 430a5e4d..430a5e4d 100644
--- a/tests/input/res/drawable-xhdpi/ch_953_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_953_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_954_logo.png b/tests/common/res/drawable-xhdpi/ch_954_logo.png
index 8ddc6cee..8ddc6cee 100644
--- a/tests/input/res/drawable-xhdpi/ch_954_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_954_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_955_logo.png b/tests/common/res/drawable-xhdpi/ch_955_logo.png
index 69ec92b5..69ec92b5 100644
--- a/tests/input/res/drawable-xhdpi/ch_955_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_955_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_956_logo.png b/tests/common/res/drawable-xhdpi/ch_956_logo.png
index bc1edbd7..bc1edbd7 100644
--- a/tests/input/res/drawable-xhdpi/ch_956_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_956_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_957_logo.png b/tests/common/res/drawable-xhdpi/ch_957_logo.png
index 20db4202..20db4202 100644
--- a/tests/input/res/drawable-xhdpi/ch_957_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_957_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_958_logo.png b/tests/common/res/drawable-xhdpi/ch_958_logo.png
index 8e9a7a68..8e9a7a68 100644
--- a/tests/input/res/drawable-xhdpi/ch_958_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_958_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_959_logo.png b/tests/common/res/drawable-xhdpi/ch_959_logo.png
index 4d61c092..4d61c092 100644
--- a/tests/input/res/drawable-xhdpi/ch_959_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_959_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_95_logo.png b/tests/common/res/drawable-xhdpi/ch_95_logo.png
index 50cc5990..50cc5990 100644
--- a/tests/input/res/drawable-xhdpi/ch_95_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_95_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_960_logo.png b/tests/common/res/drawable-xhdpi/ch_960_logo.png
index b2a54413..b2a54413 100644
--- a/tests/input/res/drawable-xhdpi/ch_960_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_960_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_961_logo.png b/tests/common/res/drawable-xhdpi/ch_961_logo.png
index 5dc31323..5dc31323 100644
--- a/tests/input/res/drawable-xhdpi/ch_961_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_961_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_962_logo.png b/tests/common/res/drawable-xhdpi/ch_962_logo.png
index 4ef2a219..4ef2a219 100644
--- a/tests/input/res/drawable-xhdpi/ch_962_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_962_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_963_logo.png b/tests/common/res/drawable-xhdpi/ch_963_logo.png
index 22633d33..22633d33 100644
--- a/tests/input/res/drawable-xhdpi/ch_963_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_963_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_964_logo.png b/tests/common/res/drawable-xhdpi/ch_964_logo.png
index ba8ad46c..ba8ad46c 100644
--- a/tests/input/res/drawable-xhdpi/ch_964_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_964_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_965_logo.png b/tests/common/res/drawable-xhdpi/ch_965_logo.png
index 2c935852..2c935852 100644
--- a/tests/input/res/drawable-xhdpi/ch_965_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_965_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_966_logo.png b/tests/common/res/drawable-xhdpi/ch_966_logo.png
index 8b751988..8b751988 100644
--- a/tests/input/res/drawable-xhdpi/ch_966_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_966_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_967_logo.png b/tests/common/res/drawable-xhdpi/ch_967_logo.png
index 974712fd..974712fd 100644
--- a/tests/input/res/drawable-xhdpi/ch_967_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_967_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_968_logo.png b/tests/common/res/drawable-xhdpi/ch_968_logo.png
index d1edc191..d1edc191 100644
--- a/tests/input/res/drawable-xhdpi/ch_968_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_968_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_969_logo.png b/tests/common/res/drawable-xhdpi/ch_969_logo.png
index 7774ed92..7774ed92 100644
--- a/tests/input/res/drawable-xhdpi/ch_969_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_969_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_96_logo.png b/tests/common/res/drawable-xhdpi/ch_96_logo.png
index e37da468..e37da468 100644
--- a/tests/input/res/drawable-xhdpi/ch_96_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_96_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_970_logo.png b/tests/common/res/drawable-xhdpi/ch_970_logo.png
index 5dd52457..5dd52457 100644
--- a/tests/input/res/drawable-xhdpi/ch_970_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_970_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_971_logo.png b/tests/common/res/drawable-xhdpi/ch_971_logo.png
index 0aca871c..0aca871c 100644
--- a/tests/input/res/drawable-xhdpi/ch_971_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_971_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_972_logo.png b/tests/common/res/drawable-xhdpi/ch_972_logo.png
index 2f8803b5..2f8803b5 100644
--- a/tests/input/res/drawable-xhdpi/ch_972_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_972_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_973_logo.png b/tests/common/res/drawable-xhdpi/ch_973_logo.png
index 35ec5c90..35ec5c90 100644
--- a/tests/input/res/drawable-xhdpi/ch_973_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_973_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_974_logo.png b/tests/common/res/drawable-xhdpi/ch_974_logo.png
index 98f9a7aa..98f9a7aa 100644
--- a/tests/input/res/drawable-xhdpi/ch_974_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_974_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_975_logo.png b/tests/common/res/drawable-xhdpi/ch_975_logo.png
index bdc31316..bdc31316 100644
--- a/tests/input/res/drawable-xhdpi/ch_975_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_975_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_976_logo.png b/tests/common/res/drawable-xhdpi/ch_976_logo.png
index 078d35b7..078d35b7 100644
--- a/tests/input/res/drawable-xhdpi/ch_976_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_976_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_977_logo.png b/tests/common/res/drawable-xhdpi/ch_977_logo.png
index c6fbb7be..c6fbb7be 100644
--- a/tests/input/res/drawable-xhdpi/ch_977_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_977_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_978_logo.png b/tests/common/res/drawable-xhdpi/ch_978_logo.png
index 00a6e5e1..00a6e5e1 100644
--- a/tests/input/res/drawable-xhdpi/ch_978_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_978_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_979_logo.png b/tests/common/res/drawable-xhdpi/ch_979_logo.png
index fd1f56d1..fd1f56d1 100644
--- a/tests/input/res/drawable-xhdpi/ch_979_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_979_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_97_logo.png b/tests/common/res/drawable-xhdpi/ch_97_logo.png
index f852548a..f852548a 100644
--- a/tests/input/res/drawable-xhdpi/ch_97_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_97_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_980_logo.png b/tests/common/res/drawable-xhdpi/ch_980_logo.png
index 362a1988..362a1988 100644
--- a/tests/input/res/drawable-xhdpi/ch_980_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_980_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_981_logo.png b/tests/common/res/drawable-xhdpi/ch_981_logo.png
index 9f879c4b..9f879c4b 100644
--- a/tests/input/res/drawable-xhdpi/ch_981_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_981_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_982_logo.png b/tests/common/res/drawable-xhdpi/ch_982_logo.png
index 0d945a11..0d945a11 100644
--- a/tests/input/res/drawable-xhdpi/ch_982_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_982_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_983_logo.png b/tests/common/res/drawable-xhdpi/ch_983_logo.png
index ffeaddfc..ffeaddfc 100644
--- a/tests/input/res/drawable-xhdpi/ch_983_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_983_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_984_logo.png b/tests/common/res/drawable-xhdpi/ch_984_logo.png
index d8f92211..d8f92211 100644
--- a/tests/input/res/drawable-xhdpi/ch_984_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_984_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_985_logo.png b/tests/common/res/drawable-xhdpi/ch_985_logo.png
index b6c6f0dc..b6c6f0dc 100644
--- a/tests/input/res/drawable-xhdpi/ch_985_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_985_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_986_logo.png b/tests/common/res/drawable-xhdpi/ch_986_logo.png
index 8e2c0b50..8e2c0b50 100644
--- a/tests/input/res/drawable-xhdpi/ch_986_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_986_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_987_logo.png b/tests/common/res/drawable-xhdpi/ch_987_logo.png
index ce8c107a..ce8c107a 100644
--- a/tests/input/res/drawable-xhdpi/ch_987_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_987_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_988_logo.png b/tests/common/res/drawable-xhdpi/ch_988_logo.png
index ffa8ded7..ffa8ded7 100644
--- a/tests/input/res/drawable-xhdpi/ch_988_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_988_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_989_logo.png b/tests/common/res/drawable-xhdpi/ch_989_logo.png
index 8522a03a..8522a03a 100644
--- a/tests/input/res/drawable-xhdpi/ch_989_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_989_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_98_logo.png b/tests/common/res/drawable-xhdpi/ch_98_logo.png
index 13fe760f..13fe760f 100644
--- a/tests/input/res/drawable-xhdpi/ch_98_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_98_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_990_logo.png b/tests/common/res/drawable-xhdpi/ch_990_logo.png
index bd6df061..bd6df061 100644
--- a/tests/input/res/drawable-xhdpi/ch_990_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_990_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_991_logo.png b/tests/common/res/drawable-xhdpi/ch_991_logo.png
index 8611d57d..8611d57d 100644
--- a/tests/input/res/drawable-xhdpi/ch_991_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_991_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_992_logo.png b/tests/common/res/drawable-xhdpi/ch_992_logo.png
index 36d26bc0..36d26bc0 100644
--- a/tests/input/res/drawable-xhdpi/ch_992_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_992_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_993_logo.png b/tests/common/res/drawable-xhdpi/ch_993_logo.png
index f67e0eec..f67e0eec 100644
--- a/tests/input/res/drawable-xhdpi/ch_993_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_993_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_994_logo.png b/tests/common/res/drawable-xhdpi/ch_994_logo.png
index a63d5ee1..a63d5ee1 100644
--- a/tests/input/res/drawable-xhdpi/ch_994_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_994_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_995_logo.png b/tests/common/res/drawable-xhdpi/ch_995_logo.png
index b7b45167..b7b45167 100644
--- a/tests/input/res/drawable-xhdpi/ch_995_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_995_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_996_logo.png b/tests/common/res/drawable-xhdpi/ch_996_logo.png
index 82c042c3..82c042c3 100644
--- a/tests/input/res/drawable-xhdpi/ch_996_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_996_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_997_logo.png b/tests/common/res/drawable-xhdpi/ch_997_logo.png
index d70e4793..d70e4793 100644
--- a/tests/input/res/drawable-xhdpi/ch_997_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_997_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_998_logo.png b/tests/common/res/drawable-xhdpi/ch_998_logo.png
index f6c69d2e..f6c69d2e 100644
--- a/tests/input/res/drawable-xhdpi/ch_998_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_998_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_999_logo.png b/tests/common/res/drawable-xhdpi/ch_999_logo.png
index 844c06fd..844c06fd 100644
--- a/tests/input/res/drawable-xhdpi/ch_999_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_999_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_99_logo.png b/tests/common/res/drawable-xhdpi/ch_99_logo.png
index d8be447d..d8be447d 100644
--- a/tests/input/res/drawable-xhdpi/ch_99_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_99_logo.png
Binary files differ
diff --git a/tests/input/res/drawable-xhdpi/ch_9_logo.png b/tests/common/res/drawable-xhdpi/ch_9_logo.png
index 8ba6bc55..8ba6bc55 100644
--- a/tests/input/res/drawable-xhdpi/ch_9_logo.png
+++ b/tests/common/res/drawable-xhdpi/ch_9_logo.png
Binary files differ
diff --git a/tests/common/src/com/android/tv/testing/ChannelInfo.java b/tests/common/src/com/android/tv/testing/ChannelInfo.java
index af1c9891..946c0b55 100644
--- a/tests/common/src/com/android/tv/testing/ChannelInfo.java
+++ b/tests/common/src/com/android/tv/testing/ChannelInfo.java
@@ -16,9 +16,11 @@
package com.android.tv.testing;
+import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.media.tv.TvContract;
+import android.net.Uri;
import android.support.annotation.Nullable;
import android.util.SparseArray;
@@ -38,11 +40,6 @@ public final class ChannelInfo {
VIDEO_HEIGHT_TO_FORMAT_MAP.put(4320, TvContract.Channels.VIDEO_FORMAT_4320P);
}
- /**
- * If this is specify for logo, it will be selected randomly including null.
- */
- public static final String GENERATE_LOGO = "GEN";
-
public static final String[] PROJECTION = {
TvContract.Channels.COLUMN_DISPLAY_NUMBER,
TvContract.Channels.COLUMN_DISPLAY_NAME,
@@ -80,15 +77,20 @@ public final class ChannelInfo {
.setOriginalNetworkId(channelNumber);
if (context != null) {
// tests/input/tools/get_test_logos.sh only stores 1000 logos.
- int logo_num = (channelNumber % 1000);
- builder.setLogoUrl(
- "android.resource://com.android.tv.testinput/drawable/ch_" + logo_num
- + "_logo"
- );
+ builder.setLogoUrl(getUriStringForChannelLogo(context, channelNumber));
}
return builder.build();
}
+ public static String getUriStringForChannelLogo(Context context, int logoIndex) {
+ int index = (logoIndex % 1000) + 1;
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+ .authority(context.getPackageName())
+ .path("drawable")
+ .appendPath("ch_" + index + "_logo").build().toString();
+ }
+
public static ChannelInfo fromCursor(Cursor c) {
// TODO: Fill other fields.
Builder builder = new Builder();
diff --git a/tests/common/src/com/android/tv/testing/Utils.java b/tests/common/src/com/android/tv/testing/Utils.java
index 66a13466..b2b4036e 100644
--- a/tests/common/src/com/android/tv/testing/Utils.java
+++ b/tests/common/src/com/android/tv/testing/Utils.java
@@ -19,16 +19,15 @@ package com.android.tv.testing;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.net.Uri;
-import android.os.Looper;
import android.util.Log;
import com.android.tv.common.TvCommonUtils;
-import com.android.tv.util.MainThreadExecutor;
import java.io.IOException;
import java.io.InputStream;
@@ -37,8 +36,6 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
/**
* An utility class for testing.
@@ -101,27 +98,6 @@ public final class Utils {
return new Random(DEFAULT_RANDOM_SEED);
}
- /**
- * Executes a call on the main thread, blocking until it is completed.
- *
- * <p>Useful for doing things that are not thread-safe, such as looking at or modifying the view
- * hierarchy.
- *
- * @param runnable The code to run on the main thread.
- */
- public static void runOnMainSync(Runnable runnable) {
- if (Looper.myLooper() == Looper.getMainLooper()) {
- runnable.run();
- } else {
- Future<?> temp = MainThreadExecutor.getInstance().submit(runnable);
- try {
- temp.get();
- } catch (InterruptedException | ExecutionException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
private static long getSeed() {
// Set random seed as the date to track failed test data easily.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
@@ -131,4 +107,16 @@ public final class Utils {
}
private Utils() {}
+
+ /**
+ * Checks whether TvActivity is enabled or not.
+ */
+ public static boolean isTvActivityEnabled(Context context) {
+ PackageManager pm = context.getPackageManager();
+ ComponentName name = new ComponentName("com.android.tv",
+ "com.android.tv.TvActivity");
+ int enabled = pm.getComponentEnabledSetting(name);
+ return enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ || enabled == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ }
}
diff --git a/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java b/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java
index b9def95e..a9bfa97a 100644
--- a/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java
+++ b/tests/common/src/com/android/tv/testing/dvr/RecordingTestUtils.java
@@ -16,7 +16,7 @@
package com.android.tv.testing.dvr;
-import com.android.tv.dvr.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording;
import junit.framework.Assert;
diff --git a/tests/common/src/com/android/tv/testing/uihelper/Constants.java b/tests/common/src/com/android/tv/testing/uihelper/Constants.java
index 8f607fbf..8dd8e14a 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/Constants.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/Constants.java
@@ -23,6 +23,7 @@ public final class Constants {
public static final double EXTRA_TIMEOUT_PERCENT = .05;
public static final int MIN_EXTRA_TIMEOUT = 10;
public static final long MAX_SHOW_DELAY_MILLIS = 200;
+ public static final long MAX_FOCUSED_DELAY_MILLIS = 1000;
public static final String TV_APP_PACKAGE = "com.android.tv";
public static final BySelector TV_VIEW = By.res(TV_APP_PACKAGE, "main_tunable_tv_view");
public static final BySelector CHANNEL_BANNER = By.res(TV_APP_PACKAGE, "channel_banner_view");
@@ -30,6 +31,8 @@ public final class Constants {
public static final BySelector MENU = By.res(TV_APP_PACKAGE, "menu");
public static final BySelector SIDE_PANEL = By.res(TV_APP_PACKAGE, "side_panel");
public static final BySelector PROGRAM_GUIDE = By.res(TV_APP_PACKAGE, "program_guide");
+ public static final BySelector DVR_LIBRARY = By.res(TV_APP_PACKAGE, "dvr_frame");
+ public static final BySelector DVR_SCHEDULES = By.res(TV_APP_PACKAGE, "dvr_schedules");
public static final BySelector FOCUSED_VIEW = By.focused(true);
private Constants() {
diff --git a/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java b/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java
index 6757cf01..1dc0f020 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/LiveChannelsUiDeviceHelper.java
@@ -1,6 +1,7 @@
package com.android.tv.testing.uihelper;
import static com.android.tv.testing.uihelper.UiDeviceAsserts.waitForCondition;
+import static junit.framework.TestCase.assertTrue;
import android.content.Context;
import android.content.Intent;
@@ -11,6 +12,8 @@ import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
import android.util.Log;
+import com.android.tv.testing.Utils;
+
import junit.framework.Assert;
/**
@@ -29,6 +32,7 @@ public class LiveChannelsUiDeviceHelper extends BaseUiDeviceHelper {
}
public void assertAppStarted() {
+ assertTrue("TvActivity should be enabled.", Utils.isTvActivityEnabled(mContext));
Intent intent = mContext.getPackageManager()
.getLaunchIntentForPackage(Constants.TV_APP_PACKAGE);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); // Clear out any previous instances
@@ -48,4 +52,11 @@ public class LiveChannelsUiDeviceHelper extends BaseUiDeviceHelper {
mUiDevice.pressBack();
}
}
+
+ public void assertAppStopped() {
+ while(mUiDevice.hasObject(By.pkg(Constants.TV_APP_PACKAGE).depth(0))) {
+ mUiDevice.pressBack();
+ mUiDevice.waitForIdle();
+ }
+ }
} \ No newline at end of file
diff --git a/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java b/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java
index ea5360a3..80d53242 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/MenuHelper.java
@@ -139,6 +139,11 @@ public class MenuHelper extends BaseUiDeviceHelper {
R.string.channels_item_program_guide);
}
+ public UiObject2 assertPressDvrLibrary() {
+ return assertPressMenuItem(R.string.menu_title_channels,
+ R.string.channels_item_dvr);
+ }
+
/**
* Navigate to the menu item with the text {@code itemTextResId} in the row with text
* {@code rowTitleResId}.
@@ -171,7 +176,11 @@ public class MenuHelper extends BaseUiDeviceHelper {
public void showMenu() {
if (!mUiDevice.hasObject(MENU)) {
mUiDevice.pressMenu();
- UiDeviceAsserts.assertWaitForCondition(mUiDevice, Until.hasObject(MENU));
+ if (!UiDeviceAsserts.waitForCondition(mUiDevice, Until.hasObject(MENU))) {
+ // Sometimes animations might block menu key, try again to make sure it's received.
+ mUiDevice.pressMenu();
+ UiDeviceAsserts.assertWaitForCondition(mUiDevice, Until.hasObject(MENU));
+ }
}
}
}
diff --git a/tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java b/tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java
index 2d4f9b2f..98a19a41 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/SidePanelHelper.java
@@ -47,17 +47,23 @@ public class SidePanelHelper extends BaseUiDeviceHelper {
}
public UiObject2 assertNavigateToItem(int resId) {
- String title = mTargetResources.getString(resId);
- return assertNavigateToItem(title);
+ return assertNavigateToItem(resId, Direction.DOWN);
}
+ public UiObject2 assertNavigateToItem(int resId, Direction direction) {
+ String title = mTargetResources.getString(resId);
+ return assertNavigateToItem(title, direction);
+ }
public UiObject2 assertNavigateToItem(String title) {
+ return assertNavigateToItem(title, Direction.DOWN);
+ }
+
+ public UiObject2 assertNavigateToItem(String title, Direction direction) {
BySelector sidePanelSelector = ByResource.id(mTargetResources, R.id.side_panel_list);
UiObject2 sidePanelList = mUiDevice.findObject(sidePanelSelector);
Assert.assertNotNull(sidePanelSelector + " not found", sidePanelList);
- return UiDeviceAsserts
- .assertNavigateTo(mUiDevice, sidePanelList, By.hasDescendant(By.text(title)),
- Direction.DOWN);
+ return UiDeviceAsserts.assertNavigateTo(mUiDevice, sidePanelList,
+ By.hasDescendant(By.text(title)), direction);
}
}
diff --git a/tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java b/tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java
index ea9b5460..c096d7d2 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/UiDeviceAsserts.java
@@ -17,6 +17,7 @@ package com.android.tv.testing.uihelper;
import static com.android.tv.testing.uihelper.Constants.FOCUSED_VIEW;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import android.support.test.uiautomator.By;
@@ -38,6 +39,12 @@ public final class UiDeviceAsserts {
assertEquals("Has " + bySelector, expected, uiDevice.hasObject(bySelector));
}
+ public static void assertWaitUntilFocused(UiDevice uiDevice, BySelector bySelector) {
+ UiObject2 uiObject = uiDevice.findObject(bySelector);
+ assertNotNull(uiObject);
+ assertTrue(uiObject.wait(Until.focused(true), Constants.MAX_FOCUSED_DELAY_MILLIS));
+ }
+
/**
* Assert that {@code searchCondition} becomes true within
* {@value Constants#MAX_SHOW_DELAY_MILLIS} milliseconds.
diff --git a/tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java b/tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java
index 577559c2..98eff906 100644
--- a/tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java
+++ b/tests/common/src/com/android/tv/testing/uihelper/UiDeviceUtils.java
@@ -15,8 +15,16 @@
*/
package com.android.tv.testing.uihelper;
+import static junit.framework.Assert.assertTrue;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.os.Build;
+import android.os.SystemClock;
+import android.support.test.uiautomator.Configurator;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
+import android.view.InputDevice;
import android.view.KeyEvent;
/**
@@ -51,7 +59,7 @@ public final class UiDeviceUtils {
}
/**
- * Parses the string and sends the corresponding individual key preses.
+ * Parses the string and sends the corresponding individual key presses.
* <p>
* <b>Note:</b> only handles 0-9, '.', and '-'.
*/
@@ -69,6 +77,59 @@ public final class UiDeviceUtils {
}
}
+ /**
+ * Sends the DPAD Center key presses with the {@code repeat} count.
+ * TODO: Remove instrumentation argument once migrated to JUnit4.
+ */
+ public static void pressDPadCenter(Instrumentation instrumentation, int repeat) {
+ pressKey(instrumentation, KeyEvent.KEYCODE_DPAD_CENTER, repeat);
+ }
+
+ private static void pressKey(Instrumentation instrumentation, int keyCode, int repeat) {
+ UiDevice.getInstance(instrumentation).waitForIdle();
+ for (int i = 0; i < repeat; ++i) {
+ assertPressKeyDown(instrumentation, keyCode, false);
+ if (i < repeat - 1) {
+ assertPressKeyUp(instrumentation, keyCode, false);
+ }
+ }
+ // Send last key event synchronously.
+ assertPressKeyUp(instrumentation, keyCode, true);
+ }
+
+ private static void assertPressKeyDown(Instrumentation instrumentation, int keyCode,
+ boolean sync) {
+ assertPressKey(instrumentation, KeyEvent.ACTION_DOWN, keyCode, sync);
+ }
+
+ private static void assertPressKeyUp(Instrumentation instrumentation, int keyCode,
+ boolean sync) {
+ assertPressKey(instrumentation, KeyEvent.ACTION_UP, keyCode, sync);
+ }
+
+ private static void assertPressKey(Instrumentation instrumentation, int action, int keyCode,
+ boolean sync) {
+ long eventTime = SystemClock.uptimeMillis();
+ KeyEvent event = new KeyEvent(eventTime, eventTime, action, keyCode, 0, 0, -1, 0, 0,
+ InputDevice.SOURCE_KEYBOARD);
+ assertTrue("Failed to inject key up event:" + event,
+ injectEvent(instrumentation, event, sync));
+ }
+
+ private static boolean injectEvent(Instrumentation instrumentation, KeyEvent event,
+ boolean sync) {
+ return getUiAutomation(instrumentation).injectInputEvent(event, sync);
+ }
+
+ private static UiAutomation getUiAutomation(Instrumentation instrumentation) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ int flags = Configurator.getInstance().getUiAutomationFlags();
+ return instrumentation.getUiAutomation(flags);
+ } else {
+ return instrumentation.getUiAutomation();
+ }
+ }
+
private UiDeviceUtils() {
}
}
diff --git a/tests/func/Android.mk b/tests/func/Android.mk
index b0c5ad1c..e89ba25b 100644
--- a/tests/func/Android.mk
+++ b/tests/func/Android.mk
@@ -14,8 +14,6 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
tv-test-common \
ub-uiautomator \
-LOCAL_JAVA_LIBRARIES := legacy-android-test
-
LOCAL_INSTRUMENTATION_FOR := LiveTv
LOCAL_SDK_VERSION := current
diff --git a/tests/func/OWNERS b/tests/func/OWNERS
new file mode 100644
index 00000000..4aa5fe52
--- /dev/null
+++ b/tests/func/OWNERS
@@ -0,0 +1,2 @@
+nchalko@google.com
+shubang@google.com
diff --git a/tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java b/tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java
index e4f612e3..cfa5eda7 100644
--- a/tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/ChannelSourcesTest.java
@@ -23,6 +23,7 @@ import android.support.test.uiautomator.Until;
import com.android.tv.R;
import com.android.tv.testing.uihelper.ByResource;
+import com.android.tv.testing.uihelper.UiDeviceUtils;
/**
* Tests for channel sources.
@@ -60,8 +61,7 @@ public class ChannelSourcesTest extends LiveChannelsTestCase {
assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
mSidePanelHelper.assertNavigateToItem(R.string.settings_channel_source_item_setup);
- mDevice.pressDPadCenter();
- mDevice.pressDPadCenter();
+ UiDeviceUtils.pressDPadCenter(getInstrumentation(), 2);
assertWaitForCondition(mDevice,
Until.hasObject(ByResource.text(mTargetResources, R.string.setup_sources_text)));
diff --git a/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java b/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java
index 25c7909b..e306e6c6 100644
--- a/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java
+++ b/tests/func/src/com/android/tv/tests/ui/LiveChannelsTestCase.java
@@ -73,6 +73,8 @@ public abstract class LiveChannelsTestCase extends InstrumentationTestCase {
.hasObject(Constants.PROGRAM_GUIDE)) {
mDevice.pressBack();
}
+ // To destroy the activity to make sure next test case's activity launch check works well.
+ mDevice.pressBack();
super.tearDown();
}
diff --git a/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java b/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java
index bbc7aa81..82c6a810 100644
--- a/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java
+++ b/tests/func/src/com/android/tv/tests/ui/PlayControlsRowViewTest.java
@@ -16,11 +16,11 @@
package com.android.tv.tests.ui;
+import static com.android.tv.testing.uihelper.Constants.CHANNEL_BANNER;
import static com.android.tv.testing.uihelper.Constants.FOCUSED_VIEW;
import static com.android.tv.testing.uihelper.Constants.MENU;
import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
-import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiObject2;
@@ -32,9 +32,8 @@ import com.android.tv.testing.testinput.TvTestInputConstants;
import com.android.tv.testing.uihelper.DialogHelper;
@SmallTest
-@SdkSuppress(minSdkVersion = 23)
public class PlayControlsRowViewTest extends LiveChannelsTestCase {
- private static final int BUTTON_INDEX_PLAY_PAUSE = 2;
+ private static final String BUTTON_ID_PLAY_PAUSE = "com.android.tv:id/play_pause";
private BySelector mBySettingsSidePanel;
@@ -42,7 +41,9 @@ public class PlayControlsRowViewTest extends LiveChannelsTestCase {
protected void setUp() throws Exception {
super.setUp();
mLiveChannelsHelper.assertAppStarted();
- pressKeysForChannel(TvTestInputConstants.CH_1_DEFAULT_DONT_MODIFY);
+ pressKeysForChannel(TvTestInputConstants.CH_2);
+ // Wait until KeypadChannelSwitchView closes.
+ assertWaitForCondition(mDevice, Until.hasObject(CHANNEL_BANNER));
// Tune to a new channel to ensure that the channel is changed.
mDevice.pressDPadUp();
getInstrumentation().waitForIdleSync();
@@ -56,7 +57,7 @@ public class PlayControlsRowViewTest extends LiveChannelsTestCase {
public void testFocusedViewInNormalCase() {
mMenuHelper.showMenu();
mMenuHelper.assertNavigateToPlayControlsRow();
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
+ assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
mDevice.pressBack();
}
@@ -69,49 +70,30 @@ public class PlayControlsRowViewTest extends LiveChannelsTestCase {
// Fast forward button
mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD);
mMenuHelper.assertWaitForMenu();
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
+ assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
mDevice.pressBack();
// Next button
mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_NEXT);
mMenuHelper.assertWaitForMenu();
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
- mDevice.pressBack();
- }
-
- /**
- * Tests the case when the rewinding action is disabled.
- * In this case, the button corresponding to the action is disabled, so play/pause button should
- * have the focus.
- */
- public void testFocusedViewWithDisabledActionBackward() {
- // Previous button
- mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
- mMenuHelper.assertWaitForMenu();
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
- mDevice.pressBack();
-
- // Rewind button
- mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_REWIND);
- mMenuHelper.assertWaitForMenu();
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
+ assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
mDevice.pressBack();
}
public void testFocusedViewInMenu() {
mMenuHelper.showMenu();
mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PLAY);
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
+ assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
mMenuHelper.assertNavigateToRow(R.string.menu_title_channels);
mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_NEXT);
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
+ assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
}
public void testKeepPausedWhileParentalControlChange() {
// Pause the playback.
mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PAUSE);
mMenuHelper.assertWaitForMenu();
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
+ assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
// Show parental controls fragment.
mMenuHelper.assertPressOptionsSettings();
assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
@@ -130,14 +112,14 @@ public class PlayControlsRowViewTest extends LiveChannelsTestCase {
mDevice.pressBack();
// Return to the main menu.
mMenuHelper.assertWaitForMenu();
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
+ assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
}
public void testKeepPausedAfterVisitingHome() {
// Pause the playback.
mDevice.pressKeyCode(KeyEvent.KEYCODE_MEDIA_PAUSE);
mMenuHelper.assertWaitForMenu();
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
+ assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
// Press HOME twice to visit the home screen and return to Live TV.
mDevice.pressHome();
// Wait until home screen is shown.
@@ -147,19 +129,15 @@ public class PlayControlsRowViewTest extends LiveChannelsTestCase {
mDevice.waitForIdle();
// Return to the main menu.
mMenuHelper.assertWaitForMenu();
- assertButtonHasFocus(BUTTON_INDEX_PLAY_PAUSE);
+ assertButtonHasFocus(BUTTON_ID_PLAY_PAUSE);
}
- private void assertButtonHasFocus(int expectedButtonIndex) {
+ private void assertButtonHasFocus(String buttonId) {
UiObject2 menu = mDevice.findObject(MENU);
UiObject2 focusedView = menu.findObject(FOCUSED_VIEW);
assertNotNull("Play controls row doesn't have a focused child.", focusedView);
UiObject2 focusedButtonGroup = focusedView.getParent();
assertNotNull("The focused item should have parent", focusedButtonGroup);
- UiObject2 controlBar = focusedButtonGroup.getParent();
- assertNotNull("The focused item should have grandparent", controlBar);
- assertTrue("The grandparent should have more than five children",
- controlBar.getChildCount() >= 5);
- assertEquals(controlBar.getChildren().get(expectedButtonIndex), focusedButtonGroup);
+ assertEquals(buttonId, focusedButtonGroup.getResourceName());
}
}
diff --git a/tests/func/src/com/android/tv/tests/ui/ProgramGuidePerformanceTest.java b/tests/func/src/com/android/tv/tests/ui/ProgramGuidePerformanceTest.java
deleted file mode 100644
index 95921df9..00000000
--- a/tests/func/src/com/android/tv/tests/ui/ProgramGuidePerformanceTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.tests.ui;
-
-import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
-
-import android.os.SystemClock;
-import android.support.test.filters.LargeTest;
-import android.support.test.uiautomator.Until;
-import android.util.Log;
-
-import com.android.tv.R;
-import com.android.tv.testing.uihelper.Constants;
-
-/**
- * Tests for {@link com.android.tv.MainActivity}.
- */
-@LargeTest
-public class ProgramGuidePerformanceTest extends LiveChannelsTestCase {
- private static final String TAG = "ProgramGuidePerformance";
-
- public static final int SHOW_MENU_MAX_DURATION_MS = 1500;
- public void testShowMenu() {
- mLiveChannelsHelper.assertAppStarted();
- mMenuHelper.showMenu();
- mMenuHelper.assertNavigateToMenuItem(R.string.menu_title_channels,
- R.string.channels_item_program_guide);
- //TODO: build a simple performance framework like JankTest
- long start = SystemClock.elapsedRealtime();
- Log.v(TAG, "start " + start + " milliSeconds");
- mDevice.pressDPadCenter();
- assertWaitForCondition(mDevice, Until.hasObject(Constants.PROGRAM_GUIDE));
- long end = SystemClock.elapsedRealtime();
- Log.v(TAG, "end " + end + " milliSeconds");
- long duration = end - start;
- assertDuration("ShowMenu", SHOW_MENU_MAX_DURATION_MS, duration);
- mDevice.pressBack();
- }
-
- private void assertDuration(String msg, long expectedMaxMilliSeconds, long actualMilliSeconds) {
- Log.d(TAG, msg + " duration " + actualMilliSeconds + " milliSeconds");
- assertTrue(msg + " duration expected to be <= " + expectedMaxMilliSeconds
- + " milliSeconds but was " + actualMilliSeconds + " milliSeconds.",
- actualMilliSeconds <= expectedMaxMilliSeconds);
- }
-}
diff --git a/tests/func/src/com/android/tv/tests/ui/dvr/DvrLibraryTest.java b/tests/func/src/com/android/tv/tests/ui/dvr/DvrLibraryTest.java
new file mode 100644
index 00000000..d88e67ad
--- /dev/null
+++ b/tests/func/src/com/android/tv/tests/ui/dvr/DvrLibraryTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2017 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.tv.tests.ui.dvr;
+
+import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertHas;
+import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
+import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitUntilFocused;
+
+import android.os.Build;
+import android.support.test.filters.MediumTest;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+
+import com.android.tv.R;
+import com.android.tv.testing.uihelper.ByResource;
+import com.android.tv.testing.uihelper.Constants;
+import com.android.tv.tests.ui.LiveChannelsTestCase;
+
+import java.util.regex.Pattern;
+
+@MediumTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class DvrLibraryTest extends LiveChannelsTestCase {
+ private static final String PROGRAM_NAME_PREFIX = "Title(";
+
+ private BySelector mRecentRow;
+ private BySelector mScheduledRow;
+ private BySelector mSeriesRow;
+ private BySelector mFullScheduleCard;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mRecentRow = By.hasDescendant(ByResource.text(mTargetResources, R.string.dvr_main_recent));
+ mScheduledRow = By.hasDescendant(
+ ByResource.text(mTargetResources, R.string.dvr_main_scheduled));
+ mSeriesRow = By.hasDescendant(ByResource.text(mTargetResources, R.string.dvr_main_series));
+ mFullScheduleCard = By.focusable(true).hasDescendant(
+ ByResource.text(mTargetResources, R.string.dvr_full_schedule_card_view_title));
+ mLiveChannelsHelper.assertAppStarted();
+ }
+
+ public void testCancel() {
+ mMenuHelper.assertPressDvrLibrary();
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+ mDevice.pressBack();
+ assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ assertHas(mDevice, Constants.MENU, false);
+ }
+
+ public void testEmptyLibrary() {
+ mMenuHelper.assertPressDvrLibrary();
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+
+ // DVR Library is empty, only Scheduled row and Full schedule card should be displayed.
+ assertHas(mDevice, mRecentRow, false);
+ assertHas(mDevice, mScheduledRow, true);
+ assertHas(mDevice, mSeriesRow, false);
+
+ mDevice.pressDPadCenter();
+ assertWaitUntilFocused(mDevice, mFullScheduleCard);
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+
+ // Empty schedules screen should be shown.
+ assertHas(mDevice, Constants.DVR_SCHEDULES, true);
+ assertHas(mDevice, ByResource.text(mTargetResources, R.string.dvr_schedules_empty_state),
+ true);
+
+ // Close the DVR library.
+ mDevice.pressBack();
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+ mDevice.pressBack();
+ assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ }
+
+ public void testScheduleRecordings() {
+ BySelector newScheduleCard = By.focusable(true).hasDescendant(
+ By.textStartsWith(PROGRAM_NAME_PREFIX)).hasDescendant(By.textEndsWith("today"));
+ BySelector seriesCardWithOneSchedule = By.focusable(true).hasDescendant(
+ By.textStartsWith(PROGRAM_NAME_PREFIX)).hasDescendant(By.text(mTargetResources
+ .getQuantityString(R.plurals.dvr_count_scheduled_recordings, 1, 1)));
+ BySelector seriesCardWithOneRecordedProgram = By.focusable(true).hasDescendant(
+ By.textStartsWith(PROGRAM_NAME_PREFIX)).hasDescendant(By.text(mTargetResources
+ .getQuantityString(R.plurals.dvr_count_new_recordings, 1, 1)));
+ Pattern watchButton = Pattern.compile("^" + mTargetResources
+ .getString(R.string.dvr_detail_watch).toUpperCase() + "\n.*$");
+
+ mMenuHelper.showMenu();
+ mMenuHelper.assertNavigateToPlayControlsRow();
+ mDevice.pressDPadRight();
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.hasObject(
+ ByResource.text(mTargetResources, R.string.dvr_action_record_episode)));
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.gone(
+ ByResource.text(mTargetResources, R.string.dvr_action_record_episode)));
+
+ mMenuHelper.assertPressDvrLibrary();
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+
+ // Schedule should be automatically added to the series.
+ assertHas(mDevice, mRecentRow, false);
+ assertHas(mDevice, mScheduledRow, true);
+ assertHas(mDevice, mSeriesRow, true);
+ String programName = mDevice.findObject(By.textStartsWith(PROGRAM_NAME_PREFIX)).getText();
+
+ // Move to scheduled row, there should be one new schedule and one full schedule card.
+ mDevice.pressDPadRight();
+ assertWaitUntilFocused(mDevice, newScheduleCard);
+ mDevice.pressDPadRight();
+ assertWaitUntilFocused(mDevice, mFullScheduleCard);
+
+ // Enters the full schedule, there should be one schedule in the full schedule.
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ assertHas(mDevice, Constants.DVR_SCHEDULES, true);
+ assertHas(mDevice, ByResource.text(mTargetResources, R.string.dvr_schedules_empty_state),
+ false);
+ assertHas(mDevice, By.textStartsWith(programName), true);
+
+ // Moves to the series card, clicks it, the detail page should be shown with "View schedule"
+ // button.
+ mDevice.pressBack();
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+ mDevice.pressDPadLeft();
+ assertWaitUntilFocused(mDevice, newScheduleCard);
+ mDevice.pressDPadDown();
+ assertWaitUntilFocused(mDevice, seriesCardWithOneSchedule);
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ assertHas(mDevice, By.text(mTargetResources
+ .getString(R.string.dvr_detail_view_schedule).toUpperCase()), true);
+ assertHas(mDevice, By.text(watchButton), false);
+ assertHas(mDevice, By.text(mTargetResources
+ .getString(R.string.dvr_detail_series_delete).toUpperCase()), false);
+
+ // Clicks the new schedule, the detail page should be shown with "Stop recording" button.
+ mDevice.pressBack();
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+ assertWaitUntilFocused(mDevice, seriesCardWithOneSchedule);
+ mDevice.pressDPadUp();
+ assertWaitUntilFocused(mDevice, newScheduleCard);
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ assertHas(mDevice, By.text(mTargetResources
+ .getString(R.string.dvr_detail_stop_recording).toUpperCase()), true);
+
+ // Stops the recording
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.hasObject(
+ ByResource.text(mTargetResources, R.string.dvr_action_stop)));
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.gone(
+ ByResource.text(mTargetResources, R.string.dvr_action_stop)));
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+ assertWaitUntilFocused(mDevice, mFullScheduleCard);
+
+ // Moves to series' detail page again, now it should have two more buttons
+ mDevice.pressDPadDown();
+ assertWaitUntilFocused(mDevice, seriesCardWithOneRecordedProgram);
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ assertHas(mDevice, By.text(watchButton), true);
+ assertHas(mDevice, By.text(mTargetResources
+ .getString(R.string.dvr_detail_view_schedule).toUpperCase()), true);
+ assertHas(mDevice, By.text(mTargetResources
+ .getString(R.string.dvr_detail_series_delete).toUpperCase()), true);
+
+ // Moves to the recent row and clicks the recent recorded program.
+ mDevice.pressBack();
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+ assertWaitUntilFocused(mDevice, seriesCardWithOneRecordedProgram);
+ mDevice.pressDPadUp();
+ assertWaitUntilFocused(mDevice, mFullScheduleCard);
+ mDevice.pressDPadUp();
+ assertWaitUntilFocused(mDevice, By.focusable(true).hasDescendant(By.text(programName)));
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ assertHas(mDevice, By.text(mTargetResources
+ .getString(R.string.dvr_detail_watch).toUpperCase()), true);
+ assertHas(mDevice, By.text(mTargetResources
+ .getString(R.string.dvr_detail_delete).toUpperCase()), true);
+
+ // Moves to the delete button and clicks to remove the recorded program.
+ mDevice.pressDPadRight();
+ assertWaitUntilFocused(mDevice, By.text(mTargetResources
+ .getString(R.string.dvr_detail_delete).toUpperCase()));
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.DVR_LIBRARY));
+ assertWaitUntilFocused(mDevice, mFullScheduleCard);
+
+ // DVR Library should be empty now.
+ assertHas(mDevice, mRecentRow, false);
+ assertHas(mDevice, mScheduledRow, true);
+ assertHas(mDevice, mSeriesRow, false);
+
+ // Close the DVR library.
+ mDevice.pressBack();
+ assertWaitForCondition(mDevice, Until.gone(Constants.DVR_LIBRARY));
+ }
+}
diff --git a/tests/func/src/com/android/tv/tests/ui/sidepanel/CustomizeChannelListFragmentTest.java b/tests/func/src/com/android/tv/tests/ui/sidepanel/CustomizeChannelListFragmentTest.java
new file mode 100644
index 00000000..deeb9bfd
--- /dev/null
+++ b/tests/func/src/com/android/tv/tests/ui/sidepanel/CustomizeChannelListFragmentTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 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.tv.tests.ui.sidepanel;
+
+import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
+
+import android.graphics.Point;
+import android.support.test.filters.LargeTest;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Direction;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+
+import com.android.tv.R;
+import com.android.tv.testing.uihelper.Constants;
+import com.android.tv.tests.ui.LiveChannelsTestCase;
+
+@LargeTest
+public class CustomizeChannelListFragmentTest extends LiveChannelsTestCase {
+ private BySelector mBySettingsSidePanel;
+ private UiObject2 mTvView;
+ private Point mNormalTvViewCenter;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mLiveChannelsHelper.assertAppStarted();
+ mTvView = mDevice.findObject(Constants.TV_VIEW);
+ mNormalTvViewCenter = mTvView.getVisibleCenter();
+ assertNotNull(mNormalTvViewCenter);
+ pressKeysForChannel(com.android.tv.testing.testinput.TvTestInputConstants.CH_2);
+ // Wait until KeypadChannelSwitchView closes.
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.CHANNEL_BANNER));
+ mBySettingsSidePanel = mSidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_settings);
+ }
+
+ private void assertShrunkenTvView(boolean shrunkenExpected) {
+ Point currentTvViewCenter = mTvView.getVisibleCenter();
+ if (shrunkenExpected) {
+ assertFalse(mNormalTvViewCenter.equals(currentTvViewCenter));
+ } else {
+ assertTrue(mNormalTvViewCenter.equals(currentTvViewCenter));
+ }
+ }
+
+ public void testCustomizeChannelList_noraml() {
+ // Show customize channel list fragment
+ mMenuHelper.assertPressOptionsSettings();
+ assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
+ mSidePanelHelper.assertNavigateToItem(
+ R.string.settings_channel_source_item_customize_channels);
+ mDevice.pressDPadCenter();
+ BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_edit_channels_for_an_input);
+ assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ assertShrunkenTvView(true);
+
+ // Show group by fragment
+ mSidePanelHelper.assertNavigateToItem(R.string.edit_channels_item_group_by, Direction.UP);
+ mDevice.pressDPadCenter();
+ bySidePanel = mSidePanelHelper.bySidePanelTitled(R.string.side_panel_title_group_by);
+ assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ assertShrunkenTvView(true);
+
+ // Back to customize channel list fragment
+ mDevice.pressBack();
+ bySidePanel = mSidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_edit_channels_for_an_input);
+ assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ assertShrunkenTvView(true);
+
+ // Return to the main menu.
+ mDevice.pressBack();
+ assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
+ assertShrunkenTvView(false);
+ }
+
+ public void testCustomizeChannelList_timeout() {
+ // Show customize channel list fragment
+ mMenuHelper.assertPressOptionsSettings();
+ assertWaitForCondition(mDevice, Until.hasObject(mBySettingsSidePanel));
+ mSidePanelHelper.assertNavigateToItem(
+ R.string.settings_channel_source_item_customize_channels);
+ mDevice.pressDPadCenter();
+ BySelector bySidePanel = mSidePanelHelper.bySidePanelTitled(
+ R.string.side_panel_title_edit_channels_for_an_input);
+ assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ assertShrunkenTvView(true);
+
+ // Show group by fragment
+ mSidePanelHelper.assertNavigateToItem(R.string.edit_channels_item_group_by, Direction.UP);
+ mDevice.pressDPadCenter();
+ bySidePanel = mSidePanelHelper.bySidePanelTitled(R.string.side_panel_title_group_by);
+ assertWaitForCondition(mDevice, Until.hasObject(bySidePanel));
+ assertShrunkenTvView(true);
+
+ // Wait for time-out to return to the main menu.
+ assertWaitForCondition(mDevice, Until.gone(bySidePanel),
+ mTargetResources.getInteger(R.integer.side_panel_show_duration));
+ assertShrunkenTvView(false);
+ }
+}
diff --git a/tests/input/OWNERS b/tests/input/OWNERS
new file mode 100644
index 00000000..4aa5fe52
--- /dev/null
+++ b/tests/input/OWNERS
@@ -0,0 +1,2 @@
+nchalko@google.com
+shubang@google.com
diff --git a/tests/input/res/values/strings.xml b/tests/input/res/values/strings.xml
index 3f2ab3f7..4ef43955 100644
--- a/tests/input/res/values/strings.xml
+++ b/tests/input/res/values/strings.xml
@@ -15,7 +15,6 @@
-->
<resources>
<string name="app_name" translatable="false">Test TV Inputs</string>
- <string name="about_app" translatable="false">About TV Test Inputs</string>
<string name="version" translatable="false">Version: %1$s</string>
<string name="sample_tv_input" translatable="false">Test TV Input</string>
<string name="simple_input_label" translatable="false">Test Input</string>
diff --git a/tests/input/src/com/android/tv/testinput/TestTvInputService.java b/tests/input/src/com/android/tv/testinput/TestTvInputService.java
index 659b341f..621ceacb 100644
--- a/tests/input/src/com/android/tv/testinput/TestTvInputService.java
+++ b/tests/input/src/com/android/tv/testinput/TestTvInputService.java
@@ -326,11 +326,16 @@ public class TestTvInputService extends TvInputService {
if (currentSurface != null) {
String now = new Date(mCurrentPositionMs).toString();
String name = currentChannel == null ? "Null" : currentChannel.name;
- Canvas c = currentSurface.lockCanvas(null);
- c.drawColor(0xFF888888);
- c.drawText(name, 100f, 200f, mTextPaint);
- c.drawText(now, 100f, 400f, mTextPaint);
- currentSurface.unlockCanvasAndPost(c);
+ try {
+ Canvas c = currentSurface.lockCanvas(null);
+ c.drawColor(0xFF888888);
+ c.drawText(name, 100f, 200f, mTextPaint);
+ c.drawText(now, 100f, 400f, mTextPaint);
+ // Assuming c.drawXXX will never fail.
+ currentSurface.unlockCanvasAndPost(c);
+ } catch (IllegalArgumentException e) {
+ // The surface might have been abandoned. Ignore the exception.
+ }
if (DEBUG) {
Log.v(TAG, "Post to canvas");
}
diff --git a/tests/input/src/com/android/tv/testinput/TestTvInputSetupActivity.java b/tests/input/src/com/android/tv/testinput/TestTvInputSetupActivity.java
index 732972cc..a793ac71 100644
--- a/tests/input/src/com/android/tv/testinput/TestTvInputSetupActivity.java
+++ b/tests/input/src/com/android/tv/testinput/TestTvInputSetupActivity.java
@@ -20,13 +20,10 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
-import android.content.ContentResolver;
-import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
-import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
@@ -58,39 +55,27 @@ public class TestTvInputSetupActivity extends Activity {
private void registerChannels(int channelCount) {
TestTvInputSetupActivity context = this;
- registerChannels(context, mInputId, false, channelCount);
+ registerChannels(context, mInputId, channelCount);
}
- public static void registerChannels(Context context, String inputId, boolean updateBrowsable,
- int channelCount) {
+ public static void registerChannels(Context context, String inputId, int channelCount) {
Log.i(TAG, "Registering " + channelCount + " channels");
List<ChannelInfo> channels = new ArrayList<>();
for (int i = 1; i <= channelCount; i++) {
channels.add(ChannelInfo.create(context, i));
}
ChannelUtils.updateChannels(context, inputId, channels);
- if (updateBrowsable) {
- updateChannelsBrowsable(context.getContentResolver(), inputId);
- }
// Reload channels so we have the ids.
Map<Long, ChannelInfo> channelIdToInfoMap =
ChannelUtils.queryChannelInfoMapForTvInput(context, inputId);
for (Long channelId : channelIdToInfoMap.keySet()) {
- // TODO: http://b/21705569 Create better program info for tests
ProgramInfo programInfo = ProgramInfo.create();
ProgramUtils.populatePrograms(context, TvContract.buildChannelUri(channelId),
programInfo);
}
}
- private static void updateChannelsBrowsable(ContentResolver contentResolver, String inputId) {
- Uri uri = TvContract.buildChannelsUriForInput(inputId);
- ContentValues values = new ContentValues();
- values.put(TvContract.Channels.COLUMN_BROWSABLE, 1);
- contentResolver.update(uri, values, null, null);
- }
-
public static class MyAlertDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
diff --git a/tests/input/src/com/android/tv/testinput/instrument/TestSetupInstrumentation.java b/tests/input/src/com/android/tv/testinput/instrument/TestSetupInstrumentation.java
index 379bce86..48e485c5 100644
--- a/tests/input/src/com/android/tv/testinput/instrument/TestSetupInstrumentation.java
+++ b/tests/input/src/com/android/tv/testinput/instrument/TestSetupInstrumentation.java
@@ -104,7 +104,7 @@ public class TestSetupInstrumentation extends Instrumentation {
throw new TestSetupException(
"Unknown " + TEST_SETUP_MODE_ARG + " of " + testSetupMode);
}
- TestTvInputSetupActivity.registerChannels(getContext(), mInputId, true, channelCount);
+ TestTvInputSetupActivity.registerChannels(getContext(), mInputId, channelCount);
}
}
diff --git a/tests/jank/Android.mk b/tests/jank/Android.mk
index 210a75ea..b71ea1b7 100644
--- a/tests/jank/Android.mk
+++ b/tests/jank/Android.mk
@@ -15,8 +15,6 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
ub-janktesthelper \
ub-uiautomator \
-LOCAL_JAVA_LIBRARIES := legacy-android-test
-
LOCAL_INSTRUMENTATION_FOR := LiveTv
LOCAL_SDK_VERSION := current
diff --git a/tests/jank/OWNERS b/tests/jank/OWNERS
new file mode 100644
index 00000000..4aa5fe52
--- /dev/null
+++ b/tests/jank/OWNERS
@@ -0,0 +1,2 @@
+nchalko@google.com
+shubang@google.com
diff --git a/tests/jank/src/com/android/tv/tests/jank/ChannelZappingJankTest.java b/tests/jank/src/com/android/tv/tests/jank/ChannelZappingJankTest.java
index b0463e71..ef936e32 100644
--- a/tests/jank/src/com/android/tv/tests/jank/ChannelZappingJankTest.java
+++ b/tests/jank/src/com/android/tv/tests/jank/ChannelZappingJankTest.java
@@ -15,20 +15,15 @@
*/
package com.android.tv.tests.jank;
-import android.content.res.Resources;
import android.support.test.filters.MediumTest;
import android.support.test.jank.GfxMonitor;
import android.support.test.jank.JankTest;
-import android.support.test.jank.JankTestBase;
-import android.support.test.uiautomator.UiDevice;
-
-import com.android.tv.testing.uihelper.LiveChannelsUiDeviceHelper;
/**
* Jank tests for channel zapping.
*/
@MediumTest
-public class ChannelZappingJankTest extends JankTestBase {
+public class ChannelZappingJankTest extends LiveChannelsTestCase {
private static final String TAG = "ChannelZappingJankTest";
private static final String STARTING_CHANNEL = "13";
@@ -45,16 +40,9 @@ public class ChannelZappingJankTest extends JankTestBase {
private static final int EXPECTED_FRAMES = 100;
private static final int WARM_UP_CHANNEL_ZAPPING_COUNT = 2;
- private UiDevice mDevice;
-
@Override
protected void setUp() throws Exception {
super.setUp();
- mDevice = UiDevice.getInstance(getInstrumentation());
- Resources targetResources = getInstrumentation().getTargetContext().getResources();
- LiveChannelsUiDeviceHelper liveChannelsHelper = new LiveChannelsUiDeviceHelper(mDevice,
- targetResources, getInstrumentation().getContext());
- liveChannelsHelper.assertAppStarted();
Utils.pressKeysForChannelNumber(STARTING_CHANNEL, mDevice);
}
diff --git a/tests/jank/src/com/android/tv/tests/jank/LiveChannelsTestCase.java b/tests/jank/src/com/android/tv/tests/jank/LiveChannelsTestCase.java
new file mode 100644
index 00000000..6de01036
--- /dev/null
+++ b/tests/jank/src/com/android/tv/tests/jank/LiveChannelsTestCase.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 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.tv.tests.jank;
+
+import android.content.res.Resources;
+import android.support.test.jank.JankTestBase;
+import android.support.test.uiautomator.UiDevice;
+
+import com.android.tv.testing.uihelper.LiveChannelsUiDeviceHelper;
+
+/**
+ * Base test case for LiveChannel jank tests.
+ */
+abstract class LiveChannelsTestCase extends JankTestBase {
+ protected UiDevice mDevice;
+ protected Resources mTargetResources;
+ protected LiveChannelsUiDeviceHelper mLiveChannelsHelper;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ mTargetResources = getInstrumentation().getTargetContext().getResources();
+ mLiveChannelsHelper = new LiveChannelsUiDeviceHelper(mDevice, mTargetResources,
+ getInstrumentation().getContext());
+ mLiveChannelsHelper.assertAppStarted();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // Destroys the activity to make sure next test case's activity launch check works well.
+ mLiveChannelsHelper.assertAppStopped();
+ super.tearDown();
+ }
+}
diff --git a/tests/jank/src/com/android/tv/tests/jank/MenuJankTest.java b/tests/jank/src/com/android/tv/tests/jank/MenuJankTest.java
index 47ebea3b..411a0bb9 100644
--- a/tests/jank/src/com/android/tv/tests/jank/MenuJankTest.java
+++ b/tests/jank/src/com/android/tv/tests/jank/MenuJankTest.java
@@ -15,21 +15,17 @@
*/
package com.android.tv.tests.jank;
-import android.content.res.Resources;
import android.support.test.filters.MediumTest;
import android.support.test.jank.GfxMonitor;
import android.support.test.jank.JankTest;
-import android.support.test.jank.JankTestBase;
-import android.support.test.uiautomator.UiDevice;
-import com.android.tv.testing.uihelper.LiveChannelsUiDeviceHelper;
import com.android.tv.testing.uihelper.MenuHelper;
/**
* Jank tests for the program guide.
*/
@MediumTest
-public class MenuJankTest extends JankTestBase {
+public class MenuJankTest extends LiveChannelsTestCase {
private static final String STARTING_CHANNEL = "1";
/**
@@ -42,22 +38,12 @@ public class MenuJankTest extends JankTestBase {
* @see <a href="http://go/janktesthelper-best-practices">Jank Test Helper Best Practices</a>
*/
private static final int EXPECTED_FRAMES = 200;
-
- protected UiDevice mDevice;
-
- protected Resources mTargetResources;
protected MenuHelper mMenuHelper;
- protected LiveChannelsUiDeviceHelper mLiveChannelsHelper;
@Override
protected void setUp() throws Exception {
super.setUp();
- mDevice = UiDevice.getInstance(getInstrumentation());
- mTargetResources = getInstrumentation().getTargetContext().getResources();
mMenuHelper = new MenuHelper(mDevice, mTargetResources);
- mLiveChannelsHelper = new LiveChannelsUiDeviceHelper(mDevice, mTargetResources,
- getInstrumentation().getContext());
- mLiveChannelsHelper.assertAppStarted();
Utils.pressKeysForChannelNumber(STARTING_CHANNEL, mDevice);
}
diff --git a/tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java b/tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java
index 7d751c4c..d8860dd7 100644
--- a/tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java
+++ b/tests/jank/src/com/android/tv/tests/jank/ProgramGuideJankTest.java
@@ -17,29 +17,21 @@ package com.android.tv.tests.jank;
import static com.android.tv.testing.uihelper.UiDeviceAsserts.assertWaitForCondition;
-import android.content.res.Resources;
import android.support.test.filters.MediumTest;
import android.support.test.jank.GfxMonitor;
import android.support.test.jank.JankTest;
-import android.support.test.jank.JankTestBase;
-import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
import com.android.tv.R;
import com.android.tv.testing.uihelper.ByResource;
import com.android.tv.testing.uihelper.Constants;
-import com.android.tv.testing.uihelper.LiveChannelsUiDeviceHelper;
import com.android.tv.testing.uihelper.MenuHelper;
-import com.android.tv.testing.uihelper.UiDeviceUtils;
/**
* Jank tests for the program guide.
*/
@MediumTest
-public class ProgramGuideJankTest extends JankTestBase {
- private static final boolean DEBUG = false;
- private static final String TAG = "ProgramGuideJank";
-
+public class ProgramGuideJankTest extends LiveChannelsTestCase {
private static final String STARTING_CHANNEL = "13";
/**
@@ -53,20 +45,12 @@ public class ProgramGuideJankTest extends JankTestBase {
*/
private static final int EXPECTED_FRAMES = 200;
- private UiDevice mDevice;
-
- private Resources mTargetResources;
private MenuHelper mMenuHelper;
@Override
protected void setUp() throws Exception {
super.setUp();
- mDevice = UiDevice.getInstance(getInstrumentation());
- mTargetResources = getInstrumentation().getTargetContext().getResources();
mMenuHelper = new MenuHelper(mDevice, mTargetResources);
- LiveChannelsUiDeviceHelper liveChannelsHelper = new LiveChannelsUiDeviceHelper(mDevice,
- mTargetResources, getInstrumentation().getContext());
- liveChannelsHelper.assertAppStarted();
Utils.pressKeysForChannelNumber(STARTING_CHANNEL, mDevice);
}
@@ -83,7 +67,7 @@ public class ProgramGuideJankTest extends JankTestBase {
}
@JankTest(expectedFrames = EXPECTED_FRAMES,
- beforeLoop = "showProgramGuide",
+ beforeLoop = "showAndFocusProgramGuide",
afterLoop = "clearProgramGuide")
@GfxMonitor(processName = Utils.LIVE_CHANNELS_PROCESS_NAME)
public void testScrollDown() {
@@ -95,7 +79,7 @@ public class ProgramGuideJankTest extends JankTestBase {
}
@JankTest(expectedFrames = EXPECTED_FRAMES,
- beforeLoop = "showProgramGuide",
+ beforeLoop = "showAndFocusProgramGuide",
afterLoop = "clearProgramGuide")
@GfxMonitor(processName = Utils.LIVE_CHANNELS_PROCESS_NAME)
public void testScrollRight() {
@@ -128,11 +112,17 @@ public class ProgramGuideJankTest extends JankTestBase {
assertWaitForCondition(mDevice, Until.gone(Constants.PROGRAM_GUIDE));
}
- // It's public to be used with @JankTest annotation.
public void showProgramGuide() {
selectProgramGuideMenuItem();
mDevice.pressDPadCenter();
assertWaitForCondition(mDevice, Until.hasObject(Constants.PROGRAM_GUIDE));
+ }
+
+ // It's public to be used with @JankTest annotation.
+ public void showAndFocusProgramGuide() {
+ selectProgramGuideMenuItem();
+ mDevice.pressDPadCenter();
+ assertWaitForCondition(mDevice, Until.hasObject(Constants.PROGRAM_GUIDE));
// If the side panel grid is visible (and thus has focus), move right to clear it.
if (mDevice.hasObject(
ByResource.id(mTargetResources, R.id.program_guide_side_panel_grid_view))) {
diff --git a/tests/unit/Android.mk b/tests/unit/Android.mk
index f53220de..3632fe94 100644
--- a/tests/unit/Android.mk
+++ b/tests/unit/Android.mk
@@ -12,7 +12,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
mockito-target \
tv-test-common \
-LOCAL_JAVA_LIBRARIES := android.test.mock.sdk legacy-android-test
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../common/res
LOCAL_PACKAGE_NAME := TVUnitTests
@@ -22,3 +23,4 @@ LOCAL_SDK_VERSION := system_current
LOCAL_MIN_SDK_VERSION := 23 # M
include $(BUILD_PACKAGE)
+
diff --git a/tests/unit/AndroidManifest.xml b/tests/unit/AndroidManifest.xml
index aebb3772..d073f8ac 100644
--- a/tests/unit/AndroidManifest.xml
+++ b/tests/unit/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tv.tests" >
- <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21" />
+ <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="23" />
<instrumentation
android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/unit/OWNERS b/tests/unit/OWNERS
new file mode 100644
index 00000000..4aa5fe52
--- /dev/null
+++ b/tests/unit/OWNERS
@@ -0,0 +1,2 @@
+nchalko@google.com
+shubang@google.com
diff --git a/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java b/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java
index e2f620ed..e6f1af7e 100644
--- a/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java
+++ b/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java
@@ -15,9 +15,11 @@
*/
package com.android.tv;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+
import android.content.Context;
import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase2;
+import android.support.test.rule.ActivityTestRule;
import android.text.TextUtils;
import com.android.tv.data.Channel;
@@ -28,41 +30,40 @@ import com.android.tv.testing.testinput.TestInputControlConnection;
import com.android.tv.testing.testinput.TestInputControlUtils;
import com.android.tv.testing.testinput.TvTestInputConstants;
+import org.junit.Before;
+import org.junit.Rule;
+
import java.util.List;
/**
* Base TestCase for tests that need a {@link MainActivity}.
*/
-public abstract class BaseMainActivityTestCase
- extends ActivityInstrumentationTestCase2<MainActivity> {
+public abstract class BaseMainActivityTestCase {
private static final String TAG = "BaseMainActivityTest";
private static final int CHANNEL_LOADING_CHECK_INTERVAL_MS = 10;
+ @Rule
+ public ActivityTestRule<MainActivity> mActivityTestRule =
+ new ActivityTestRule<>(MainActivity.class);
+
protected final TestInputControlConnection mConnection = new TestInputControlConnection();
protected MainActivity mActivity;
- public BaseMainActivityTestCase(Class<MainActivity> activityClass) {
- super(activityClass);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
+ mActivity = mActivityTestRule.getActivity();
// TODO: ensure the SampleInputs are setup.
- setActivityInitialTouchMode(false);
- mActivity = getActivity();
- getInstrumentation().getContext()
+ getInstrumentation().getTargetContext()
.bindService(TestInputControlUtils.createIntent(), mConnection,
Context.BIND_AUTO_CREATE);
}
- @Override
- protected void tearDown() throws Exception {
+ @Before
+ public void tearDown() {
if (mConnection.isBound()) {
- getInstrumentation().getContext().unbindService(mConnection);
+ getInstrumentation().getTargetContext().unbindService(mConnection);
}
- super.tearDown();
}
/**
@@ -72,16 +73,12 @@ public abstract class BaseMainActivityTestCase
*/
protected void tuneToChannel(final Channel channel) {
// Run on UI thread so views can be modified
- try {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mActivity.tuneToChannel(channel);
- }
- });
- } catch (Throwable throwable) {
- throw new RuntimeException(throwable);
- }
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mActivity.tuneToChannel(channel);
+ }
+ });
}
/**
@@ -130,13 +127,17 @@ public abstract class BaseMainActivityTestCase
private Channel findChannelWithName(String displayName) {
waitUntilChannelLoadingFinish();
- List<Channel> channelList = mActivity.getChannelDataManager().getChannelList();
+ Channel channel = null;
+ List <Channel> channelList = mActivity.getChannelDataManager().getChannelList();
for (Channel c : channelList) {
if (TextUtils.equals(c.getDisplayName(), displayName)) {
- return c;
+ channel = c;
+ break;
}
}
- throw new AssertionError("'" + displayName + "' channel not found");
+ if (channel == null) {
+ throw new AssertionError("'" + displayName + "' channel not found");
+ }
+ return channel;
}
-
}
diff --git a/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java b/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
index 899083f3..f2917181 100644
--- a/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
+++ b/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java
@@ -18,33 +18,37 @@ package com.android.tv;
import static com.android.tv.TimeShiftManager.INVALID_TIME;
import static com.android.tv.TimeShiftManager.REQUEST_TIMEOUT_MS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.MediumTest;
-import android.test.UiThreadTest;
+
+import org.junit.Before;
+import org.junit.Test;
@MediumTest
public class CurrentPositionMediatorTest extends BaseMainActivityTestCase {
private TimeShiftManager.CurrentPositionMediator mMediator;
- public CurrentPositionMediatorTest() {
- super(MainActivity.class);
- }
-
@Override
- protected void setUp() throws Exception {
+ @Before
+ public void setUp() {
super.setUp();
mMediator = mActivity.getTimeShiftManager().mCurrentPositionMediator;
}
@UiThreadTest
- public void testInitialize() throws Throwable {
+ @Test
+ public void testInitialize() {
long currentTimeMs = System.currentTimeMillis();
mMediator.initialize(currentTimeMs);
assertCurrentPositionMediator(INVALID_TIME, currentTimeMs);
}
@UiThreadTest
- public void testOnSeekRequested() throws Throwable {
+ @Test
+ public void testOnSeekRequested() {
long seekToTimeMs = System.currentTimeMillis() - REQUEST_TIMEOUT_MS * 3;
mMediator.onSeekRequested(seekToTimeMs);
assertNotSame("Seek request time", INVALID_TIME, mMediator.mSeekRequestTimeMs);
@@ -52,7 +56,8 @@ public class CurrentPositionMediatorTest extends BaseMainActivityTestCase {
}
@UiThreadTest
- public void testOnCurrentPositionChangedInvalidInput() throws Throwable {
+ @Test
+ public void testOnCurrentPositionChangedInvalidInput() {
long seekToTimeMs = System.currentTimeMillis() - REQUEST_TIMEOUT_MS * 3;
long newCurrentTimeMs = seekToTimeMs + REQUEST_TIMEOUT_MS;
mMediator.onSeekRequested(seekToTimeMs);
@@ -63,7 +68,8 @@ public class CurrentPositionMediatorTest extends BaseMainActivityTestCase {
}
@UiThreadTest
- public void testOnCurrentPositionChangedValidInput() throws Throwable {
+ @Test
+ public void testOnCurrentPositionChangedValidInput() {
long seekToTimeMs = System.currentTimeMillis() - REQUEST_TIMEOUT_MS * 3;
long newCurrentTimeMs = seekToTimeMs + REQUEST_TIMEOUT_MS - 1;
mMediator.onSeekRequested(seekToTimeMs);
diff --git a/tests/unit/src/com/android/tv/FeaturesTest.java b/tests/unit/src/com/android/tv/FeaturesTest.java
index 644c4248..9d61e757 100644
--- a/tests/unit/src/com/android/tv/FeaturesTest.java
+++ b/tests/unit/src/com/android/tv/FeaturesTest.java
@@ -16,19 +16,21 @@
package com.android.tv;
+import static org.junit.Assert.assertFalse;
+
import android.support.test.filters.SmallTest;
-import junit.framework.TestCase;
+import org.junit.Test;
/**
* Test for features.
*/
@SmallTest
-public class FeaturesTest extends TestCase {
-
+public class FeaturesTest {
+ @Test
public void testPropertyFeatureKeyLength() {
// This forces the class to be loaded and verifies all PropertyFeature key lengths.
// If any keys are too long the test will fail to load.
- assertEquals(false, Features.TEST_FEATURE.isEnabled(null));
+ assertFalse(Features.TEST_FEATURE.isEnabled(null));
}
}
diff --git a/tests/unit/src/com/android/tv/MainActivityTest.java b/tests/unit/src/com/android/tv/MainActivityTest.java
index b2fe6745..15805032 100644
--- a/tests/unit/src/com/android/tv/MainActivityTest.java
+++ b/tests/unit/src/com/android/tv/MainActivityTest.java
@@ -15,6 +15,10 @@
*/
package com.android.tv;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import android.support.test.filters.MediumTest;
import android.view.View;
import android.widget.TextView;
@@ -23,6 +27,8 @@ import com.android.tv.data.Channel;
import com.android.tv.testing.testinput.TvTestInputConstants;
import com.android.tv.ui.ChannelBannerView;
+import org.junit.Test;
+
import java.util.List;
/**
@@ -30,25 +36,22 @@ import java.util.List;
*/
@MediumTest
public class MainActivityTest extends BaseMainActivityTestCase {
-
- public MainActivityTest() {
- super(MainActivity.class);
- }
-
+ @Test
public void testInitialConditions() {
waitUntilChannelLoadingFinish();
List<Channel> channelList = mActivity.getChannelDataManager().getChannelList();
assertTrue("Expected at least one channel", channelList.size() > 0);
- assertFalse("PIP disabled", mActivity.isPipEnabled());
}
- public void testTuneToChannel() throws Throwable {
+ @Test
+ public void testTuneToChannel() {
tuneToChannel(TvTestInputConstants.CH_2);
assertChannelBannerShown(true);
assertChannelName(TvTestInputConstants.CH_2.name);
}
- public void testShowProgramGuide() throws Throwable {
+ @Test
+ public void testShowProgramGuide() {
tuneToChannel(TvTestInputConstants.CH_2);
showProgramGuide();
getInstrumentation().waitForIdleSync();
@@ -56,7 +59,7 @@ public class MainActivityTest extends BaseMainActivityTestCase {
assertProgramGuide(true);
}
- private void showProgramGuide() throws Throwable {
+ private void showProgramGuide() {
// Run on UI thread so views can be modified
getInstrumentation().runOnMainSync(new Runnable() {
@Override
@@ -81,7 +84,7 @@ public class MainActivityTest extends BaseMainActivityTestCase {
}
private View assertExpectedBannerSceneClassShown(Class<ChannelBannerView> expectedClass,
- boolean expectedShown) throws AssertionError {
+ boolean expectedShown) {
View v = assertViewIsShown(expectedClass.getSimpleName(), R.id.scene_transition_common,
expectedShown);
if (v != null) {
@@ -90,8 +93,7 @@ public class MainActivityTest extends BaseMainActivityTestCase {
return v;
}
- private View assertViewIsShown(String viewName, int viewId, boolean expected)
- throws AssertionError {
+ private View assertViewIsShown(String viewName, int viewId, boolean expected) {
View view = mActivity.findViewById(viewId);
if (view == null) {
if (expected) {
@@ -103,5 +105,4 @@ public class MainActivityTest extends BaseMainActivityTestCase {
assertEquals(viewName + " shown", expected, view.isShown());
return view;
}
-
}
diff --git a/tests/unit/src/com/android/tv/TimeShiftManagerTest.java b/tests/unit/src/com/android/tv/TimeShiftManagerTest.java
index f7c6f622..052b5d19 100644
--- a/tests/unit/src/com/android/tv/TimeShiftManagerTest.java
+++ b/tests/unit/src/com/android/tv/TimeShiftManagerTest.java
@@ -22,23 +22,25 @@ import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_JUMP_TO_PREVI
import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_PAUSE;
import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_PLAY;
import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_REWIND;
+import static org.junit.Assert.assertEquals;
import android.support.test.filters.MediumTest;
+import org.junit.Before;
+import org.junit.Test;
+
@MediumTest
public class TimeShiftManagerTest extends BaseMainActivityTestCase {
private TimeShiftManager mTimeShiftManager;
- public TimeShiftManagerTest() {
- super(MainActivity.class);
- }
-
@Override
- protected void setUp() throws Exception {
+ @Before
+ public void setUp() {
super.setUp();
mTimeShiftManager = mActivity.getTimeShiftManager();
}
+ @Test
public void testDisableActions() {
enableAllActions(true);
assertActionState(true, true, true, true, true, true);
@@ -56,6 +58,7 @@ public class TimeShiftManagerTest extends BaseMainActivityTestCase {
assertActionState(false, false, false, false, false, false);
}
+ @Test
public void testEnableActions() {
enableAllActions(false);
assertActionState(false, false, false, false, false, false);
diff --git a/tests/unit/src/com/android/tv/common/TvContentRatingCacheTest.java b/tests/unit/src/com/android/tv/common/TvContentRatingCacheTest.java
deleted file mode 100644
index eadc50d5..00000000
--- a/tests/unit/src/com/android/tv/common/TvContentRatingCacheTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.common;
-
-import android.content.ComponentCallbacks2;
-import android.media.tv.TvContentRating;
-import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
-import android.test.MoreAsserts;
-
-import com.android.tv.testing.TvContentRatingConstants;
-import com.android.tv.util.Utils;
-
-/**
- * Test for {@link android.media.tv.TvContentRating} tests in {@link Utils}.
- */
-@SmallTest
-public class TvContentRatingCacheTest extends AndroidTestCase {
-
- /**
- * US_TV_MA and US_TV_Y7 in order
- */
- public static final String MA_AND_Y7 = TvContentRatingConstants.STRING_US_TV_MA + ","
- + TvContentRatingConstants.STRING_US_TV_Y7_US_TV_FV;
-
- /**
- * US_TV_MA and US_TV_Y7 not in order
- */
- public static final String Y7_AND_MA = TvContentRatingConstants.STRING_US_TV_Y7_US_TV_FV + ","
- + TvContentRatingConstants.STRING_US_TV_MA;
- final TvContentRatingCache mCache = TvContentRatingCache.getInstance();
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mCache.performTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
- }
-
- @Override
- protected void tearDown() throws Exception {
- mCache.performTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
- super.tearDown();
- }
-
- public void testGetRatings_US_TV_MA() {
- TvContentRating[] result = mCache.getRatings(TvContentRatingConstants.STRING_US_TV_MA);
- MoreAsserts.assertEquals(asArray(TvContentRatingConstants.CONTENT_RATING_US_TV_MA), result);
- }
-
- public void testGetRatings_US_TV_MA_same() {
- TvContentRating[] first = mCache.getRatings(TvContentRatingConstants.STRING_US_TV_MA);
- TvContentRating[] second = mCache.getRatings(TvContentRatingConstants.STRING_US_TV_MA);
- assertSame(first, second);
- }
-
- public void testGetRatings_US_TV_MA_diffAfterClear() {
- TvContentRating[] first = mCache.getRatings(TvContentRatingConstants.STRING_US_TV_MA);
- mCache.performTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
- TvContentRating[] second = mCache.getRatings(TvContentRatingConstants.STRING_US_TV_MA);
- assertNotSame(first, second);
- }
-
- public void testGetRatings_TWO_orderDoesNotMatter() {
- TvContentRating[] first = mCache.getRatings(MA_AND_Y7);
- TvContentRating[] second = mCache.getRatings(Y7_AND_MA);
- assertSame(first, second);
- }
-
- public void testContentRatingsToString_null() {
- String result = TvContentRatingCache.contentRatingsToString(null);
- assertEquals("ratings string", null, result);
- }
-
- public void testContentRatingsToString_none() {
- String result = TvContentRatingCache.contentRatingsToString(asArray());
- assertEquals("ratings string", null, result);
- }
-
- public void testContentRatingsToString_one() {
- String result = TvContentRatingCache
- .contentRatingsToString(asArray(TvContentRatingConstants.CONTENT_RATING_US_TV_MA));
- assertEquals("ratings string", TvContentRatingConstants.STRING_US_TV_MA, result);
- }
-
- public void testContentRatingsToString_twoInOrder() {
- String result = TvContentRatingCache.contentRatingsToString(
- asArray(TvContentRatingConstants.CONTENT_RATING_US_TV_MA,
- TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV));
- assertEquals("ratings string", MA_AND_Y7, result);
- }
-
- public void testContentRatingsToString_twoNotInOrder() {
- String result = TvContentRatingCache.contentRatingsToString(asArray(
- TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV,
- TvContentRatingConstants.CONTENT_RATING_US_TV_MA));
- assertEquals("ratings string", MA_AND_Y7, result);
- }
-
- public void testContentRatingsToString_double() {
- String result = TvContentRatingCache.contentRatingsToString(asArray(
- TvContentRatingConstants.CONTENT_RATING_US_TV_MA,
- TvContentRatingConstants.CONTENT_RATING_US_TV_MA));
- assertEquals("ratings string", TvContentRatingConstants.STRING_US_TV_MA, result);
- }
-
- public void testStringToContentRatings_null() {
- assertNull(TvContentRatingCache.stringToContentRatings(null));
- }
-
- public void testStringToContentRatings_none() {
- assertNull(TvContentRatingCache.stringToContentRatings(""));
- }
-
- public void testStringToContentRatings_bad() {
- assertNull(TvContentRatingCache.stringToContentRatings("bad"));
- }
-
- public void testStringToContentRatings_oneGoodOneBad() {
- TvContentRating[] results = TvContentRatingCache
- .stringToContentRatings(TvContentRatingConstants.STRING_US_TV_Y7_US_TV_FV + ",bad");
- MoreAsserts.assertEquals("ratings",
- asArray(TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV), results);
- }
-
- public void testStringToContentRatings_one() {
- TvContentRating[] results = TvContentRatingCache
- .stringToContentRatings(TvContentRatingConstants.STRING_US_TV_Y7_US_TV_FV);
- MoreAsserts.assertEquals("ratings",
- asArray(TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV), results);
- }
-
- public void testStringToContentRatings_twoNotInOrder() {
- TvContentRating[] results = TvContentRatingCache.stringToContentRatings(Y7_AND_MA);
- MoreAsserts.assertEquals("ratings",
- asArray(TvContentRatingConstants.CONTENT_RATING_US_TV_MA,
- TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV), results);
- }
-
- public void testStringToContentRatings_twoInOrder() {
- TvContentRating[] results = TvContentRatingCache.stringToContentRatings(MA_AND_Y7);
- MoreAsserts.assertEquals("ratings",
- asArray(TvContentRatingConstants.CONTENT_RATING_US_TV_MA,
- TvContentRatingConstants.CONTENT_RATING_US_TV_Y7_US_TV_FV), results);
- }
-
- public void testStringToContentRatings_double() {
- TvContentRating[] results = TvContentRatingCache.stringToContentRatings(
- TvContentRatingConstants.STRING_US_TV_MA + ","
- + TvContentRatingConstants.STRING_US_TV_MA);
- MoreAsserts
- .assertEquals("ratings", asArray(TvContentRatingConstants.CONTENT_RATING_US_TV_MA),
- results);
- }
-
- private static TvContentRating[] asArray(TvContentRating... ratings) {
- return ratings;
- }
-}
diff --git a/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java b/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
index 9f9ada1f..7a4a4982 100644
--- a/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
+++ b/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java
@@ -16,6 +16,12 @@
package com.android.tv.data;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -26,9 +32,7 @@ import android.media.tv.TvContract;
import android.media.tv.TvContract.Channels;
import android.net.Uri;
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
import android.test.MoreAsserts;
-import android.test.UiThreadTest;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.test.mock.MockCursor;
@@ -38,9 +42,11 @@ import android.util.SparseArray;
import com.android.tv.testing.ChannelInfo;
import com.android.tv.testing.Constants;
-import com.android.tv.testing.Utils;
import com.android.tv.util.TvInputManagerHelper;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;
@@ -57,14 +63,13 @@ import java.util.concurrent.TimeUnit;
* Note that all the methods of {@link ChannelDataManager} should be called from the UI thread.
*/
@SmallTest
-public class ChannelDataManagerTest extends AndroidTestCase {
+public class ChannelDataManagerTest {
private static final boolean DEBUG = false;
private static final String TAG = "ChannelDataManagerTest";
// Wait time for expected success.
private static final long WAIT_TIME_OUT_MS = 1000L;
private static final String DUMMY_INPUT_ID = "dummy";
- // TODO: Use Channels.COLUMN_BROWSABLE and Channels.COLUMN_LOCKED instead.
private static final String COLUMN_BROWSABLE = "browsable";
private static final String COLUMN_LOCKED = "locked";
@@ -73,51 +78,59 @@ public class ChannelDataManagerTest extends AndroidTestCase {
private FakeContentResolver mContentResolver;
private FakeContentProvider mContentProvider;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
assertTrue("More than 2 channels to test", Constants.UNIT_TEST_CHANNEL_COUNT > 2);
- mContentProvider = new FakeContentProvider(getContext());
+ mContentProvider = new FakeContentProvider(getTargetContext());
mContentResolver = new FakeContentResolver();
mContentResolver.addProvider(TvContract.AUTHORITY, mContentProvider);
mListener = new TestChannelDataManagerListener();
- Utils.runOnMainSync(new Runnable() {
+ getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
TvInputManagerHelper mockHelper = Mockito.mock(TvInputManagerHelper.class);
Mockito.when(mockHelper.hasTvInputInfo(Matchers.anyString())).thenReturn(true);
- mChannelDataManager = new ChannelDataManager(getContext(), mockHelper,
+ mChannelDataManager = new ChannelDataManager(getTargetContext(), mockHelper,
mContentResolver);
mChannelDataManager.addListener(mListener);
}
});
}
- @Override
- protected void tearDown() throws Exception {
- Utils.runOnMainSync(new Runnable() {
+ @After
+ public void tearDown() {
+ getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
mChannelDataManager.stop();
}
});
- super.tearDown();
}
- private void startAndWaitForComplete() throws Exception {
- mChannelDataManager.start();
+ private void startAndWaitForComplete() throws InterruptedException {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mChannelDataManager.start();
+ }
+ });
assertTrue(mListener.loadFinishedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
}
- private void restart() throws Exception {
- mChannelDataManager.stop();
- mListener.reset();
+ private void restart() throws InterruptedException {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mChannelDataManager.stop();
+ mListener.reset();
+ }
+ });
startAndWaitForComplete();
}
- @UiThreadTest
- public void testIsDbLoadFinished() throws Exception {
+ @Test
+ public void testIsDbLoadFinished() throws InterruptedException {
startAndWaitForComplete();
assertTrue(mChannelDataManager.isDbLoadFinished());
}
@@ -128,8 +141,8 @@ public class ChannelDataManagerTest extends AndroidTestCase {
* - {@link ChannelDataManager#getChannelList}
* - {@link ChannelDataManager#getChannel}
*/
- @UiThreadTest
- public void testGetChannels() throws Exception {
+ @Test
+ public void testGetChannels() throws InterruptedException {
startAndWaitForComplete();
// Test {@link ChannelDataManager#getChannelCount}
@@ -138,7 +151,7 @@ public class ChannelDataManagerTest extends AndroidTestCase {
// Test {@link ChannelDataManager#getChannelList}
List<ChannelInfo> channelInfoList = new ArrayList<>();
for (int i = 1; i <= Constants.UNIT_TEST_CHANNEL_COUNT; i++) {
- channelInfoList.add(ChannelInfo.create(getContext(), i));
+ channelInfoList.add(ChannelInfo.create(getTargetContext(), i));
}
List<Channel> channelList = mChannelDataManager.getChannelList();
for (Channel channel : channelList) {
@@ -163,8 +176,8 @@ public class ChannelDataManagerTest extends AndroidTestCase {
/**
* Test for {@link ChannelDataManager#getChannelCount} when no channel is available.
*/
- @UiThreadTest
- public void testGetChannels_noChannels() throws Exception {
+ @Test
+ public void testGetChannels_noChannels() throws InterruptedException {
mContentProvider.clear();
startAndWaitForComplete();
assertEquals(0, mChannelDataManager.getChannelCount());
@@ -175,12 +188,12 @@ public class ChannelDataManagerTest extends AndroidTestCase {
* - {@link ChannelDataManager#updateBrowsable}
* - {@link ChannelDataManager#applyUpdatedValuesToDb}
*/
- @UiThreadTest
- public void testBrowsable() throws Exception {
+ @Test
+ public void testBrowsable() throws InterruptedException {
startAndWaitForComplete();
// Test if all channels are browsable
- List<Channel> channelList = new ArrayList<>(mChannelDataManager.getChannelList());
+ List<Channel> channelList = mChannelDataManager.getChannelList();
List<Channel> browsableChannelList = mChannelDataManager.getBrowsableChannelList();
for (Channel browsableChannel : browsableChannelList) {
boolean found = channelList.remove(browsableChannel);
@@ -189,9 +202,10 @@ public class ChannelDataManagerTest extends AndroidTestCase {
assertEquals(0, channelList.size());
// Prepare for next tests.
+ channelList = mChannelDataManager.getChannelList();
TestChannelDataManagerChannelListener channelListener =
new TestChannelDataManagerChannelListener();
- Channel channel1 = mChannelDataManager.getChannelList().get(0);
+ Channel channel1 = channelList.get(0);
mChannelDataManager.addChannelListener(channel1.getId(), channelListener);
// Test {@link ChannelDataManager#updateBrowsable} & notification.
@@ -216,15 +230,16 @@ public class ChannelDataManagerTest extends AndroidTestCase {
* - {@link ChannelDataManager#updateBrowsable}
* - {@link ChannelDataManager#applyUpdatedValuesToDb}
*/
- @UiThreadTest
- public void testBrowsable_skipNotification() throws Exception {
+ @Test
+ public void testBrowsable_skipNotification() throws InterruptedException {
startAndWaitForComplete();
+ List<Channel> channels = mChannelDataManager.getChannelList();
// Prepare for next tests.
TestChannelDataManagerChannelListener channelListener =
new TestChannelDataManagerChannelListener();
- Channel channel1 = mChannelDataManager.getChannelList().get(0);
- Channel channel2 = mChannelDataManager.getChannelList().get(1);
+ Channel channel1 = channels.get(0);
+ Channel channel2 = channels.get(1);
mChannelDataManager.addChannelListener(channel1.getId(), channelListener);
mChannelDataManager.addChannelListener(channel2.getId(), channelListener);
@@ -252,8 +267,8 @@ public class ChannelDataManagerTest extends AndroidTestCase {
* - {@link ChannelDataManager#updateLocked}
* - {@link ChannelDataManager#applyUpdatedValuesToDb}
*/
- @UiThreadTest
- public void testLocked() throws Exception {
+ @Test
+ public void testLocked() throws InterruptedException {
startAndWaitForComplete();
// Test if all channels aren't locked at the first time.
@@ -283,14 +298,14 @@ public class ChannelDataManagerTest extends AndroidTestCase {
/**
* Test ChannelDataManager when channels in TvContract are updated, removed, or added.
*/
- @UiThreadTest
- public void testChannelListChanged() throws Exception {
+ @Test
+ public void testChannelListChanged() throws InterruptedException {
startAndWaitForComplete();
// Test channel add.
mListener.reset();
long testChannelId = Constants.UNIT_TEST_CHANNEL_COUNT + 1;
- ChannelInfo testChannelInfo = ChannelInfo.create(getContext(), (int) testChannelId);
+ ChannelInfo testChannelInfo = ChannelInfo.create(getTargetContext(), (int) testChannelId);
testChannelId = Constants.UNIT_TEST_CHANNEL_COUNT + 1;
mContentProvider.simulateInsert(testChannelInfo);
assertTrue(
@@ -376,7 +391,7 @@ public class ChannelDataManagerTest extends AndroidTestCase {
super(context);
for (int i = 1; i <= Constants.UNIT_TEST_CHANNEL_COUNT; i++) {
mChannelInfoList.put(i,
- new ChannelInfoWrapper(ChannelInfo.create(getContext(), i)));
+ new ChannelInfoWrapper(ChannelInfo.create(getTargetContext(), i)));
}
}
@@ -466,8 +481,8 @@ public class ChannelDataManagerTest extends AndroidTestCase {
*/
public void simulateInsert(ChannelInfo testChannelInfo) {
long channelId = testChannelInfo.originalNetworkId;
- mChannelInfoList.put((int) channelId,
- new ChannelInfoWrapper(ChannelInfo.create(getContext(), (int) channelId)));
+ mChannelInfoList.put((int) channelId, new ChannelInfoWrapper(
+ ChannelInfo.create(getTargetContext(), (int) channelId)));
mContentResolver.notifyChange(TvContract.buildChannelUri(channelId), null);
}
diff --git a/tests/unit/src/com/android/tv/data/ChannelNumberTest.java b/tests/unit/src/com/android/tv/data/ChannelNumberTest.java
index 4e6e9f3c..827dcdbd 100644
--- a/tests/unit/src/com/android/tv/data/ChannelNumberTest.java
+++ b/tests/unit/src/com/android/tv/data/ChannelNumberTest.java
@@ -16,22 +16,24 @@
package com.android.tv.data;
import static com.android.tv.data.ChannelNumber.parseChannelNumber;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import android.support.test.filters.SmallTest;
import com.android.tv.testing.ComparableTester;
-import junit.framework.TestCase;
+import org.junit.Test;
/**
* Tests for {@link ChannelNumber}.
*/
@SmallTest
-public class ChannelNumberTest extends TestCase {
-
+public class ChannelNumberTest {
/**
* Test method for {@link ChannelNumber#ChannelNumber()}.
*/
+ @Test
public void testChannelNumber() {
assertChannelEquals(new ChannelNumber(), "", false, "");
}
@@ -40,32 +42,32 @@ public class ChannelNumberTest extends TestCase {
* Test method for
* {@link com.android.tv.data.ChannelNumber#parseChannelNumber(java.lang.String)}.
*/
+ @Test
public void testParseChannelNumber() {
assertNull(parseChannelNumber(""));
- assertNull(parseChannelNumber(" "));
+ assertNull(parseChannelNumber("-"));
assertNull(parseChannelNumber("abcd12"));
assertNull(parseChannelNumber("12abcd"));
assertNull(parseChannelNumber("-12"));
assertChannelEquals(parseChannelNumber("1"), "1", false, "");
- assertChannelEquals(parseChannelNumber("1234 4321"), "1234", true, "4321");
+ assertChannelEquals(parseChannelNumber("1234-4321"), "1234", true, "4321");
assertChannelEquals(parseChannelNumber("3-4"), "3", true, "4");
- assertChannelEquals(parseChannelNumber("5.6"), "5", true, "6");
+ assertChannelEquals(parseChannelNumber("5-6"), "5", true, "6");
}
/**
* Test method for {@link ChannelNumber#compareTo(com.android.tv.data.ChannelNumber)}.
*/
+ @Test
public void testCompareTo() {
new ComparableTester<ChannelNumber>()
.addEquivalentGroup(parseChannelNumber("1"), parseChannelNumber("1"))
.addEquivalentGroup(parseChannelNumber("2"))
- .addEquivalentGroup(parseChannelNumber("2 1"), parseChannelNumber("2.1"),
- parseChannelNumber("2-1"))
+ .addEquivalentGroup(parseChannelNumber("2-1"))
.addEquivalentGroup(parseChannelNumber("2-2"))
.addEquivalentGroup(parseChannelNumber("2-10"))
.addEquivalentGroup(parseChannelNumber("3"))
- .addEquivalentGroup(parseChannelNumber("4"), parseChannelNumber("4 0"),
- parseChannelNumber("4.0"), parseChannelNumber("4-0"))
+ .addEquivalentGroup(parseChannelNumber("4"), parseChannelNumber("4-0"))
.addEquivalentGroup(parseChannelNumber("10"))
.addEquivalentGroup(parseChannelNumber("100"))
.test();
@@ -74,6 +76,7 @@ public class ChannelNumberTest extends TestCase {
/**
* Test method for {@link ChannelNumber#compare(java.lang.String, java.lang.String)}.
*/
+ @Test
public void testCompare() {
// Only need to test nulls, the reset is tested by testCompareTo
assertEquals("compareTo(null,null)", 0, ChannelNumber.compare(null, null));
diff --git a/tests/unit/src/com/android/tv/data/ChannelTest.java b/tests/unit/src/com/android/tv/data/ChannelTest.java
index 95e3ee90..d270e277 100644
--- a/tests/unit/src/com/android/tv/data/ChannelTest.java
+++ b/tests/unit/src/com/android/tv/data/ChannelTest.java
@@ -16,17 +16,21 @@
package com.android.tv.data;
+import static org.junit.Assert.assertEquals;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
import com.android.tv.testing.ComparatorTester;
import com.android.tv.util.TvInputManagerHelper;
+import org.junit.Before;
+import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
@@ -38,7 +42,7 @@ import java.util.Comparator;
* Tests for {@link Channel}.
*/
@SmallTest
-public class ChannelTest extends AndroidTestCase {
+public class ChannelTest {
// Used for testing TV inputs with invalid input package. This could happen when a TV input is
// uninstalled while drawing an app link card.
private static final String INVALID_TV_INPUT_PACKAGE_NAME =
@@ -59,9 +63,8 @@ public class ChannelTest extends AndroidTestCase {
private Intent mInvalidIntent;
private Intent mValidIntent;
- @Override
- public void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws NameNotFoundException {
mInvalidIntent = new Intent(Intent.ACTION_VIEW);
mInvalidIntent.setComponent(new ComponentName(INVALID_TV_INPUT_PACKAGE_NAME, ".test"));
mValidIntent = new Intent(Intent.ACTION_VIEW);
@@ -103,6 +106,7 @@ public class ChannelTest extends AndroidTestCase {
Mockito.when(mMockContext.getPackageManager()).thenReturn(mockPackageManager);
}
+ @Test
public void testGetAppLinkType_NoText_NoIntent() {
assertAppLinkType(Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME, null, null);
assertAppLinkType(Channel.APP_LINK_TYPE_NONE, LIVE_CHANNELS_PACKAGE_NAME, null, null);
@@ -226,7 +230,6 @@ public class ChannelTest extends AndroidTestCase {
* See <a href="http://b/23031603">b/23031603</a>.
*/
public void testComparatorLabel() {
-
TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class);
Mockito.when(manager.isPartnerInput(Matchers.anyString())).thenAnswer(
new Answer<Boolean>() {
@@ -254,6 +257,29 @@ public class ChannelTest extends AndroidTestCase {
comparatorTester.test();
}
+ public void testNormalizeChannelNumber() {
+ assertNormalizedDisplayNumber(null, null);
+ assertNormalizedDisplayNumber("", "");
+ assertNormalizedDisplayNumber("1", "1");
+ assertNormalizedDisplayNumber("abcde", "abcde");
+ assertNormalizedDisplayNumber("1-1", "1-1");
+ assertNormalizedDisplayNumber("1.1", "1-1");
+ assertNormalizedDisplayNumber("1 1", "1-1");
+ assertNormalizedDisplayNumber("1\u058a1", "1-1");
+ assertNormalizedDisplayNumber("1\u05be1", "1-1");
+ assertNormalizedDisplayNumber("1\u14001", "1-1");
+ assertNormalizedDisplayNumber("1\u18061", "1-1");
+ assertNormalizedDisplayNumber("1\u20101", "1-1");
+ assertNormalizedDisplayNumber("1\u20111", "1-1");
+ assertNormalizedDisplayNumber("1\u20121", "1-1");
+ assertNormalizedDisplayNumber("1\u20131", "1-1");
+ assertNormalizedDisplayNumber("1\u20141", "1-1");
+ }
+
+ private void assertNormalizedDisplayNumber(String displayNumber, String normalized) {
+ assertEquals(normalized, Channel.normalizeDisplayNumber(displayNumber));
+ }
+
private class TestChannelComparator extends Channel.DefaultComparator {
public TestChannelComparator(TvInputManagerHelper manager) {
super(null, manager);
diff --git a/tests/unit/src/com/android/tv/data/GenreItemTest.java b/tests/unit/src/com/android/tv/data/GenreItemTest.java
index fb48fd41..fdbcb599 100644
--- a/tests/unit/src/com/android/tv/data/GenreItemTest.java
+++ b/tests/unit/src/com/android/tv/data/GenreItemTest.java
@@ -16,23 +16,32 @@
package com.android.tv.data;
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
import android.media.tv.TvContract.Programs.Genres;
import android.os.Build;
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
+
+import org.junit.Test;
/**
* Tests for {@link Channel}.
*/
@SmallTest
-public class GenreItemTest extends AndroidTestCase {
+public class GenreItemTest {
private static final String INVALID_GENRE = "INVALID GENRE";
+ @Test
public void testGetLabels() {
// Checks if no exception is thrown.
- GenreItems.getLabels(getContext());
+ GenreItems.getLabels(getTargetContext());
}
+ @Test
public void testGetCanonicalGenre() {
int count = GenreItems.getGenreCount();
assertNull(GenreItems.getCanonicalGenre(GenreItems.ID_ALL_CHANNELS));
@@ -41,6 +50,7 @@ public class GenreItemTest extends AndroidTestCase {
}
}
+ @Test
public void testGetId_base() {
int count = GenreItems.getGenreCount();
assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(null));
@@ -58,6 +68,7 @@ public class GenreItemTest extends AndroidTestCase {
assertInRange(GenreItems.getId(Genres.GAMING), 1, count - 1);
}
+ @Test
public void testGetId_lmp_mr1() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.ARTS));
diff --git a/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java b/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java
index 430eef91..5457051f 100644
--- a/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java
+++ b/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java
@@ -16,14 +16,20 @@
package com.android.tv.data;
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.media.tv.TvContract;
import android.net.Uri;
import android.os.HandlerThread;
+import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.test.mock.MockCursor;
@@ -35,6 +41,10 @@ import com.android.tv.testing.FakeClock;
import com.android.tv.testing.ProgramInfo;
import com.android.tv.util.Utils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -45,7 +55,7 @@ import java.util.concurrent.TimeUnit;
* Test for {@link com.android.tv.data.ProgramDataManager}
*/
@SmallTest
-public class ProgramDataManagerTest extends AndroidTestCase {
+public class ProgramDataManagerTest {
private static final boolean DEBUG = false;
private static final String TAG = "ProgramDataManagerTest";
@@ -66,31 +76,28 @@ public class ProgramDataManagerTest extends AndroidTestCase {
private FakeContentResolver mContentResolver;
private FakeContentProvider mContentProvider;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
+ @Before
+ public void setUp() {
mClock = FakeClock.createWithCurrentTime();
mListener = new TestProgramDataManagerListener();
- mContentProvider = new FakeContentProvider(getContext());
+ mContentProvider = new FakeContentProvider(getTargetContext());
mContentResolver = new FakeContentResolver();
mContentResolver.addProvider(TvContract.AUTHORITY, mContentProvider);
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mProgramDataManager = new ProgramDataManager(
- mContentResolver, mClock, mHandlerThread.getLooper(), null);
+ mContentResolver, mClock, mHandlerThread.getLooper());
mProgramDataManager.setPrefetchEnabled(true);
mProgramDataManager.addListener(mListener);
}
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
+ @After
+ public void tearDown() {
mHandlerThread.quitSafely();
mProgramDataManager.stop();
}
- private void startAndWaitForComplete() throws Exception {
+ private void startAndWaitForComplete() throws InterruptedException {
mProgramDataManager.start();
assertTrue(mListener.programUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
}
@@ -98,12 +105,13 @@ public class ProgramDataManagerTest extends AndroidTestCase {
/**
* Test for {@link ProgramInfo#getIndex} and {@link ProgramInfo#getStartTimeMs}.
*/
+ @Test
public void testProgramUtils() {
ProgramInfo stub = ProgramInfo.create();
for (long channelId = 1; channelId < Constants.UNIT_TEST_CHANNEL_COUNT; channelId++) {
int index = stub.getIndex(mClock.currentTimeMillis(), channelId);
long startTimeMs = stub.getStartTimeMs(index, channelId);
- ProgramInfo programAt = stub.build(getContext(), index);
+ ProgramInfo programAt = stub.build(InstrumentationRegistry.getContext(), index);
assertTrue(startTimeMs <= mClock.currentTimeMillis());
assertTrue(mClock.currentTimeMillis() < startTimeMs + programAt.durationMs);
}
@@ -118,7 +126,8 @@ public class ProgramDataManagerTest extends AndroidTestCase {
* {@link ProgramDataManager#setPrefetchTimeRange(long)}.
* </p>
*/
- public void testGetPrograms() throws Exception {
+ @Test
+ public void testGetPrograms() throws InterruptedException {
// Initial setup to test {@link ProgramDataManager#setPrefetchTimeRange(long)}.
long preventSnapDelayMs = ProgramDataManager.PROGRAM_GUIDE_SNAP_TIME_MS * 2;
long prefetchTimeRangeStartMs = System.currentTimeMillis() + preventSnapDelayMs;
@@ -140,7 +149,7 @@ public class ProgramDataManagerTest extends AndroidTestCase {
ProgramInfo stub = ProgramInfo.create();
int index = stub.getIndex(mClock.currentTimeMillis(), channelId);
for (Program program : programs) {
- ProgramInfo programInfoAt = stub.build(getContext(), index);
+ ProgramInfo programInfoAt = stub.build(InstrumentationRegistry.getContext(), index);
long startTimeMs = stub.getStartTimeMs(index, channelId);
assertProgramEquals(startTimeMs, programInfoAt, program);
index++;
@@ -167,14 +176,15 @@ public class ProgramDataManagerTest extends AndroidTestCase {
* {@link ProgramDataManager#removeOnCurrentProgramUpdatedListener}.
* </p>
*/
- public void testCurrentProgramListener() throws Exception {
+ @Test
+ public void testCurrentProgramListener() throws InterruptedException {
final long testChannelId = 1;
ProgramInfo stub = ProgramInfo.create();
int index = stub.getIndex(mClock.currentTimeMillis(), testChannelId);
// Set current time to few seconds before the current program ends,
// so we can see if callback is called as expected.
long nextProgramStartTimeMs = stub.getStartTimeMs(index + 1, testChannelId);
- ProgramInfo nextProgramInfo = stub.build(getContext(), index + 1);
+ ProgramInfo nextProgramInfo = stub.build(InstrumentationRegistry.getContext(), index + 1);
mClock.setCurrentTimeMillis(nextProgramStartTimeMs - (WAIT_TIME_OUT_MS / 2));
startAndWaitForComplete();
@@ -196,7 +206,8 @@ public class ProgramDataManagerTest extends AndroidTestCase {
/**
* Test if program data is refreshed after the program insertion.
*/
- public void testContentProviderUpdate() throws Exception {
+ @Test
+ public void testContentProviderUpdate() throws InterruptedException {
final long testChannelId = 1;
startAndWaitForComplete();
// Force program data manager to update program data whenever it's changes.
@@ -217,7 +228,8 @@ public class ProgramDataManagerTest extends AndroidTestCase {
/**
* Test for {@link ProgramDataManager#setPauseProgramUpdate(boolean)}.
*/
- public void testSetPauseProgramUpdate() throws Exception {
+ @Test
+ public void testSetPauseProgramUpdate() throws InterruptedException {
final long testChannelId = 1;
startAndWaitForComplete();
// Force program data manager to update program data whenever it's changes.
@@ -290,7 +302,7 @@ public class ProgramDataManagerTest extends AndroidTestCase {
int index = stub.getIndex(startTimeMs, i);
long programStartTimeMs = stub.getStartTimeMs(index, i);
while (programStartTimeMs < endTimeMs) {
- ProgramInfo programAt = stub.build(getContext(), index);
+ ProgramInfo programAt = stub.build(InstrumentationRegistry.getContext(), index);
programInfoList.add(
new ProgramInfoWrapper(index, programStartTimeMs, programAt));
index++;
@@ -340,7 +352,8 @@ public class ProgramDataManagerTest extends AndroidTestCase {
ProgramInfo stub = ProgramInfo.create();
ProgramInfoWrapper last = programList.get(programList.size() - 1);
while (last.startTimeMs < endTimeMs) {
- ProgramInfo nextProgramInfo = stub.build(getContext(), last.index + 1);
+ ProgramInfo nextProgramInfo = stub.build(InstrumentationRegistry.getContext(),
+ last.index + 1);
ProgramInfoWrapper next = new ProgramInfoWrapper(last.index + 1,
last.startTimeMs + last.programInfo.durationMs, nextProgramInfo);
programList.add(next);
diff --git a/tests/unit/src/com/android/tv/data/ProgramTest.java b/tests/unit/src/com/android/tv/data/ProgramTest.java
index 7e474cd6..1d1f6c10 100644
--- a/tests/unit/src/com/android/tv/data/ProgramTest.java
+++ b/tests/unit/src/com/android/tv/data/ProgramTest.java
@@ -17,17 +17,18 @@ package com.android.tv.data;
import static android.media.tv.TvContract.Programs.Genres.COMEDY;
import static android.media.tv.TvContract.Programs.Genres.FAMILY_KIDS;
-
-import com.android.tv.data.Program.CriticScore;
-import com.android.tv.dvr.SeriesRecording;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import android.media.tv.TvContentRating;
import android.media.tv.TvContract.Programs.Genres;
import android.os.Parcel;
import android.support.test.filters.SmallTest;
-import android.util.Log;
-import junit.framework.TestCase;
+import com.android.tv.data.Program.CriticScore;
+
+import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
@@ -37,19 +38,20 @@ import java.util.List;
* Tests for {@link Program}.
*/
@SmallTest
-public class ProgramTest extends TestCase {
-
+public class ProgramTest {
private static final int NOT_FOUND_GENRE = 987;
private static final int FAMILY_GENRE_ID = GenreItems.getId(FAMILY_KIDS);
private static final int COMEDY_GENRE_ID = GenreItems.getId(COMEDY);
+ @Test
public void testBuild() {
Program program = new Program.Builder().build();
assertEquals("isValid", false, program.isValid());
}
+ @Test
public void testNoGenres() {
Program program = new Program.Builder()
.setCanonicalGenres("")
@@ -61,6 +63,7 @@ public class ProgramTest extends TestCase {
assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
}
+ @Test
public void testFamilyGenre() {
Program program = new Program.Builder()
.setCanonicalGenres(FAMILY_KIDS)
@@ -72,6 +75,7 @@ public class ProgramTest extends TestCase {
assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
}
+ @Test
public void testFamilyComedyGenre() {
Program program = new Program.Builder()
.setCanonicalGenres(FAMILY_KIDS + ", " + COMEDY)
@@ -83,6 +87,7 @@ public class ProgramTest extends TestCase {
assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
}
+ @Test
public void testOtherGenre() {
Program program = new Program.Builder()
.setCanonicalGenres("other")
@@ -94,7 +99,8 @@ public class ProgramTest extends TestCase {
assertHasGenre(program, GenreItems.ID_ALL_CHANNELS, true);
}
- public void testParcelable() throws Exception {
+ @Test
+ public void testParcelable() {
List<CriticScore> criticScores = new ArrayList<>();
criticScores.add(new CriticScore("1", "2", "3"));
criticScores.add(new CriticScore("4", "5", "6"));
@@ -139,6 +145,7 @@ public class ProgramTest extends TestCase {
}
}
+ @Test
public void testParcelableWithCriticScore() {
Program program = new Program.Builder()
.setTitle("MyTitle")
diff --git a/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java b/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java
index f5504d48..b4682dd9 100644
--- a/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java
+++ b/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java
@@ -19,8 +19,6 @@ package com.android.tv.data;
import android.content.pm.ResolveInfo;
import android.media.tv.TvInputInfo;
import android.support.test.filters.SmallTest;
-import android.support.test.filters.Suppress;
-import android.test.AndroidTestCase;
import android.util.Pair;
import com.android.tv.testing.ComparatorTester;
@@ -28,6 +26,7 @@ import com.android.tv.util.SetupUtils;
import com.android.tv.util.TestUtils;
import com.android.tv.util.TvInputManagerHelper;
+import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
@@ -40,16 +39,16 @@ import java.util.LinkedHashMap;
* Test for {@link TvInputNewComparator}
*/
@SmallTest
-public class TvInputNewComparatorTest extends AndroidTestCase {
+public class TvInputNewComparatorTest {
+ @Test
public void testComparator() throws Exception {
- final LinkedHashMap<String, Pair<Boolean, Boolean>> INPUT_ID_TO_NEW_INPUT =
- new LinkedHashMap<>();
- INPUT_ID_TO_NEW_INPUT.put("2_new_input", new Pair(true, false));
- INPUT_ID_TO_NEW_INPUT.put("4_new_input", new Pair(true, false));
- INPUT_ID_TO_NEW_INPUT.put("4_old_input", new Pair(false, false));
- INPUT_ID_TO_NEW_INPUT.put("0_old_input", new Pair(false, true));
- INPUT_ID_TO_NEW_INPUT.put("1_old_input", new Pair(false, true));
- INPUT_ID_TO_NEW_INPUT.put("3_old_input", new Pair(false, true));
+ LinkedHashMap<String, Pair<Boolean, Boolean>> inputIdToNewInput = new LinkedHashMap<>();
+ inputIdToNewInput.put("2_new_input", new Pair<>(true, false));
+ inputIdToNewInput.put("4_new_input", new Pair<>(true, false));
+ inputIdToNewInput.put("4_old_input", new Pair<>(false, false));
+ inputIdToNewInput.put("0_old_input", new Pair<>(false, true));
+ inputIdToNewInput.put("1_old_input", new Pair<>(false, true));
+ inputIdToNewInput.put("3_old_input", new Pair<>(false, true));
SetupUtils setupUtils = Mockito.mock(SetupUtils.class);
Mockito.when(setupUtils.isNewInput(Matchers.anyString())).thenAnswer(
@@ -57,7 +56,7 @@ public class TvInputNewComparatorTest extends AndroidTestCase {
@Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
String inputId = (String) invocation.getArguments()[0];
- return INPUT_ID_TO_NEW_INPUT.get(inputId).first;
+ return inputIdToNewInput.get(inputId).first;
}
}
);
@@ -66,7 +65,7 @@ public class TvInputNewComparatorTest extends AndroidTestCase {
@Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
String inputId = (String) invocation.getArguments()[0];
- return INPUT_ID_TO_NEW_INPUT.get(inputId).second;
+ return inputIdToNewInput.get(inputId).second;
}
}
);
@@ -83,7 +82,7 @@ public class TvInputNewComparatorTest extends AndroidTestCase {
ComparatorTester<TvInputInfo> comparatorTester =
ComparatorTester.withoutEqualsTest(comparator);
ResolveInfo resolveInfo = TestUtils.createResolveInfo("test", "test");
- for (String id : INPUT_ID_TO_NEW_INPUT.keySet()) {
+ for (String id : inputIdToNewInput.keySet()) {
// Put mock resolveInfo to prevent NPE in {@link TvInputInfo#toString}
TvInputInfo info1 = TestUtils.createTvInputInfo(
resolveInfo, id, "test1", TvInputInfo.TYPE_TUNER, false);
diff --git a/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java b/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java
index c86bb724..7eea1be7 100644
--- a/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java
+++ b/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java
@@ -16,60 +16,57 @@
package com.android.tv.data;
-import android.support.test.filters.SmallTest;
-import android.support.test.filters.Suppress;
-import android.test.AndroidTestCase;
-import android.test.UiThreadTest;
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Looper;
+import android.support.test.filters.MediumTest;
import com.android.tv.data.WatchedHistoryManager.WatchedRecord;
-import com.android.tv.testing.Utils;
-import java.util.concurrent.CountDownLatch;
+import org.junit.Before;
+import org.junit.Test;
+
import java.util.concurrent.TimeUnit;
/**
* Test for {@link com.android.tv.data.WatchedHistoryManagerTest}
+ * <p>
+ * This is a medium test because it load files which accessing SharedPreferences.
*/
-@SmallTest
-@Suppress // http://b/27156462
-public class WatchedHistoryManagerTest extends AndroidTestCase {
- private static final boolean DEBUG = false;
- private static final String TAG = "WatchedHistoryManager";
-
+@MediumTest
+public class WatchedHistoryManagerTest {
// Wait time for expected success.
- private static final long WAIT_TIME_OUT_MS = 1000L;
private static final int MAX_HISTORY_SIZE = 100;
private WatchedHistoryManager mWatchedHistoryManager;
private TestWatchedHistoryManagerListener mListener;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- Utils.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mWatchedHistoryManager = new WatchedHistoryManager(getContext(), MAX_HISTORY_SIZE);
- mListener = new TestWatchedHistoryManagerListener();
- mWatchedHistoryManager.setListener(mListener);
- }
- });
+ @Before
+ public void setUp() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ mWatchedHistoryManager = new WatchedHistoryManager(getTargetContext(), MAX_HISTORY_SIZE);
+ mListener = new TestWatchedHistoryManagerListener();
+ mWatchedHistoryManager.setListener(mListener);
}
- private void startAndWaitForComplete() throws Exception {
+ private void startAndWaitForComplete() throws InterruptedException {
mWatchedHistoryManager.start();
- assertTrue(mListener.loadFinishedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS));
+ assertTrue(mListener.mLoadFinished);
}
- @UiThreadTest
- public void testIsLoaded() throws Exception {
- assertFalse(mWatchedHistoryManager.isLoaded());
+ @Test
+ public void testIsLoaded() throws InterruptedException {
startAndWaitForComplete();
assertTrue(mWatchedHistoryManager.isLoaded());
}
- @UiThreadTest
- public void testLogChannelViewStop() throws Exception {
+ @Test
+ public void testLogChannelViewStop() throws InterruptedException {
startAndWaitForComplete();
long fakeId = 100000000;
long time = System.currentTimeMillis();
@@ -86,8 +83,8 @@ public class WatchedHistoryManagerTest extends AndroidTestCase {
assertEquals(record, recordFromSharedPreferences);
}
- @UiThreadTest
- public void testCircularHistoryQueue() throws Exception {
+ @Test
+ public void testCircularHistoryQueue() throws InterruptedException {
startAndWaitForComplete();
final long startChannelId = 100000000;
long time = System.currentTimeMillis();
@@ -111,7 +108,7 @@ public class WatchedHistoryManagerTest extends AndroidTestCase {
mWatchedHistoryManager.getRecordFromSharedPreferences(MAX_HISTORY_SIZE));
}
- @UiThreadTest
+ @Test
public void testWatchedRecordEquals() {
assertTrue(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 3)));
assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 4)));
@@ -119,8 +116,8 @@ public class WatchedHistoryManagerTest extends AndroidTestCase {
assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(4, 2, 3)));
}
- @UiThreadTest
- public void testEncodeDecodeWatchedRecord() throws Exception {
+ @Test
+ public void testEncodeDecodeWatchedRecord() {
long fakeId = 100000000;
long time = System.currentTimeMillis();
long duration = TimeUnit.MINUTES.toMillis(10);
@@ -131,11 +128,11 @@ public class WatchedHistoryManagerTest extends AndroidTestCase {
}
private class TestWatchedHistoryManagerListener implements WatchedHistoryManager.Listener {
- public final CountDownLatch loadFinishedLatch = new CountDownLatch(1);
+ boolean mLoadFinished;
@Override
public void onLoadFinished() {
- loadFinishedLatch.countDown();
+ mLoadFinished = true;
}
@Override
diff --git a/tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java b/tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java
index 1292759e..5f0ae15c 100644
--- a/tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java
+++ b/tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java
@@ -16,35 +16,51 @@
package com.android.tv.dvr;
+import static android.support.test.InstrumentationRegistry.getContext;
+
+import android.os.Build;
import android.support.annotation.NonNull;
+import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
import android.test.MoreAsserts;
+import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.feature.TestableFeature;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.testing.FakeClock;
import com.android.tv.testing.dvr.RecordingTestUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
import java.util.List;
import java.util.concurrent.TimeUnit;
-/**
- * Tests for {@link BaseDvrDataManager} using {@link DvrDataManagerInMemoryImpl}.
- */
+/** Tests for {@link BaseDvrDataManager} using {@link DvrDataManagerInMemoryImpl}. */
@SmallTest
-public class BaseDvrDataManagerTest extends AndroidTestCase {
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class BaseDvrDataManagerTest {
private static final String INPUT_ID = "input_id";
private static final int CHANNEL_ID = 273;
+ private final TestableFeature mDvrFeature = CommonFeatures.DVR;
private DvrDataManagerInMemoryImpl mDvrDataManager;
private FakeClock mFakeClock;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
+ mDvrFeature.enableForTest();
mFakeClock = FakeClock.createWithCurrentTime();
mDvrDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock);
}
+ @After
+ public void tearDown() {
+ mDvrFeature.resetForTests();
+ }
+
+ @Test
public void testGetNonStartedScheduledRecordings() {
ScheduledRecording recording = mDvrDataManager
.addScheduledRecordingInternal(createNewScheduledRecordingStartingNow());
@@ -52,6 +68,7 @@ public class BaseDvrDataManagerTest extends AndroidTestCase {
MoreAsserts.assertContentsInAnyOrder(result, recording);
}
+ @Test
public void testGetNonStartedScheduledRecordings_past() {
mDvrDataManager.addScheduledRecordingInternal(createNewScheduledRecordingStartingNow());
mFakeClock.increment(TimeUnit.MINUTES, 6);
diff --git a/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java b/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java
index b822f164..9771a2e5 100644
--- a/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java
+++ b/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java
@@ -16,24 +16,29 @@
package com.android.tv.dvr;
+import static org.junit.Assert.assertEquals;
+
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.testing.dvr.RecordingTestUtils;
-import junit.framework.TestCase;
+import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
-/**
- * Tests for {@link DvrDataManagerImpl}
- */
+/** Tests for {@link DvrDataManagerImpl} */
@SmallTest
-public class DvrDataManagerImplTest extends TestCase {
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class DvrDataManagerImplTest {
private static final String INPUT_ID = "input_id";
private static final int CHANNEL_ID = 273;
- public void testGetNextScheduledStartTimeAfter() throws Exception {
+ @Test
+ public void testGetNextScheduledStartTimeAfter() {
long id = 1;
List<ScheduledRecording> scheduledRecordings = new ArrayList<>();
assertNextStartTime(scheduledRecordings, 0L, DvrDataManager.NEXT_START_TIME_NOT_FOUND);
diff --git a/tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java b/tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java
index 85e35c4d..0a7ab46c 100644
--- a/tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java
+++ b/tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java
@@ -17,14 +17,19 @@
package com.android.tv.dvr;
import android.content.Context;
+import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.test.filters.SdkSuppress;
import android.text.TextUtils;
import android.util.Log;
import android.util.Range;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.dvr.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.data.RecordedProgram;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.ScheduledRecording.RecordingState;
+import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.util.Clock;
import java.util.ArrayList;
@@ -34,10 +39,9 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
-/**
- * A DVR Data manager that stores values in memory suitable for testing.
- */
-final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
+/** A DVR Data manager that stores values in memory suitable for testing. */
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager {
private final static String TAG = "DvrDataManagerInMemory";
private final AtomicLong mNextId = new AtomicLong(1);
private final Map<Long, ScheduledRecording> mScheduledRecordings = new HashMap<>();
diff --git a/tests/unit/src/com/android/tv/dvr/DvrDbSyncTest.java b/tests/unit/src/com/android/tv/dvr/DvrDbSyncTest.java
deleted file mode 100644
index 7cb3721c..00000000
--- a/tests/unit/src/com/android/tv/dvr/DvrDbSyncTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
-
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.data.Program;
-
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for {@link DvrScheduleManager}
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class DvrDbSyncTest extends AndroidTestCase {
- private static final String INPUT_ID = "input_id";
- private static final long BASE_PROGRAM_ID = 1;
- private static final long BASE_START_TIME_MS = 0;
- private static final long BASE_END_TIME_MS = 1;
- private static final String BASE_SEASON_NUMBER = "2";
- private static final String BASE_EPISODE_NUMBER = "3";
- private static final Program BASE_PROGRAM = new Program.Builder().setId(BASE_PROGRAM_ID)
- .setStartTimeUtcMillis(BASE_START_TIME_MS).setEndTimeUtcMillis(BASE_END_TIME_MS)
- .setSeasonNumber(BASE_SEASON_NUMBER).setEpisodeNumber(BASE_EPISODE_NUMBER).build();
- private static final ScheduledRecording BASE_SCHEDULE =
- ScheduledRecording.builder(INPUT_ID, BASE_PROGRAM).build();
-
- private DvrDbSync mDbSync;
- @Mock private DvrDataManagerImpl mDataManager;
- @Mock private ChannelDataManager mChannelDataManager;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- MockitoAnnotations.initMocks(this);
- when(mChannelDataManager.isDbLoadFinished()).thenReturn(true);
- mDbSync = new DvrDbSync(getContext(), mDataManager, mChannelDataManager);
- }
-
- public void testHandleUpdateProgram_null() {
- addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE);
- mDbSync.handleUpdateProgram(null, BASE_PROGRAM_ID);
- verify(mDataManager).removeScheduledRecording(BASE_SCHEDULE);
- }
-
- public void testHandleUpdateProgram_changeTimeNotStarted() {
- addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE);
- long startTimeMs = BASE_START_TIME_MS + 1;
- long endTimeMs = BASE_END_TIME_MS + 1;
- Program program = new Program.Builder(BASE_PROGRAM).setStartTimeUtcMillis(startTimeMs)
- .setEndTimeUtcMillis(endTimeMs).build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- assertUpdateScheduleCalled(program);
- }
-
- public void testHandleUpdateProgram_changeTimeInProgressNotCalled() {
- addSchedule(BASE_PROGRAM_ID, ScheduledRecording.buildFrom(BASE_SCHEDULE)
- .setState(ScheduledRecording.STATE_RECORDING_IN_PROGRESS).build());
- long startTimeMs = BASE_START_TIME_MS + 1;
- Program program = new Program.Builder(BASE_PROGRAM).setStartTimeUtcMillis(startTimeMs)
- .build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- verify(mDataManager, never()).updateScheduledRecording(anyObject());
- }
-
- public void testHandleUpdateProgram_changeSeason() {
- addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE);
- String seasonNumber = BASE_SEASON_NUMBER + "1";
- String episodeNumber = BASE_EPISODE_NUMBER + "1";
- Program program = new Program.Builder(BASE_PROGRAM).setSeasonNumber(seasonNumber)
- .setEpisodeNumber(episodeNumber).build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- assertUpdateScheduleCalled(program);
- }
-
- public void testHandleUpdateProgram_finished() {
- addSchedule(BASE_PROGRAM_ID, ScheduledRecording.buildFrom(BASE_SCHEDULE)
- .setState(ScheduledRecording.STATE_RECORDING_FINISHED).build());
- String seasonNumber = BASE_SEASON_NUMBER + "1";
- String episodeNumber = BASE_EPISODE_NUMBER + "1";
- Program program = new Program.Builder(BASE_PROGRAM).setSeasonNumber(seasonNumber)
- .setEpisodeNumber(episodeNumber).build();
- mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
- verify(mDataManager, never()).updateScheduledRecording(anyObject());
- }
-
- private void addSchedule(long programId, ScheduledRecording schedule) {
- when(mDataManager.getScheduledRecordingForProgramId(programId)).thenReturn(schedule);
- }
-
- private void assertUpdateScheduleCalled(Program program) {
- verify(mDataManager).updateScheduledRecording(
- eq(ScheduledRecording.builder(INPUT_ID, program).build()));
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/DvrRecordingServiceTest.java b/tests/unit/src/com/android/tv/dvr/DvrRecordingServiceTest.java
deleted file mode 100644
index 0a203ede..00000000
--- a/tests/unit/src/com/android/tv/dvr/DvrRecordingServiceTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import static org.mockito.Mockito.verify;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.ServiceTestCase;
-
-import com.android.tv.common.feature.CommonFeatures;
-import com.android.tv.common.feature.TestableFeature;
-import com.android.tv.testing.FakeClock;
-
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for {@link DvrRecordingService}.
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class DvrRecordingServiceTest extends ServiceTestCase<DvrRecordingService> {
- @Mock Scheduler mMockScheduler;
- private final TestableFeature mDvrFeature = CommonFeatures.DVR;
- private final FakeClock mFakeClock = FakeClock.createWithCurrentTime();
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mDvrFeature.enableForTest();
- MockitoAnnotations.initMocks(this);
- setupService();
- DvrRecordingService service = getService();
- service.setScheduler(mMockScheduler);
- }
-
- @Override
- protected void tearDown() throws Exception {
- mDvrFeature.resetForTests();
- super.tearDown();
- }
-
- public DvrRecordingServiceTest() {
- super(DvrRecordingService.class);
- }
-
- public void testStartService_null() throws Exception {
- startService(null);
- verify(mMockScheduler, Mockito.only()).update();
- }
-} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java b/tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java
index 2850a5f7..1c77aa0e 100644
--- a/tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java
+++ b/tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java
@@ -16,32 +16,39 @@
package com.android.tv.dvr;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.test.MoreAsserts;
import android.util.Range;
+import com.android.tv.dvr.DvrScheduleManager.ConflictInfo;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.testing.dvr.RecordingTestUtils;
-import junit.framework.TestCase;
+import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
-/**
- * Tests for {@link DvrScheduleManager}
- */
+/** Tests for {@link DvrScheduleManager} */
@SmallTest
-public class DvrScheduleManagerTest extends TestCase {
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class DvrScheduleManagerTest {
private static final String INPUT_ID = "input_id";
+ @Test
public void testGetConflictingSchedules_emptySchedule() {
List<ScheduledRecording> schedules = new ArrayList<>();
MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1));
}
+ @Test
public void testGetConflictingSchedules_noConflict() {
long priority = 0;
long channelId = 0;
@@ -68,6 +75,7 @@ public class DvrScheduleManagerTest extends TestCase {
MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3));
}
+ @Test
public void testGetConflictingSchedules_noTuner() {
long priority = 0;
long channelId = 0;
@@ -82,6 +90,7 @@ public class DvrScheduleManagerTest extends TestCase {
assertEquals(schedules, DvrScheduleManager.getConflictingSchedules(schedules, 0));
}
+ @Test
public void testGetConflictingSchedules_conflict() {
long priority = 0;
long channelId = 0;
@@ -160,6 +169,7 @@ public class DvrScheduleManagerTest extends TestCase {
MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 5));
}
+ @Test
public void testGetConflictingSchedules_conflict2() {
// The case when there is a long schedule.
long priority = 0;
@@ -186,6 +196,7 @@ public class DvrScheduleManagerTest extends TestCase {
MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2));
}
+ @Test
public void testGetConflictingSchedules_reverseOrder() {
long priority = 0;
long channelId = 0;
@@ -264,6 +275,7 @@ public class DvrScheduleManagerTest extends TestCase {
MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 5));
}
+ @Test
public void testGetConflictingSchedules_period1() {
long priority = 0;
long channelId = 0;
@@ -281,6 +293,7 @@ public class DvrScheduleManagerTest extends TestCase {
Collections.singletonList(new Range<>(110L, 120L))), r1);
}
+ @Test
public void testGetConflictingSchedules_period2() {
long priority = 0;
long channelId = 0;
@@ -298,6 +311,7 @@ public class DvrScheduleManagerTest extends TestCase {
Collections.singletonList(new Range<>(110L, 120L))), r1);
}
+ @Test
public void testGetConflictingSchedules_period3() {
long priority = 0;
long channelId = 0;
@@ -328,6 +342,7 @@ public class DvrScheduleManagerTest extends TestCase {
ranges), r2, r1);
}
+ @Test
public void testGetConflictingSchedules_addSchedules1() {
long priority = 0;
long channelId = 0;
@@ -351,6 +366,7 @@ public class DvrScheduleManagerTest extends TestCase {
schedules, 1), r1);
}
+ @Test
public void testGetConflictingSchedules_addSchedules2() {
long priority = 0;
long channelId = 0;
@@ -374,6 +390,7 @@ public class DvrScheduleManagerTest extends TestCase {
schedules, 1), r2, r1);
}
+ @Test
public void testGetConflictingSchedules_addLowestPriority() {
long priority = 0;
long channelId = 0;
@@ -394,6 +411,7 @@ public class DvrScheduleManagerTest extends TestCase {
schedules, 1), r1);
}
+ @Test
public void testGetConflictingSchedules_sameChannel() {
long priority = 0;
long channelId = 1;
@@ -405,6 +423,7 @@ public class DvrScheduleManagerTest extends TestCase {
MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3));
}
+ @Test
public void testGetConflictingSchedule_startEarlyAndFail() {
long priority = 0;
long channelId = 0;
@@ -423,6 +442,7 @@ public class DvrScheduleManagerTest extends TestCase {
r2);
}
+ @Test
public void testGetConflictingSchedule_startLate() {
long priority = 0;
long channelId = 0;
@@ -441,6 +461,7 @@ public class DvrScheduleManagerTest extends TestCase {
r2, r1);
}
+ @Test
public void testGetConflictingSchedulesForTune_canTune() {
// Can tune to the recorded channel if tuner count is 1.
long priority = 0;
@@ -452,6 +473,7 @@ public class DvrScheduleManagerTest extends TestCase {
channelId, 0L, priority + 1, schedules, 1));
}
+ @Test
public void testGetConflictingSchedulesForTune_cannotTune() {
// Can't tune to a channel if other channel is recording and tuner count is 1.
long priority = 0;
@@ -463,6 +485,7 @@ public class DvrScheduleManagerTest extends TestCase {
INPUT_ID, channelId + 1, 0L, priority + 1, schedules, 1), schedules.get(0));
}
+ @Test
public void testGetConflictingSchedulesForWatching_otherChannels() {
// The other channels are to be recorded.
long priority = 0;
@@ -481,6 +504,7 @@ public class DvrScheduleManagerTest extends TestCase {
INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2), r1);
}
+ @Test
public void testGetConflictingSchedulesForWatching_sameChannel1() {
long priority = 0;
long channelToWatch = 1;
@@ -498,6 +522,7 @@ public class DvrScheduleManagerTest extends TestCase {
INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), r2);
}
+ @Test
public void testGetConflictingSchedulesForWatching_sameChannel2() {
long priority = 0;
long channelToWatch = 1;
@@ -515,6 +540,7 @@ public class DvrScheduleManagerTest extends TestCase {
INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), r1);
}
+ @Test
public void testGetConflictingSchedulesForWatching_sameChannelConflict1() {
long priority = 0;
long channelToWatch = 1;
@@ -537,6 +563,7 @@ public class DvrScheduleManagerTest extends TestCase {
INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), r2, r1);
}
+ @Test
public void testGetConflictingSchedulesForWatching_sameChannelConflict2() {
long priority = 0;
long channelToWatch = 1;
@@ -559,6 +586,7 @@ public class DvrScheduleManagerTest extends TestCase {
INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), r3, r1);
}
+ @Test
public void testPartiallyConflictingSchedules() {
long priority = 100;
long channelId = 0;
@@ -586,49 +614,80 @@ public class DvrScheduleManagerTest extends TestCase {
RecordingTestUtils.createTestRecordingWithPriorityAndPeriod(++channelId,
--priority, 50L, 900L)
));
- Map<ScheduledRecording, Boolean> conflictsInfo = DvrScheduleManager
- .getConflictingSchedulesInfo(schedules, 1);
-
- assertNull(conflictsInfo.get(schedules.get(0)));
- assertFalse(conflictsInfo.get(schedules.get(1)));
- assertTrue(conflictsInfo.get(schedules.get(2)));
- assertTrue(conflictsInfo.get(schedules.get(3)));
- assertNull(conflictsInfo.get(schedules.get(4)));
- assertTrue(conflictsInfo.get(schedules.get(5)));
- assertNull(conflictsInfo.get(schedules.get(6)));
- assertFalse(conflictsInfo.get(schedules.get(7)));
- assertFalse(conflictsInfo.get(schedules.get(8)));
- assertFalse(conflictsInfo.get(schedules.get(9)));
- assertFalse(conflictsInfo.get(schedules.get(10)));
-
- conflictsInfo = DvrScheduleManager
- .getConflictingSchedulesInfo(schedules, 2);
-
- assertNull(conflictsInfo.get(schedules.get(0)));
- assertNull(conflictsInfo.get(schedules.get(1)));
- assertNull(conflictsInfo.get(schedules.get(2)));
- assertNull(conflictsInfo.get(schedules.get(3)));
- assertNull(conflictsInfo.get(schedules.get(4)));
- assertNull(conflictsInfo.get(schedules.get(5)));
- assertNull(conflictsInfo.get(schedules.get(6)));
- assertFalse(conflictsInfo.get(schedules.get(7)));
- assertFalse(conflictsInfo.get(schedules.get(8)));
- assertFalse(conflictsInfo.get(schedules.get(9)));
- assertTrue(conflictsInfo.get(schedules.get(10)));
-
- conflictsInfo = DvrScheduleManager
- .getConflictingSchedulesInfo(schedules, 3);
-
- assertNull(conflictsInfo.get(schedules.get(0)));
- assertNull(conflictsInfo.get(schedules.get(1)));
- assertNull(conflictsInfo.get(schedules.get(2)));
- assertNull(conflictsInfo.get(schedules.get(3)));
- assertNull(conflictsInfo.get(schedules.get(4)));
- assertNull(conflictsInfo.get(schedules.get(5)));
- assertNull(conflictsInfo.get(schedules.get(6)));
- assertNull(conflictsInfo.get(schedules.get(7)));
- assertTrue(conflictsInfo.get(schedules.get(8)));
- assertNull(conflictsInfo.get(schedules.get(9)));
- assertTrue(conflictsInfo.get(schedules.get(10)));
+ List<ConflictInfo> conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 1);
+
+ assertNotInList(schedules.get(0), conflicts);
+ assertFullConflict(schedules.get(1), conflicts);
+ assertPartialConflict(schedules.get(2), conflicts);
+ assertPartialConflict(schedules.get(3), conflicts);
+ assertNotInList(schedules.get(4), conflicts);
+ assertPartialConflict(schedules.get(5), conflicts);
+ assertNotInList(schedules.get(6), conflicts);
+ assertFullConflict(schedules.get(7), conflicts);
+ assertFullConflict(schedules.get(8), conflicts);
+ assertFullConflict(schedules.get(9), conflicts);
+ assertFullConflict(schedules.get(10), conflicts);
+
+ conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 2);
+
+ assertNotInList(schedules.get(0), conflicts);
+ assertNotInList(schedules.get(1), conflicts);
+ assertNotInList(schedules.get(2), conflicts);
+ assertNotInList(schedules.get(3), conflicts);
+ assertNotInList(schedules.get(4), conflicts);
+ assertNotInList(schedules.get(5), conflicts);
+ assertNotInList(schedules.get(6), conflicts);
+ assertFullConflict(schedules.get(7), conflicts);
+ assertFullConflict(schedules.get(8), conflicts);
+ assertFullConflict(schedules.get(9), conflicts);
+ assertPartialConflict(schedules.get(10), conflicts);
+
+ conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 3);
+
+ assertNotInList(schedules.get(0), conflicts);
+ assertNotInList(schedules.get(1), conflicts);
+ assertNotInList(schedules.get(2), conflicts);
+ assertNotInList(schedules.get(3), conflicts);
+ assertNotInList(schedules.get(4), conflicts);
+ assertNotInList(schedules.get(5), conflicts);
+ assertNotInList(schedules.get(6), conflicts);
+ assertNotInList(schedules.get(7), conflicts);
+ assertPartialConflict(schedules.get(8), conflicts);
+ assertNotInList(schedules.get(9), conflicts);
+ assertPartialConflict(schedules.get(10), conflicts);
+ }
+
+ private void assertNotInList(ScheduledRecording schedule, List<ConflictInfo> conflicts) {
+ for (ConflictInfo conflictInfo : conflicts) {
+ if (conflictInfo.schedule.equals(schedule)) {
+ fail(schedule + " conflicts with others.");
+ }
+ }
+ }
+
+ private void assertPartialConflict(ScheduledRecording schedule, List<ConflictInfo> conflicts) {
+ for (ConflictInfo conflictInfo : conflicts) {
+ if (conflictInfo.schedule.equals(schedule)) {
+ if (conflictInfo.partialConflict) {
+ return;
+ } else {
+ fail(schedule + " fully conflicts with others.");
+ }
+ }
+ }
+ fail(schedule + " doesn't conflict");
+ }
+
+ private void assertFullConflict(ScheduledRecording schedule, List<ConflictInfo> conflicts) {
+ for (ConflictInfo conflictInfo : conflicts) {
+ if (conflictInfo.schedule.equals(schedule)) {
+ if (!conflictInfo.partialConflict) {
+ return;
+ } else {
+ fail(schedule + " partially conflicts with others.");
+ }
+ }
+ }
+ fail(schedule + " doesn't conflict");
}
} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/EpisodicProgramLoadTaskTest.java b/tests/unit/src/com/android/tv/dvr/EpisodicProgramLoadTaskTest.java
deleted file mode 100644
index 2172d488..00000000
--- a/tests/unit/src/com/android/tv/dvr/EpisodicProgramLoadTaskTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
-
-import com.android.tv.dvr.EpisodicProgramLoadTask.ScheduledEpisode;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests for {@link EpisodicProgramLoadTask}
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class EpisodicProgramLoadTaskTest extends AndroidTestCase {
- private static final long SERIES_RECORDING_ID1 = 1;
- private static final long SERIES_RECORDING_ID2 = 2;
- private static final String SEASON_NUMBER1 = "SEASON NUMBER1";
- private static final String SEASON_NUMBER2 = "SEASON NUMBER2";
- private static final String EPISODE_NUMBER1 = "EPISODE NUMBER1";
- private static final String EPISODE_NUMBER2 = "EPISODE NUMBER2";
-
- public void testEpisodeAlreadyScheduled_true() {
- List<ScheduledEpisode> episodes = new ArrayList<>();
- ScheduledEpisode episode = new ScheduledEpisode(SERIES_RECORDING_ID1, SEASON_NUMBER1,
- EPISODE_NUMBER1);
- episodes.add(episode);
- assertTrue(EpisodicProgramLoadTask.isEpisodeScheduled(episodes,
- new ScheduledEpisode(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1)));
- }
-
- public void testEpisodeAlreadyScheduled_false() {
- List<ScheduledEpisode> episodes = new ArrayList<>();
- ScheduledEpisode episode = new ScheduledEpisode(SERIES_RECORDING_ID1, SEASON_NUMBER1,
- EPISODE_NUMBER1);
- episodes.add(episode);
- assertFalse(EpisodicProgramLoadTask.isEpisodeScheduled(episodes,
- new ScheduledEpisode(SERIES_RECORDING_ID2, SEASON_NUMBER1, EPISODE_NUMBER1)));
- assertFalse(EpisodicProgramLoadTask.isEpisodeScheduled(episodes,
- new ScheduledEpisode(SERIES_RECORDING_ID1, SEASON_NUMBER2, EPISODE_NUMBER1)));
- assertFalse(EpisodicProgramLoadTask.isEpisodeScheduled(episodes,
- new ScheduledEpisode(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER2)));
- }
-
- public void testEpisodeAlreadyScheduled_null() {
- List<ScheduledEpisode> episodes = new ArrayList<>();
- ScheduledEpisode episode = new ScheduledEpisode(SERIES_RECORDING_ID1, SEASON_NUMBER1,
- EPISODE_NUMBER1);
- episodes.add(episode);
- assertFalse(EpisodicProgramLoadTask.isEpisodeScheduled(episodes,
- new ScheduledEpisode(SERIES_RECORDING_ID1, null, EPISODE_NUMBER1)));
- assertFalse(EpisodicProgramLoadTask.isEpisodeScheduled(episodes,
- new ScheduledEpisode(SERIES_RECORDING_ID1, SEASON_NUMBER1, null)));
- assertFalse(EpisodicProgramLoadTask.isEpisodeScheduled(episodes,
- new ScheduledEpisode(SERIES_RECORDING_ID1, null, null)));
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/InputTaskSchedulerTest.java b/tests/unit/src/com/android/tv/dvr/InputTaskSchedulerTest.java
deleted file mode 100644
index 85c78ce2..00000000
--- a/tests/unit/src/com/android/tv/dvr/InputTaskSchedulerTest.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.after;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.AlarmManager;
-import android.media.tv.TvInputInfo;
-import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.data.Channel;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.dvr.InputTaskScheduler.RecordingTaskFactory;
-import com.android.tv.testing.FakeClock;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-import com.android.tv.util.Clock;
-import com.android.tv.util.TestUtils;
-
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for {@link InputTaskScheduler}.
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class InputTaskSchedulerTest extends AndroidTestCase {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 1;
- private static final long LISTENER_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(1);
- private static final int TUNER_COUNT_ONE = 1;
- private static final int TUNER_COUNT_TWO = 2;
- private static final long LOW_PRIORITY = 1;
- private static final long HIGH_PRIORITY = 2;
-
- private FakeClock mFakeClock;
- private InputTaskScheduler mScheduler;
- @Mock private DvrManager mDvrManager;
- @Mock private WritableDvrDataManager mDataManager;
- @Mock private InputSessionManager mSessionManager;
- @Mock private AlarmManager mMockAlarmManager;
- @Mock private ChannelDataManager mChannelDataManager;
- private List<RecordingTask> mRecordingTasks;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- Handler fakeMainHandler = new Handler();
- Handler workerThreadHandler = new Handler();
- mRecordingTasks = new ArrayList();
- MockitoAnnotations.initMocks(this);
- mFakeClock = FakeClock.createWithCurrentTime();
- TvInputInfo input = createTvInputInfo(TUNER_COUNT_ONE);
- mScheduler = new InputTaskScheduler(getContext(), input, Looper.myLooper(),
- mChannelDataManager, mDvrManager, mDataManager, mSessionManager, mFakeClock,
- fakeMainHandler, workerThreadHandler, new RecordingTaskFactory() {
- @Override
- public RecordingTask createRecordingTask(ScheduledRecording scheduledRecording,
- Channel channel, DvrManager dvrManager,
- InputSessionManager sessionManager, WritableDvrDataManager dataManager,
- Clock clock) {
- RecordingTask task = mock(RecordingTask.class);
- when(task.getPriority()).thenReturn(scheduledRecording.getPriority());
- when(task.getEndTimeMs()).thenReturn(scheduledRecording.getEndTimeMs());
- mRecordingTasks.add(task);
- return task;
- }
- });
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testAddSchedule_past() throws Exception {
- ScheduledRecording r = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
- CHANNEL_ID, 0L, 1L);
- when(mDataManager.getScheduledRecording(anyLong())).thenReturn(r);
- mScheduler.handleAddSchedule(r);
- mScheduler.handleBuildSchedule();
- verify(mDataManager, timeout((int) LISTENER_TIMEOUT_MS).times(1))
- .changeState(any(ScheduledRecording.class),
- eq(ScheduledRecording.STATE_RECORDING_FAILED));
- }
-
- public void testAddSchedule_start() throws Exception {
- mScheduler.handleAddSchedule(RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
- CHANNEL_ID, mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1)));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- }
-
- public void testAddSchedule_consecutiveNoStop() throws Exception {
- long startTimeMs = mFakeClock.currentTimeMillis();
- long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- long id = 0;
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- LOW_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- startTimeMs = endTimeMs;
- endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- HIGH_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- // The first schedule should not be stopped because the second one should wait for the end
- // of the first schedule.
- verify(mRecordingTasks.get(0), after((int) LISTENER_TIMEOUT_MS).never()).stop();
- }
-
- public void testAddSchedule_consecutiveNoFail() throws Exception {
- long startTimeMs = mFakeClock.currentTimeMillis();
- long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- long id = 0;
- when(mDataManager.getScheduledRecording(anyLong())).thenReturn(ScheduledRecording
- .builder(INPUT_ID, CHANNEL_ID, 0L, 0L).build());
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- HIGH_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- startTimeMs = endTimeMs;
- endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- LOW_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- verify(mRecordingTasks.get(0), after((int) LISTENER_TIMEOUT_MS).never()).stop();
- // The second schedule should not fail because it can starts after the first one finishes.
- verify(mDataManager, after((int) LISTENER_TIMEOUT_MS).never())
- .changeState(any(ScheduledRecording.class),
- eq(ScheduledRecording.STATE_RECORDING_FAILED));
- }
-
- public void testAddSchedule_consecutiveUseLessSession() throws Exception {
- TvInputInfo input = createTvInputInfo(TUNER_COUNT_TWO);
- mScheduler.updateTvInputInfo(input);
- long startTimeMs = mFakeClock.currentTimeMillis();
- long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- long id = 0;
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- LOW_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- startTimeMs = endTimeMs;
- endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
- mScheduler.handleAddSchedule(
- RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
- HIGH_PRIORITY, startTimeMs, endTimeMs));
- mScheduler.handleBuildSchedule();
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
- verify(mRecordingTasks.get(0), after((int) LISTENER_TIMEOUT_MS).never()).stop();
- // The second schedule should wait until the first one finishes rather than creating a new
- // session even though there are available tuners.
- assertTrue(mRecordingTasks.size() == 1);
- }
-
- public void testUpdateSchedule_noCancel() throws Exception {
- ScheduledRecording r = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
- CHANNEL_ID, mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1));
- mScheduler.handleAddSchedule(r);
- mScheduler.handleBuildSchedule();
- mScheduler.handleUpdateSchedule(r);
- verify(mRecordingTasks.get(0), after((int) LISTENER_TIMEOUT_MS).never()).cancel();
- }
-
- public void testUpdateSchedule_cancel() throws Exception {
- ScheduledRecording r = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
- CHANNEL_ID, mFakeClock.currentTimeMillis(),
- mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(2));
- mScheduler.handleAddSchedule(r);
- mScheduler.handleBuildSchedule();
- mScheduler.handleUpdateSchedule(ScheduledRecording.buildFrom(r)
- .setStartTimeMs(mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1))
- .build());
- verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).cancel();
- }
-
- private TvInputInfo createTvInputInfo(int tunerCount) throws Exception {
- return TestUtils.createTvInputInfo(null, null, null, 0, false, true, tunerCount);
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/RecordingTaskTest.java b/tests/unit/src/com/android/tv/dvr/RecordingTaskTest.java
deleted file mode 100644
index 7404a554..00000000
--- a/tests/unit/src/com/android/tv/dvr/RecordingTaskTest.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-import static org.mockito.hamcrest.MockitoHamcrest.longThat;
-
-import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.InputSessionManager.RecordingSession;
-import com.android.tv.data.Channel;
-import com.android.tv.dvr.RecordingTask.State;
-import com.android.tv.testing.FakeClock;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.compat.ArgumentMatcher;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for {@link RecordingTask}.
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class RecordingTaskTest extends AndroidTestCase {
- private static final long DURATION = TimeUnit.MINUTES.toMillis(30);
- private static final long START_OFFSET_MS = Scheduler.MS_TO_WAKE_BEFORE_START;
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- private FakeClock mFakeClock;
- private DvrDataManagerInMemoryImpl mDataManager;
- @Mock Handler mMockHandler;
- @Mock DvrManager mDvrManager;
- @Mock InputSessionManager mMockSessionManager;
- @Mock RecordingSession mMockRecordingSession;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
- MockitoAnnotations.initMocks(this);
- mFakeClock = FakeClock.createWithCurrentTime();
- mDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock);
- }
-
- public void testHandle_init() {
- Channel channel = createTestChannel();
- ScheduledRecording r = createRecording(channel);
- RecordingTask task = createRecordingTask(r, channel);
- String inputId = channel.getInputId();
- when(mMockSessionManager.createRecordingSession(eq(inputId), anyString(), eq(task),
- eq(mMockHandler), anyLong())).thenReturn(mMockRecordingSession);
- when(mMockHandler.sendMessageAtTime(anyObject(), anyLong())).thenReturn(true);
- assertTrue(task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE)));
- assertEquals(State.CONNECTION_PENDING, task.getState());
- verify(mMockSessionManager).createRecordingSession(eq(inputId), anyString(), eq(task),
- eq(mMockHandler), anyLong());
- verify(mMockRecordingSession).tune(eq(inputId), eq(channel.getUri()));
- verifyNoMoreInteractions(mMockHandler, mMockRecordingSession, mMockSessionManager);
- }
-
- private static Channel createTestChannel() {
- return new Channel.Builder().setInputId(INPUT_ID).setId(CHANNEL_ID)
- .setDisplayName("Test Ch " + CHANNEL_ID).build();
- }
-
- public void testOnConnected() {
- Channel channel = createTestChannel();
- ScheduledRecording r = createRecording(channel);
- mDataManager.addScheduledRecording(r);
- RecordingTask task = createRecordingTask(r, channel);
- String inputId = channel.getInputId();
- when(mMockSessionManager.createRecordingSession(eq(inputId), anyString(), eq(task),
- eq(mMockHandler), anyLong())).thenReturn(mMockRecordingSession);
- when(mMockHandler.sendMessageAtTime(anyObject(), anyLong())).thenReturn(true);
- task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE));
- task.onTuned(channel.getUri());
- assertEquals(State.CONNECTED, task.getState());
- }
-
- private ScheduledRecording createRecording(Channel c) {
- long startTime = mFakeClock.currentTimeMillis() + START_OFFSET_MS;
- long endTime = startTime + DURATION;
- return RecordingTestUtils.createTestRecordingWithPeriod(c.getInputId(), c.getId(),
- startTime, endTime);
- }
-
- private RecordingTask createRecordingTask(ScheduledRecording r, Channel channel) {
- RecordingTask recordingTask = new RecordingTask(getContext(), r, channel, mDvrManager,
- mMockSessionManager, mDataManager, mFakeClock);
- recordingTask.setHandler(mMockHandler);
- return recordingTask;
- }
-
- private void verifySendMessageAt(int what, long when) {
- verify(mMockHandler).sendMessageAtTime(argThat(messageMatchesWhat(what)), delta(when, 100));
- }
-
- private static long delta(final long value, final long delta) {
- return longThat(new BaseMatcher<Long>() {
- @Override
- public boolean matches(Object item) {
- Long other = (Long) item;
- return other >= value - delta && other <= value + delta;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("eq " + value + "±" + delta);
-
- }
- });
- }
-
- private Message createMessage(int what) {
- Message msg = new Message();
- msg.setTarget(mMockHandler);
- msg.what = what;
- return msg;
- }
-
- private static ArgumentMatcher<Message> messageMatchesWhat(final int what) {
- return new ArgumentMatcher<Message>() {
- @Override
- public boolean matchesObject(Object argument) {
- Message message = (Message) argument;
- return message.what == what;
- }
- };
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/ScheduledProgramReaperTest.java b/tests/unit/src/com/android/tv/dvr/ScheduledProgramReaperTest.java
deleted file mode 100644
index 847540c2..00000000
--- a/tests/unit/src/com/android/tv/dvr/ScheduledProgramReaperTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.test.MoreAsserts;
-
-import com.android.tv.testing.FakeClock;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-
-import junit.framework.TestCase;
-
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for {@link ScheduledProgramReaper}.
- */
-public class ScheduledProgramReaperTest extends TestCase {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
- private static final long DURATION = TimeUnit.HOURS.toMillis(1);
-
- private ScheduledProgramReaper mReaper;
- private FakeClock mFakeClock;
- private DvrDataManagerInMemoryImpl mDvrDataManager;
- @Mock private DvrManager mDvrManager;
-
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- MockitoAnnotations.initMocks(this);
- mFakeClock = FakeClock.createWithTimeOne();
- mDvrDataManager = new DvrDataManagerInMemoryImpl(null, mFakeClock);
- mReaper = new ScheduledProgramReaper(mDvrDataManager, mFakeClock);
- }
-
- public void testRun_noRecordings() {
- MoreAsserts.assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings());
- mReaper.run();
- MoreAsserts.assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings());
- }
-
- public void testRun_oneRecordingsTomorrow() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- mReaper.run();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- }
-
- public void testRun_oneRecordingsStarted() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- mFakeClock.increment(TimeUnit.DAYS);
- mReaper.run();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- }
-
- public void testRun_oneRecordingsFinished() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- mFakeClock.increment(TimeUnit.DAYS);
- mFakeClock.increment(TimeUnit.MINUTES, 2);
- mReaper.run();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- }
-
- public void testRun_oneRecordingsExpired() {
- ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
- MoreAsserts
- .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
- mFakeClock.increment(TimeUnit.DAYS, 1 + ScheduledProgramReaper.DAYS);
- mFakeClock.increment(TimeUnit.MILLISECONDS, DURATION);
- // After the cutoff and enough so we can see on the clock
- mFakeClock.increment(TimeUnit.SECONDS, 1);
-
- mReaper.run();
- MoreAsserts.assertContentsInAnyOrder(
- "Recordings after reaper at " + com.android.tv.util.Utils
- .toIsoDateTimeString(mFakeClock.currentTimeMillis()),
- mDvrDataManager.getAllScheduledRecordings());
- }
-
- private ScheduledRecording addNewScheduledRecordingForTomorrow() {
- long startTime = mFakeClock.currentTimeMillis() + TimeUnit.DAYS.toMillis(1);
- ScheduledRecording recording = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
- CHANNEL_ID, startTime, startTime + DURATION);
- return mDvrDataManager.addScheduledRecordingInternal(
- ScheduledRecording.buildFrom(recording)
- .setState(ScheduledRecording.STATE_RECORDING_FINISHED).build());
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java b/tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java
index 96036418..b98af603 100644
--- a/tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java
+++ b/tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java
@@ -16,34 +16,37 @@
package com.android.tv.dvr;
-import static com.android.tv.testing.dvr.RecordingTestUtils
- .createTestRecordingWithIdAndPeriod;
+import static com.android.tv.testing.dvr.RecordingTestUtils.createTestRecordingWithIdAndPeriod;
import static com.android.tv.testing.dvr.RecordingTestUtils.normalizePriority;
+import static junit.framework.TestCase.assertEquals;
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.test.MoreAsserts;
import android.util.Range;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
+import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.testing.dvr.RecordingTestUtils;
-import junit.framework.TestCase;
+import org.junit.Test;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-/**
- * Tests for {@link ScheduledRecordingTest}
- */
+/** Tests for {@link ScheduledRecordingTest} */
@SmallTest
-public class ScheduledRecordingTest extends TestCase {
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class ScheduledRecordingTest {
private static final String INPUT_ID = "input_id";
private static final int CHANNEL_ID = 273;
- public void testIsOverLapping() throws Exception {
+ @Test
+ public void testIsOverLapping() {
ScheduledRecording r = createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID,
10L, 20L);
assertOverLapping(false, 1L, 9L, r);
@@ -59,6 +62,7 @@ public class ScheduledRecordingTest extends TestCase {
assertOverLapping(false, 21L, 29L, r);
}
+ @Test
public void testBuildProgram() {
Channel c = new Channel.Builder().build();
Program p = new Program.Builder().build();
@@ -67,12 +71,14 @@ public class ScheduledRecordingTest extends TestCase {
assertEquals("type", ScheduledRecording.TYPE_PROGRAM, actual.getType());
}
+ @Test
public void testBuildTime() {
ScheduledRecording actual = createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID,
10L, 20L);
assertEquals("type", ScheduledRecording.TYPE_TIMED, actual.getType());
}
+ @Test
public void testBuildFrom() {
ScheduledRecording expected = createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID,
10L, 20L);
@@ -80,6 +86,7 @@ public class ScheduledRecordingTest extends TestCase {
RecordingTestUtils.assertRecordingEquals(expected, actual);
}
+ @Test
public void testBuild_priority() {
ScheduledRecording a = normalizePriority(
createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID, 10L, 20L));
diff --git a/tests/unit/src/com/android/tv/dvr/SchedulerTest.java b/tests/unit/src/com/android/tv/dvr/SchedulerTest.java
deleted file mode 100644
index 30ac1ff1..00000000
--- a/tests/unit/src/com/android/tv/dvr/SchedulerTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2015 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.tv.dvr;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.os.Build;
-import android.os.Looper;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
-
-import com.android.tv.InputSessionManager;
-import com.android.tv.data.ChannelDataManager;
-import com.android.tv.testing.FakeClock;
-import com.android.tv.testing.dvr.RecordingTestUtils;
-import com.android.tv.util.TvInputManagerHelper;
-
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for {@link Scheduler}.
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class SchedulerTest extends AndroidTestCase {
- private static final String INPUT_ID = "input_id";
- private static final int CHANNEL_ID = 273;
-
- private FakeClock mFakeClock;
- private DvrDataManagerInMemoryImpl mDataManager;
- private Scheduler mScheduler;
- @Mock DvrManager mDvrManager;
- @Mock InputSessionManager mSessionManager;
- @Mock AlarmManager mMockAlarmManager;
- @Mock ChannelDataManager mChannelDataManager;
- @Mock TvInputManagerHelper mInputManager;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- MockitoAnnotations.initMocks(this);
- mFakeClock = FakeClock.createWithCurrentTime();
- mDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock);
- Mockito.when(mChannelDataManager.isDbLoadFinished()).thenReturn(true);
- mScheduler = new Scheduler(Looper.myLooper(), mDvrManager, mSessionManager, mDataManager,
- mChannelDataManager, mInputManager, getContext(), mFakeClock, mMockAlarmManager);
- }
-
- public void testUpdate_none() throws Exception {
- mScheduler.start();
- mScheduler.update();
- verifyZeroInteractions(mMockAlarmManager);
- }
-
- public void testUpdate_nextIn12Hours() throws Exception {
- long now = mFakeClock.currentTimeMillis();
- long startTime = now + TimeUnit.HOURS.toMillis(12);
- ScheduledRecording r = RecordingTestUtils
- .createTestRecordingWithPeriod(INPUT_ID, CHANNEL_ID, startTime,
- startTime + TimeUnit.HOURS.toMillis(1));
- mDataManager.addScheduledRecording(r);
- mScheduler.start();
- verify(mMockAlarmManager).set(
- eq(AlarmManager.RTC_WAKEUP),
- eq(startTime - Scheduler.MS_TO_WAKE_BEFORE_START),
- any(PendingIntent.class));
- Mockito.reset(mMockAlarmManager);
- mScheduler.update();
- verify(mMockAlarmManager).set(
- eq(AlarmManager.RTC_WAKEUP),
- eq(startTime - Scheduler.MS_TO_WAKE_BEFORE_START),
- any(PendingIntent.class));
- }
-
- public void testStartsWithin() throws Exception {
- long now = mFakeClock.currentTimeMillis();
- long startTime = now + 3;
- ScheduledRecording r = RecordingTestUtils
- .createTestRecordingWithPeriod(INPUT_ID, CHANNEL_ID, startTime, startTime + 100);
- assertFalse(mScheduler.startsWithin(r, 2));
- assertTrue(mScheduler.startsWithin(r, 3));
- }
-} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/SeriesRecordingSchedulerTest.java b/tests/unit/src/com/android/tv/dvr/SeriesRecordingSchedulerTest.java
deleted file mode 100644
index efefb93c..00000000
--- a/tests/unit/src/com/android/tv/dvr/SeriesRecordingSchedulerTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.os.Build;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
-import android.test.MoreAsserts;
-import android.util.LongSparseArray;
-
-import com.android.tv.data.Program;
-import com.android.tv.testing.FakeClock;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Tests for {@link SeriesRecordingScheduler}
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class SeriesRecordingSchedulerTest extends AndroidTestCase {
- private static final String PROGRAM_TITLE = "MyProgram";
- private static final long CHANNEL_ID = 123;
- private static final long SERIES_RECORDING_ID1 = 1;
- private static final String SERIES_ID = "SERIES_ID";
- private static final String SEASON_NUMBER1 = "SEASON NUMBER1";
- private static final String SEASON_NUMBER2 = "SEASON NUMBER2";
- private static final String EPISODE_NUMBER1 = "EPISODE NUMBER1";
- private static final String EPISODE_NUMBER2 = "EPISODE NUMBER2";
-
- private final SeriesRecording mBaseSeriesRecording = new SeriesRecording.Builder()
- .setTitle(PROGRAM_TITLE).setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
- private final Program mBaseProgram = new Program.Builder().setTitle(PROGRAM_TITLE)
- .setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
-
- private DvrDataManagerInMemoryImpl mDataManager;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- FakeClock fakeClock = FakeClock.createWithCurrentTime();
- mDataManager = new DvrDataManagerInMemoryImpl(getContext(), fakeClock);
- }
-
- public void testPickOneProgramPerEpisode_onePerEpisode() {
- SeriesRecording seriesRecording = SeriesRecording.buildFrom(mBaseSeriesRecording)
- .setId(SERIES_RECORDING_ID1).build();
- mDataManager.addSeriesRecording(seriesRecording);
- List<Program> programs = new ArrayList<>();
- Program program1 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER1)
- .setEpisodeNumber(EPISODE_NUMBER1).build();
- programs.add(program1);
- Program program2 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER2)
- .setEpisodeNumber(EPISODE_NUMBER2).build();
- programs.add(program2);
- LongSparseArray<List<Program>> result = SeriesRecordingScheduler.pickOneProgramPerEpisode(
- mDataManager, Collections.singletonList(seriesRecording), programs);
- MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program2);
- }
-
- public void testPickOneProgramPerEpisode_manyPerEpisode() {
- SeriesRecording seriesRecording = SeriesRecording.buildFrom(mBaseSeriesRecording)
- .setId(SERIES_RECORDING_ID1).build();
- mDataManager.addSeriesRecording(seriesRecording);
- List<Program> programs = new ArrayList<>();
- Program program1 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER1)
- .setEpisodeNumber(EPISODE_NUMBER1).setStartTimeUtcMillis(0).build();
- programs.add(program1);
- Program program2 = new Program.Builder(program1).setStartTimeUtcMillis(1).build();
- programs.add(program2);
- Program program3 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER2)
- .setEpisodeNumber(EPISODE_NUMBER2).build();
- programs.add(program3);
- Program program4 = new Program.Builder(program1).setStartTimeUtcMillis(1).build();
- programs.add(program4);
- LongSparseArray<List<Program>> result = SeriesRecordingScheduler.pickOneProgramPerEpisode(
- mDataManager, Collections.singletonList(seriesRecording), programs);
- MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program3);
- }
-
- public void testPickOneProgramPerEpisode_nullEpisode() {
- SeriesRecording seriesRecording = SeriesRecording.buildFrom(mBaseSeriesRecording)
- .setId(SERIES_RECORDING_ID1).build();
- mDataManager.addSeriesRecording(seriesRecording);
- List<Program> programs = new ArrayList<>();
- Program program1 = new Program.Builder(mBaseProgram).setStartTimeUtcMillis(0).build();
- programs.add(program1);
- Program program2 = new Program.Builder(mBaseProgram).setStartTimeUtcMillis(1).build();
- programs.add(program2);
- LongSparseArray<List<Program>> result = SeriesRecordingScheduler.pickOneProgramPerEpisode(
- mDataManager, Collections.singletonList(seriesRecording), programs);
- MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program2);
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/SeriesRecordingTest.java b/tests/unit/src/com/android/tv/dvr/SeriesRecordingTest.java
deleted file mode 100644
index c48fec02..00000000
--- a/tests/unit/src/com/android/tv/dvr/SeriesRecordingTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2016 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.tv.dvr;
-
-import android.os.Build;
-import android.os.Parcel;
-import android.support.test.filters.SdkSuppress;
-import android.support.test.filters.SmallTest;
-
-import com.android.tv.data.Program;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@link SeriesRecording}.
- */
-@SmallTest
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
-public class SeriesRecordingTest extends TestCase {
- private static final String PROGRAM_TITLE = "MyProgram";
- private static final long CHANNEL_ID = 123;
- private static final long OTHER_CHANNEL_ID = 321;
- private static final String SERIES_ID = "SERIES_ID";
- private static final String OTHER_SERIES_ID = "OTHER_SERIES_ID";
-
- private final SeriesRecording mBaseSeriesRecording = new SeriesRecording.Builder()
- .setTitle(PROGRAM_TITLE).setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
- private final SeriesRecording mSeriesRecordingSeason2 = SeriesRecording
- .buildFrom(mBaseSeriesRecording).setStartFromSeason(2).build();
- private final SeriesRecording mSeriesRecordingSeason2Episode5 = SeriesRecording
- .buildFrom(mSeriesRecordingSeason2).setStartFromEpisode(5).build();
- private final Program mBaseProgram = new Program.Builder().setTitle(PROGRAM_TITLE)
- .setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
-
- public void testParcelable() throws Exception {
- SeriesRecording r1 = new SeriesRecording.Builder()
- .setId(1)
- .setChannelId(2)
- .setPriority(3)
- .setTitle("4")
- .setDescription("5")
- .setLongDescription("5-long")
- .setSeriesId("6")
- .setStartFromEpisode(7)
- .setStartFromSeason(8)
- .setChannelOption(SeriesRecording.OPTION_CHANNEL_ALL)
- .setCanonicalGenreIds(new int[] {9, 10})
- .setPosterUri("11")
- .setPhotoUri("12")
- .build();
- Parcel p1 = Parcel.obtain();
- Parcel p2 = Parcel.obtain();
- try {
- r1.writeToParcel(p1, 0);
- byte[] bytes = p1.marshall();
- p2.unmarshall(bytes, 0, bytes.length);
- p2.setDataPosition(0);
- SeriesRecording r2 = SeriesRecording.fromParcel(p2);
- assertEquals(r1, r2);
- } finally {
- p1.recycle();
- p2.recycle();
- }
- }
-
- public void testDoesProgramMatch_simpleMatch() {
- assertDoesProgramMatch(mBaseProgram, mBaseSeriesRecording, true);
- }
-
- public void testDoesProgramMatch_differentSeriesId() {
- Program program = new Program.Builder(mBaseProgram).setSeriesId(OTHER_SERIES_ID).build();
- assertDoesProgramMatch(program, mBaseSeriesRecording, false);
- }
-
- public void testDoesProgramMatch_differentChannel() {
- Program program = new Program.Builder(mBaseProgram).setChannelId(OTHER_CHANNEL_ID).build();
- assertDoesProgramMatch(program, mBaseSeriesRecording, false);
- }
-
- public void testDoesProgramMatch_startFromSeason2() {
- Program program = mBaseProgram;
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
- program = new Program.Builder(program).setSeasonNumber("1").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, false);
- program = new Program.Builder(program).setSeasonNumber("2").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
- program = new Program.Builder(program).setSeasonNumber("3").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
- }
-
- public void testDoesProgramMatch_startFromSeason2episode5() {
- Program program = mBaseProgram;
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new Program.Builder(program).setSeasonNumber("2").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new Program.Builder(program).setEpisodeNumber("4").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, false);
- program = new Program.Builder(program).setEpisodeNumber("5").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new Program.Builder(program).setEpisodeNumber("6").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- program = new Program.Builder(program).setSeasonNumber("3").setEpisodeNumber("1").build();
- assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
- }
-
- private void assertDoesProgramMatch(Program p, SeriesRecording seriesRecording,
- boolean expected) {
- assertEquals(seriesRecording + " doesProgramMatch " + p, expected,
- seriesRecording.matchProgram(p));
- }
-}
diff --git a/tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java b/tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java
new file mode 100644
index 00000000..790b2ee8
--- /dev/null
+++ b/tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.data;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Build;
+import android.os.Parcel;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+
+import com.android.tv.data.Program;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link SeriesRecording}.
+ */
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class SeriesRecordingTest {
+ private static final String PROGRAM_TITLE = "MyProgram";
+ private static final long CHANNEL_ID = 123;
+ private static final long OTHER_CHANNEL_ID = 321;
+ private static final String SERIES_ID = "SERIES_ID";
+ private static final String OTHER_SERIES_ID = "OTHER_SERIES_ID";
+
+ private final SeriesRecording mBaseSeriesRecording = new SeriesRecording.Builder()
+ .setTitle(PROGRAM_TITLE).setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
+ private final SeriesRecording mSeriesRecordingSeason2 = SeriesRecording
+ .buildFrom(mBaseSeriesRecording).setStartFromSeason(2).build();
+ private final SeriesRecording mSeriesRecordingSeason2Episode5 = SeriesRecording
+ .buildFrom(mSeriesRecordingSeason2).setStartFromEpisode(5).build();
+ private final Program mBaseProgram = new Program.Builder().setTitle(PROGRAM_TITLE)
+ .setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
+
+ @Test
+ public void testParcelable() {
+ SeriesRecording r1 = new SeriesRecording.Builder()
+ .setId(1)
+ .setChannelId(2)
+ .setPriority(3)
+ .setTitle("4")
+ .setDescription("5")
+ .setLongDescription("5-long")
+ .setSeriesId("6")
+ .setStartFromEpisode(7)
+ .setStartFromSeason(8)
+ .setChannelOption(SeriesRecording.OPTION_CHANNEL_ALL)
+ .setCanonicalGenreIds(new int[] {9, 10})
+ .setPosterUri("11")
+ .setPhotoUri("12")
+ .build();
+ Parcel p1 = Parcel.obtain();
+ Parcel p2 = Parcel.obtain();
+ try {
+ r1.writeToParcel(p1, 0);
+ byte[] bytes = p1.marshall();
+ p2.unmarshall(bytes, 0, bytes.length);
+ p2.setDataPosition(0);
+ SeriesRecording r2 = SeriesRecording.fromParcel(p2);
+ assertEquals(r1, r2);
+ } finally {
+ p1.recycle();
+ p2.recycle();
+ }
+ }
+
+ @Test
+ public void testDoesProgramMatch_simpleMatch() {
+ assertDoesProgramMatch(mBaseProgram, mBaseSeriesRecording, true);
+ }
+
+ @Test
+ public void testDoesProgramMatch_differentSeriesId() {
+ Program program = new Program.Builder(mBaseProgram).setSeriesId(OTHER_SERIES_ID).build();
+ assertDoesProgramMatch(program, mBaseSeriesRecording, false);
+ }
+
+ @Test
+ public void testDoesProgramMatch_differentChannel() {
+ Program program = new Program.Builder(mBaseProgram).setChannelId(OTHER_CHANNEL_ID).build();
+ assertDoesProgramMatch(program, mBaseSeriesRecording, false);
+ }
+
+ @Test
+ public void testDoesProgramMatch_startFromSeason2() {
+ Program program = mBaseProgram;
+ assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
+ program = new Program.Builder(program).setSeasonNumber("1").build();
+ assertDoesProgramMatch(program, mSeriesRecordingSeason2, false);
+ program = new Program.Builder(program).setSeasonNumber("2").build();
+ assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
+ program = new Program.Builder(program).setSeasonNumber("3").build();
+ assertDoesProgramMatch(program, mSeriesRecordingSeason2, true);
+ }
+
+ @Test
+ public void testDoesProgramMatch_startFromSeason2episode5() {
+ Program program = mBaseProgram;
+ assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
+ program = new Program.Builder(program).setSeasonNumber("2").build();
+ assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
+ program = new Program.Builder(program).setEpisodeNumber("4").build();
+ assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, false);
+ program = new Program.Builder(program).setEpisodeNumber("5").build();
+ assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
+ program = new Program.Builder(program).setEpisodeNumber("6").build();
+ assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
+ program = new Program.Builder(program).setSeasonNumber("3").setEpisodeNumber("1").build();
+ assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true);
+ }
+
+ private void assertDoesProgramMatch(Program p, SeriesRecording seriesRecording,
+ boolean expected) {
+ assertEquals(seriesRecording + " doesProgramMatch " + p, expected,
+ seriesRecording.matchProgram(p));
+ }
+}
diff --git a/tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java b/tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java
new file mode 100644
index 00000000..94f88a51
--- /dev/null
+++ b/tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.provider;
+
+import static android.support.test.InstrumentationRegistry.getContext;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.Program;
+import com.android.tv.dvr.DvrDataManagerImpl;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.dvr.recorder.SeriesRecordingScheduler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link com.android.tv.dvr.DvrScheduleManager}
+ */
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class DvrDbSyncTest {
+ private static final String INPUT_ID = "input_id";
+ private static final long BASE_PROGRAM_ID = 1;
+ private static final long BASE_START_TIME_MS = 0;
+ private static final long BASE_END_TIME_MS = 1;
+ private static final String BASE_SEASON_NUMBER = "2";
+ private static final String BASE_EPISODE_NUMBER = "3";
+ private static final Program BASE_PROGRAM = new Program.Builder().setId(BASE_PROGRAM_ID)
+ .setStartTimeUtcMillis(BASE_START_TIME_MS).setEndTimeUtcMillis(BASE_END_TIME_MS)
+ .build();
+ private static final Program BASE_SERIES_PROGRAM = new Program.Builder().setId(BASE_PROGRAM_ID)
+ .setStartTimeUtcMillis(BASE_START_TIME_MS).setEndTimeUtcMillis(BASE_END_TIME_MS)
+ .setSeasonNumber(BASE_SEASON_NUMBER).setEpisodeNumber(BASE_EPISODE_NUMBER).build();
+ private static final ScheduledRecording BASE_SCHEDULE =
+ ScheduledRecording.builder(INPUT_ID, BASE_PROGRAM).build();
+ private static final ScheduledRecording BASE_SERIES_SCHEDULE =
+ ScheduledRecording.builder(INPUT_ID, BASE_SERIES_PROGRAM).build();
+
+ private DvrDbSync mDbSync;
+ @Mock private DvrManager mDvrManager;
+ @Mock private DvrDataManagerImpl mDataManager;
+ @Mock private ChannelDataManager mChannelDataManager;
+ @Mock private SeriesRecordingScheduler mSeriesRecordingScheduler;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mChannelDataManager.isDbLoadFinished()).thenReturn(true);
+ when(mDvrManager.addSeriesRecording(anyObject(), anyObject(), anyInt()))
+ .thenReturn(SeriesRecording.builder(INPUT_ID, BASE_PROGRAM).build());
+ mDbSync = new DvrDbSync(getContext(), mDataManager, mChannelDataManager,
+ mDvrManager, mSeriesRecordingScheduler);
+ }
+
+ @Test
+ public void testHandleUpdateProgram_null() {
+ addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE);
+ mDbSync.handleUpdateProgram(null, BASE_PROGRAM_ID);
+ verify(mDataManager).removeScheduledRecording(BASE_SCHEDULE);
+ }
+
+ @Test
+ public void testHandleUpdateProgram_changeTimeNotStarted() {
+ addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE);
+ long startTimeMs = BASE_START_TIME_MS + 1;
+ long endTimeMs = BASE_END_TIME_MS + 1;
+ Program program = new Program.Builder(BASE_PROGRAM).setStartTimeUtcMillis(startTimeMs)
+ .setEndTimeUtcMillis(endTimeMs).build();
+ mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
+ assertUpdateScheduleCalled(program);
+ }
+
+ @Test
+ public void testHandleUpdateProgram_changeTimeInProgressNotCalled() {
+ addSchedule(BASE_PROGRAM_ID, ScheduledRecording.buildFrom(BASE_SCHEDULE)
+ .setState(ScheduledRecording.STATE_RECORDING_IN_PROGRESS).build());
+ long startTimeMs = BASE_START_TIME_MS + 1;
+ Program program = new Program.Builder(BASE_PROGRAM).setStartTimeUtcMillis(startTimeMs)
+ .build();
+ mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
+ verify(mDataManager, never()).updateScheduledRecording(anyObject());
+ }
+
+ @Test
+ public void testHandleUpdateProgram_changeSeason() {
+ addSchedule(BASE_PROGRAM_ID, BASE_SERIES_SCHEDULE);
+ String seasonNumber = BASE_SEASON_NUMBER + "1";
+ String episodeNumber = BASE_EPISODE_NUMBER + "1";
+ Program program = new Program.Builder(BASE_SERIES_PROGRAM).setSeasonNumber(seasonNumber)
+ .setEpisodeNumber(episodeNumber).build();
+ mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
+ assertUpdateScheduleCalled(program);
+ }
+
+ @Test
+ public void testHandleUpdateProgram_finished() {
+ addSchedule(BASE_PROGRAM_ID, ScheduledRecording.buildFrom(BASE_SERIES_SCHEDULE)
+ .setState(ScheduledRecording.STATE_RECORDING_FINISHED).build());
+ String seasonNumber = BASE_SEASON_NUMBER + "1";
+ String episodeNumber = BASE_EPISODE_NUMBER + "1";
+ Program program = new Program.Builder(BASE_SERIES_PROGRAM).setSeasonNumber(seasonNumber)
+ .setEpisodeNumber(episodeNumber).build();
+ mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID);
+ verify(mDataManager, never()).updateScheduledRecording(anyObject());
+ }
+
+ private void addSchedule(long programId, ScheduledRecording schedule) {
+ when(mDataManager.getScheduledRecordingForProgramId(programId)).thenReturn(schedule);
+ }
+
+ private void assertUpdateScheduleCalled(Program program) {
+ verify(mDataManager).updateScheduledRecording(
+ eq(ScheduledRecording.builder(INPUT_ID, program).build()));
+ }
+}
diff --git a/tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java b/tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java
new file mode 100644
index 00000000..216d4d5b
--- /dev/null
+++ b/tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.provider;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+
+import com.android.tv.dvr.data.SeasonEpisodeNumber;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link EpisodicProgramLoadTask}
+ */
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class EpisodicProgramLoadTaskTest {
+ private static final long SERIES_RECORDING_ID1 = 1;
+ private static final long SERIES_RECORDING_ID2 = 2;
+ private static final String SEASON_NUMBER1 = "SEASON NUMBER1";
+ private static final String SEASON_NUMBER2 = "SEASON NUMBER2";
+ private static final String EPISODE_NUMBER1 = "EPISODE NUMBER1";
+ private static final String EPISODE_NUMBER2 = "EPISODE NUMBER2";
+
+ @Test
+ public void testEpisodeAlreadyScheduled_true() {
+ List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>();
+ SeasonEpisodeNumber seasonEpisodeNumber = new SeasonEpisodeNumber(
+ SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1);
+ seasonEpisodeNumbers.add(seasonEpisodeNumber);
+ assertTrue(seasonEpisodeNumbers.contains(
+ new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1)));
+ }
+
+ @Test
+ public void testEpisodeAlreadyScheduled_false() {
+ List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>();
+ SeasonEpisodeNumber seasonEpisodeNumber = new SeasonEpisodeNumber(
+ SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1);
+ seasonEpisodeNumbers.add(seasonEpisodeNumber);
+ assertFalse(seasonEpisodeNumbers.contains(
+ new SeasonEpisodeNumber(SERIES_RECORDING_ID2, SEASON_NUMBER1, EPISODE_NUMBER1)));
+ assertFalse(seasonEpisodeNumbers.contains(
+ new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER2, EPISODE_NUMBER1)));
+ assertFalse(seasonEpisodeNumbers.contains(
+ new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER2)));
+ }
+
+ @Test
+ public void testEpisodeAlreadyScheduled_null() {
+ List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>();
+ SeasonEpisodeNumber seasonEpisodeNumber = new SeasonEpisodeNumber(
+ SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1);
+ seasonEpisodeNumbers.add(seasonEpisodeNumber);
+ assertFalse(seasonEpisodeNumbers.contains(
+ new SeasonEpisodeNumber(SERIES_RECORDING_ID1, null, EPISODE_NUMBER1)));
+ assertFalse(seasonEpisodeNumbers.contains(
+ new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, null)));
+ assertFalse(seasonEpisodeNumbers.contains(
+ new SeasonEpisodeNumber(SERIES_RECORDING_ID1, null, null)));
+ }
+} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/DvrRecordingServiceTest.java b/tests/unit/src/com/android/tv/dvr/recorder/DvrRecordingServiceTest.java
new file mode 100644
index 00000000..8f7dcaf2
--- /dev/null
+++ b/tests/unit/src/com/android/tv/dvr/recorder/DvrRecordingServiceTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.recorder;
+
+import static org.mockito.Mockito.verify;
+
+import android.content.Intent;
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+import android.test.ServiceTestCase;
+
+import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.feature.TestableFeature;
+
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link DvrRecordingService}.
+ */
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class DvrRecordingServiceTest
+ extends ServiceTestCase<DvrRecordingServiceTest.MockDvrRecordingService> {
+ private final TestableFeature mDvrFeature = CommonFeatures.DVR;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mDvrFeature.enableForTest();
+ MockitoAnnotations.initMocks(this);
+ setupService();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mDvrFeature.resetForTests();
+ super.tearDown();
+ }
+
+ public DvrRecordingServiceTest() {
+ super(MockDvrRecordingService.class);
+ }
+
+ public void testStartService_null() throws Exception {
+ // Not recording
+ startService(null);
+ assertFalse(getService().mInForeground);
+
+ // Recording
+ getService().startRecording();
+ startService(null);
+ assertTrue(getService().mInForeground);
+ assertTrue(getService().mIsRecording);
+ getService().reset();
+ }
+
+ public void testStartService_noUpcomingRecording() throws Exception {
+ Intent intent = new Intent(getContext(), DvrRecordingServiceTest.class);
+ intent.putExtra(DvrRecordingService.EXTRA_START_FOR_RECORDING, false);
+
+ // Not recording
+ startService(intent);
+ assertTrue(getService().mInForeground);
+ assertFalse(getService().mForegroundForUpcomingRecording);
+ getService().stopForegroundIfNotRecordingInternal();
+ assertFalse(getService().mInForeground);
+
+ // Recording, ended quickly
+ getService().startRecording();
+ startService(intent);
+ assertTrue(getService().mInForeground);
+ assertTrue(getService().mForegroundForUpcomingRecording);
+ assertTrue(getService().mIsRecording);
+ getService().stopRecording();
+ assertFalse(getService().mInForeground);
+ assertFalse(getService().mIsRecording);
+ getService().stopForegroundIfNotRecordingInternal();
+ assertFalse(getService().mInForeground);
+ assertFalse(getService().mIsRecording);
+ getService().reset();
+
+ // Recording, ended later
+ getService().startRecording();
+ startService(intent);
+ assertTrue(getService().mInForeground);
+ assertTrue(getService().mForegroundForUpcomingRecording);
+ assertTrue(getService().mIsRecording);
+ getService().stopForegroundIfNotRecordingInternal();
+ assertTrue(getService().mInForeground);
+ assertTrue(getService().mForegroundForUpcomingRecording);
+ assertTrue(getService().mIsRecording);
+ getService().stopRecording();
+ assertFalse(getService().mInForeground);
+ assertFalse(getService().mIsRecording);
+ getService().reset();
+ }
+
+ public void testStartService_hasUpcomingRecording() throws Exception {
+ Intent intent = new Intent(getContext(), DvrRecordingServiceTest.class);
+ intent.putExtra(DvrRecordingService.EXTRA_START_FOR_RECORDING, true);
+
+ // Not recording
+ startService(intent);
+ assertTrue(getService().mInForeground);
+ assertTrue(getService().mForegroundForUpcomingRecording);
+ assertFalse(getService().mIsRecording);
+ getService().startRecording();
+ assertTrue(getService().mInForeground);
+ assertTrue(getService().mForegroundForUpcomingRecording);
+ assertTrue(getService().mIsRecording);
+ getService().stopRecording();
+ assertFalse(getService().mInForeground);
+ assertFalse(getService().mIsRecording);
+ getService().reset();
+
+ // Recording
+ getService().startRecording();
+ startService(intent);
+ assertTrue(getService().mInForeground);
+ assertTrue(getService().mForegroundForUpcomingRecording);
+ assertTrue(getService().mIsRecording);
+ getService().startRecording();
+ assertTrue(getService().mInForeground);
+ assertTrue(getService().mForegroundForUpcomingRecording);
+ assertTrue(getService().mIsRecording);
+ getService().stopRecording();
+ assertTrue(getService().mInForeground);
+ assertTrue(getService().mForegroundForUpcomingRecording);
+ assertTrue(getService().mIsRecording);
+ getService().stopRecording();
+ assertFalse(getService().mInForeground);
+ assertFalse(getService().mIsRecording);
+ getService().reset();
+ }
+
+ public static class MockDvrRecordingService extends DvrRecordingService {
+ private int mRecordingCount = 0;
+ private boolean mInForeground;
+ private boolean mForegroundForUpcomingRecording;
+
+ @Override
+ protected void startForegroundInternal(boolean hasUpcomingRecording) {
+ mForegroundForUpcomingRecording = hasUpcomingRecording;
+ mInForeground = true;
+ }
+
+ @Override
+ protected void stopForegroundInternal() {
+ mInForeground = false;
+ }
+
+ private void startRecording() {
+ mOnRecordingSessionChangeListener.onRecordingSessionChange(true, ++mRecordingCount);
+ }
+
+ private void stopRecording() {
+ mOnRecordingSessionChangeListener.onRecordingSessionChange(false, --mRecordingCount);
+ }
+
+ private void reset() {
+ mRecordingCount = 0;
+ mInForeground = false;
+ mIsRecording = false;
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java b/tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java
new file mode 100644
index 00000000..e5c27e2c
--- /dev/null
+++ b/tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.recorder;
+
+import static android.support.test.InstrumentationRegistry.getContext;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AlarmManager;
+import android.media.tv.TvInputInfo;
+import android.os.Build;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+
+import com.android.tv.InputSessionManager;
+import com.android.tv.data.Channel;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.WritableDvrDataManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.recorder.InputTaskScheduler.RecordingTaskFactory;
+import com.android.tv.testing.FakeClock;
+import com.android.tv.testing.dvr.RecordingTestUtils;
+import com.android.tv.util.Clock;
+import com.android.tv.util.TestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for {@link InputTaskScheduler}.
+ */
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class InputTaskSchedulerTest {
+ private static final String INPUT_ID = "input_id";
+ private static final int CHANNEL_ID = 1;
+ private static final long LISTENER_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(1);
+ private static final int TUNER_COUNT_ONE = 1;
+ private static final int TUNER_COUNT_TWO = 2;
+ private static final long LOW_PRIORITY = 1;
+ private static final long HIGH_PRIORITY = 2;
+
+ private FakeClock mFakeClock;
+ private InputTaskScheduler mScheduler;
+ @Mock private DvrManager mDvrManager;
+ @Mock private WritableDvrDataManager mDataManager;
+ @Mock private InputSessionManager mSessionManager;
+ @Mock private AlarmManager mMockAlarmManager;
+ @Mock private ChannelDataManager mChannelDataManager;
+ private List<RecordingTask> mRecordingTasks;
+
+ @Before
+ public void setUp() throws Exception {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ mRecordingTasks = new ArrayList();
+ MockitoAnnotations.initMocks(this);
+ mFakeClock = FakeClock.createWithCurrentTime();
+ TvInputInfo input = createTvInputInfo(TUNER_COUNT_ONE);
+ mScheduler = new InputTaskScheduler(getContext(), input, Looper.myLooper(),
+ mChannelDataManager, mDvrManager, mDataManager, mSessionManager, mFakeClock,
+ new RecordingTaskFactory() {
+ @Override
+ public RecordingTask createRecordingTask(ScheduledRecording scheduledRecording,
+ Channel channel, DvrManager dvrManager,
+ InputSessionManager sessionManager, WritableDvrDataManager dataManager,
+ Clock clock) {
+ RecordingTask task = mock(RecordingTask.class);
+ when(task.getPriority()).thenReturn(scheduledRecording.getPriority());
+ when(task.getEndTimeMs()).thenReturn(scheduledRecording.getEndTimeMs());
+ mRecordingTasks.add(task);
+ return task;
+ }
+ });
+ }
+
+ @Test
+ public void testAddSchedule_past() {
+ ScheduledRecording r = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
+ CHANNEL_ID, 0L, 1L);
+ when(mDataManager.getScheduledRecording(anyLong())).thenReturn(r);
+ mScheduler.handleAddSchedule(r);
+ mScheduler.handleBuildSchedule();
+ verify(mDataManager, timeout((int) LISTENER_TIMEOUT_MS).times(1))
+ .changeState(any(ScheduledRecording.class),
+ eq(ScheduledRecording.STATE_RECORDING_FAILED));
+ }
+
+ @Test
+ public void testAddSchedule_start() {
+ mScheduler.handleAddSchedule(RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
+ CHANNEL_ID, mFakeClock.currentTimeMillis(),
+ mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1)));
+ mScheduler.handleBuildSchedule();
+ verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
+ }
+
+ @Test
+ public void testAddSchedule_consecutiveNoStop() {
+ long startTimeMs = mFakeClock.currentTimeMillis();
+ long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
+ long id = 0;
+ mScheduler.handleAddSchedule(
+ RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
+ LOW_PRIORITY, startTimeMs, endTimeMs));
+ mScheduler.handleBuildSchedule();
+ startTimeMs = endTimeMs;
+ endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
+ mScheduler.handleAddSchedule(
+ RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
+ HIGH_PRIORITY, startTimeMs, endTimeMs));
+ mScheduler.handleBuildSchedule();
+ verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
+ // The first schedule should not be stopped because the second one should wait for the end
+ // of the first schedule.
+ SystemClock.sleep(LISTENER_TIMEOUT_MS);
+ verify(mRecordingTasks.get(0), never()).stop();
+ }
+
+ @Test
+ public void testAddSchedule_consecutiveNoFail() {
+ long startTimeMs = mFakeClock.currentTimeMillis();
+ long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
+ long id = 0;
+ when(mDataManager.getScheduledRecording(anyLong())).thenReturn(ScheduledRecording
+ .builder(INPUT_ID, CHANNEL_ID, 0L, 0L).build());
+ mScheduler.handleAddSchedule(
+ RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
+ HIGH_PRIORITY, startTimeMs, endTimeMs));
+ mScheduler.handleBuildSchedule();
+ startTimeMs = endTimeMs;
+ endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
+ mScheduler.handleAddSchedule(
+ RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
+ LOW_PRIORITY, startTimeMs, endTimeMs));
+ mScheduler.handleBuildSchedule();
+ verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
+ SystemClock.sleep(LISTENER_TIMEOUT_MS);
+ verify(mRecordingTasks.get(0), never()).stop();
+ // The second schedule should not fail because it can starts after the first one finishes.
+ SystemClock.sleep(LISTENER_TIMEOUT_MS);
+ verify(mDataManager, never())
+ .changeState(any(ScheduledRecording.class),
+ eq(ScheduledRecording.STATE_RECORDING_FAILED));
+ }
+
+ @Test
+ public void testAddSchedule_consecutiveUseLessSession() throws Exception {
+ TvInputInfo input = createTvInputInfo(TUNER_COUNT_TWO);
+ mScheduler.updateTvInputInfo(input);
+ long startTimeMs = mFakeClock.currentTimeMillis();
+ long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
+ long id = 0;
+ mScheduler.handleAddSchedule(
+ RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
+ LOW_PRIORITY, startTimeMs, endTimeMs));
+ mScheduler.handleBuildSchedule();
+ startTimeMs = endTimeMs;
+ endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1);
+ mScheduler.handleAddSchedule(
+ RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod(++id, CHANNEL_ID,
+ HIGH_PRIORITY, startTimeMs, endTimeMs));
+ mScheduler.handleBuildSchedule();
+ verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start();
+ SystemClock.sleep(LISTENER_TIMEOUT_MS);
+ verify(mRecordingTasks.get(0), never()).stop();
+ // The second schedule should wait until the first one finishes rather than creating a new
+ // session even though there are available tuners.
+ assertTrue(mRecordingTasks.size() == 1);
+ }
+
+ @Test
+ public void testUpdateSchedule_noCancel() {
+ ScheduledRecording r = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
+ CHANNEL_ID, mFakeClock.currentTimeMillis(),
+ mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1));
+ mScheduler.handleAddSchedule(r);
+ mScheduler.handleBuildSchedule();
+ mScheduler.handleUpdateSchedule(r);
+ SystemClock.sleep(LISTENER_TIMEOUT_MS);
+ verify(mRecordingTasks.get(0), never()).cancel();
+ }
+
+ @Test
+ public void testUpdateSchedule_cancel() {
+ ScheduledRecording r = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
+ CHANNEL_ID, mFakeClock.currentTimeMillis(),
+ mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(2));
+ mScheduler.handleAddSchedule(r);
+ mScheduler.handleBuildSchedule();
+ mScheduler.handleUpdateSchedule(ScheduledRecording.buildFrom(r)
+ .setStartTimeMs(mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1))
+ .build());
+ verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).cancel();
+ }
+
+ private TvInputInfo createTvInputInfo(int tunerCount) throws Exception {
+ return TestUtils.createTvInputInfo(null, null, null, 0, false, true, tunerCount);
+ }
+}
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java b/tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java
new file mode 100644
index 00000000..37561a42
--- /dev/null
+++ b/tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.recorder;
+
+import static android.support.test.InstrumentationRegistry.getContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+
+import com.android.tv.InputSessionManager;
+import com.android.tv.InputSessionManager.RecordingSession;
+import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.feature.TestableFeature;
+import com.android.tv.data.Channel;
+import com.android.tv.dvr.DvrDataManagerInMemoryImpl;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.dvr.recorder.RecordingTask.State;
+import com.android.tv.testing.FakeClock;
+import com.android.tv.testing.dvr.RecordingTestUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for {@link RecordingTask}.
+ */
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class RecordingTaskTest {
+ private static final long DURATION = TimeUnit.MINUTES.toMillis(30);
+ private static final long START_OFFSET_MS = RecordingScheduler.MS_TO_WAKE_BEFORE_START;
+ private static final String INPUT_ID = "input_id";
+ private static final int CHANNEL_ID = 273;
+
+ private FakeClock mFakeClock;
+ private DvrDataManagerInMemoryImpl mDataManager;
+ @Mock Handler mMockHandler;
+ @Mock DvrManager mDvrManager;
+ @Mock InputSessionManager mMockSessionManager;
+ @Mock RecordingSession mMockRecordingSession;
+ private final TestableFeature mDvrFeature = CommonFeatures.DVR;
+
+ @Before
+ public void setUp() {
+ mDvrFeature.enableForTest();
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ MockitoAnnotations.initMocks(this);
+ mFakeClock = FakeClock.createWithCurrentTime();
+ mDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock);
+ }
+
+ @After
+ public void tearDown() {
+ mDvrFeature.resetForTests();
+ }
+
+ @Test
+ public void testHandle_init() {
+ Channel channel = createTestChannel();
+ ScheduledRecording r = createRecording(channel);
+ RecordingTask task = createRecordingTask(r, channel);
+ String inputId = channel.getInputId();
+ when(mMockSessionManager.createRecordingSession(eq(inputId), anyString(), eq(task),
+ eq(mMockHandler), anyLong())).thenReturn(mMockRecordingSession);
+ when(mMockHandler.sendMessageAtTime(anyObject(), anyLong())).thenReturn(true);
+ assertTrue(task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE)));
+ assertEquals(State.CONNECTION_PENDING, task.getState());
+ verify(mMockSessionManager).createRecordingSession(eq(inputId), anyString(), eq(task),
+ eq(mMockHandler), anyLong());
+ verify(mMockRecordingSession).tune(eq(inputId), eq(channel.getUri()));
+ verifyNoMoreInteractions(mMockHandler, mMockRecordingSession, mMockSessionManager);
+ }
+
+ private static Channel createTestChannel() {
+ return new Channel.Builder().setInputId(INPUT_ID).setId(CHANNEL_ID)
+ .setDisplayName("Test Ch " + CHANNEL_ID).build();
+ }
+
+ @Test
+ public void testOnConnected() {
+ Channel channel = createTestChannel();
+ ScheduledRecording r = createRecording(channel);
+ mDataManager.addScheduledRecording(r);
+ RecordingTask task = createRecordingTask(r, channel);
+ String inputId = channel.getInputId();
+ when(mMockSessionManager.createRecordingSession(eq(inputId), anyString(), eq(task),
+ eq(mMockHandler), anyLong())).thenReturn(mMockRecordingSession);
+ when(mMockHandler.sendMessageAtTime(anyObject(), anyLong())).thenReturn(true);
+ task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE));
+ task.onTuned(channel.getUri());
+ assertEquals(State.CONNECTED, task.getState());
+ }
+
+ private ScheduledRecording createRecording(Channel c) {
+ long startTime = mFakeClock.currentTimeMillis() + START_OFFSET_MS;
+ long endTime = startTime + DURATION;
+ return RecordingTestUtils.createTestRecordingWithPeriod(c.getInputId(), c.getId(),
+ startTime, endTime);
+ }
+
+ private RecordingTask createRecordingTask(ScheduledRecording r, Channel channel) {
+ RecordingTask recordingTask = new RecordingTask(getContext(), r, channel, mDvrManager,
+ mMockSessionManager, mDataManager, mFakeClock);
+ recordingTask.setHandler(mMockHandler);
+ return recordingTask;
+ }
+
+ private Message createMessage(int what) {
+ Message msg = new Message();
+ msg.setTarget(mMockHandler);
+ msg.what = what;
+ return msg;
+ }
+} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java b/tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java
new file mode 100644
index 00000000..ca72e13f
--- /dev/null
+++ b/tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.recorder;
+
+import static android.support.test.InstrumentationRegistry.getContext;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+import android.test.MoreAsserts;
+
+import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.feature.TestableFeature;
+import com.android.tv.dvr.DvrDataManagerInMemoryImpl;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.testing.FakeClock;
+import com.android.tv.testing.dvr.RecordingTestUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for {@link ScheduledProgramReaper}.
+ */
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class ScheduledProgramReaperTest {
+ private static final String INPUT_ID = "input_id";
+ private static final int CHANNEL_ID = 273;
+ private static final long DURATION = TimeUnit.HOURS.toMillis(1);
+
+ private ScheduledProgramReaper mReaper;
+ private FakeClock mFakeClock;
+ private DvrDataManagerInMemoryImpl mDvrDataManager;
+ @Mock private DvrManager mDvrManager;
+ private final TestableFeature mDvrFeature = CommonFeatures.DVR;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mDvrFeature.enableForTest();
+ mFakeClock = FakeClock.createWithTimeOne();
+ mDvrDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock);
+ mReaper = new ScheduledProgramReaper(mDvrDataManager, mFakeClock);
+ }
+
+ @After
+ public void tearDown() {
+ mDvrFeature.resetForTests();
+ }
+
+ @Test
+ public void testRun_noRecordings() {
+ assertTrue(mDvrDataManager.getAllScheduledRecordings().isEmpty());
+ mReaper.run();
+ assertTrue(mDvrDataManager.getAllScheduledRecordings().isEmpty());
+ }
+
+ @Test
+ public void testRun_oneRecordingsTomorrow() {
+ ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
+ MoreAsserts
+ .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
+ mReaper.run();
+ MoreAsserts
+ .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
+ }
+
+ @Test
+ public void testRun_oneRecordingsStarted() {
+ ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
+ MoreAsserts
+ .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
+ mFakeClock.increment(TimeUnit.DAYS);
+ mReaper.run();
+ MoreAsserts
+ .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
+ }
+
+ @Test
+ public void testRun_oneRecordingsFinished() {
+ ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
+ MoreAsserts
+ .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
+ mFakeClock.increment(TimeUnit.DAYS);
+ mFakeClock.increment(TimeUnit.MINUTES, 2);
+ mReaper.run();
+ MoreAsserts
+ .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
+ }
+
+ @Test
+ public void testRun_oneRecordingsExpired() {
+ ScheduledRecording recording = addNewScheduledRecordingForTomorrow();
+ MoreAsserts
+ .assertContentsInAnyOrder(mDvrDataManager.getAllScheduledRecordings(), recording);
+ mFakeClock.increment(TimeUnit.DAYS, 1 + ScheduledProgramReaper.DAYS);
+ mFakeClock.increment(TimeUnit.MILLISECONDS, DURATION);
+ // After the cutoff and enough so we can see on the clock
+ mFakeClock.increment(TimeUnit.SECONDS, 1);
+
+ mReaper.run();
+ assertTrue("Recordings after reaper at " + com.android.tv.util.Utils
+ .toIsoDateTimeString(mFakeClock.currentTimeMillis()),
+ mDvrDataManager.getAllScheduledRecordings().isEmpty());
+ }
+
+ private ScheduledRecording addNewScheduledRecordingForTomorrow() {
+ long startTime = mFakeClock.currentTimeMillis() + TimeUnit.DAYS.toMillis(1);
+ ScheduledRecording recording = RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID,
+ CHANNEL_ID, startTime, startTime + DURATION);
+ return mDvrDataManager.addScheduledRecordingInternal(
+ ScheduledRecording.buildFrom(recording)
+ .setState(ScheduledRecording.STATE_RECORDING_FINISHED).build());
+ }
+}
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java b/tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java
new file mode 100644
index 00000000..a5154729
--- /dev/null
+++ b/tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2015 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.tv.dvr.recorder;
+
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.os.Build;
+import android.os.Looper;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+
+import com.android.tv.InputSessionManager;
+import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.feature.TestableFeature;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.dvr.DvrDataManagerInMemoryImpl;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.data.ScheduledRecording;
+import com.android.tv.testing.FakeClock;
+import com.android.tv.testing.dvr.RecordingTestUtils;
+import com.android.tv.util.TvInputManagerHelper;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for {@link RecordingScheduler}.
+ */
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class SchedulerTest {
+ private static final String INPUT_ID = "input_id";
+ private static final int CHANNEL_ID = 273;
+
+ private FakeClock mFakeClock;
+ private DvrDataManagerInMemoryImpl mDataManager;
+ private RecordingScheduler mScheduler;
+ @Mock DvrManager mDvrManager;
+ @Mock InputSessionManager mSessionManager;
+ @Mock AlarmManager mMockAlarmManager;
+ @Mock ChannelDataManager mChannelDataManager;
+ @Mock TvInputManagerHelper mInputManager;
+ private final TestableFeature mDvrFeature = CommonFeatures.DVR;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mDvrFeature.enableForTest();
+ mFakeClock = FakeClock.createWithCurrentTime();
+ mDataManager = new DvrDataManagerInMemoryImpl(getTargetContext(), mFakeClock);
+ Mockito.when(mChannelDataManager.isDbLoadFinished()).thenReturn(true);
+ mScheduler = new RecordingScheduler(Looper.myLooper(), mDvrManager, mSessionManager, mDataManager,
+ mChannelDataManager, mInputManager, getTargetContext(), mFakeClock,
+ mMockAlarmManager);
+ }
+
+ @After
+ public void tearDown() {
+ mDvrFeature.resetForTests();
+ }
+
+ @Test
+ public void testUpdate_none() {
+ mScheduler.updateAndStartServiceIfNeeded();
+ verifyZeroInteractions(mMockAlarmManager);
+ }
+
+ @Test
+ public void testUpdate_nextIn12Hours() {
+ long now = mFakeClock.currentTimeMillis();
+ long startTime = now + TimeUnit.HOURS.toMillis(12);
+ ScheduledRecording r = RecordingTestUtils
+ .createTestRecordingWithPeriod(INPUT_ID, CHANNEL_ID, startTime,
+ startTime + TimeUnit.HOURS.toMillis(1));
+ mDataManager.addScheduledRecording(r);
+ verify(mMockAlarmManager).setExactAndAllowWhileIdle(
+ eq(AlarmManager.RTC_WAKEUP),
+ eq(startTime - RecordingScheduler.MS_TO_WAKE_BEFORE_START),
+ any(PendingIntent.class));
+ Mockito.reset(mMockAlarmManager);
+ mScheduler.updateAndStartServiceIfNeeded();
+ verify(mMockAlarmManager).setExactAndAllowWhileIdle(
+ eq(AlarmManager.RTC_WAKEUP),
+ eq(startTime - RecordingScheduler.MS_TO_WAKE_BEFORE_START),
+ any(PendingIntent.class));
+ }
+
+ @Test
+ public void testStartsWithin() {
+ long now = mFakeClock.currentTimeMillis();
+ long startTime = now + 3;
+ ScheduledRecording r = RecordingTestUtils
+ .createTestRecordingWithPeriod(INPUT_ID, CHANNEL_ID, startTime, startTime + 100);
+ assertFalse(mScheduler.startsWithin(r, 2));
+ assertTrue(mScheduler.startsWithin(r, 3));
+ }
+} \ No newline at end of file
diff --git a/tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java b/tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java
new file mode 100644
index 00000000..16fa1baf
--- /dev/null
+++ b/tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 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.tv.dvr.recorder;
+
+import static android.support.test.InstrumentationRegistry.getContext;
+
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+import android.test.MoreAsserts;
+import android.util.LongSparseArray;
+
+import com.android.tv.common.feature.CommonFeatures;
+import com.android.tv.common.feature.TestableFeature;
+import com.android.tv.data.Program;
+import com.android.tv.dvr.DvrDataManagerInMemoryImpl;
+import com.android.tv.dvr.data.SeriesRecording;
+import com.android.tv.testing.FakeClock;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Tests for {@link SeriesRecordingScheduler}
+ */
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+public class SeriesRecordingSchedulerTest {
+ private static final String PROGRAM_TITLE = "MyProgram";
+ private static final long CHANNEL_ID = 123;
+ private static final long SERIES_RECORDING_ID1 = 1;
+ private static final String SERIES_ID = "SERIES_ID";
+ private static final String SEASON_NUMBER1 = "SEASON NUMBER1";
+ private static final String SEASON_NUMBER2 = "SEASON NUMBER2";
+ private static final String EPISODE_NUMBER1 = "EPISODE NUMBER1";
+ private static final String EPISODE_NUMBER2 = "EPISODE NUMBER2";
+
+ private final SeriesRecording mBaseSeriesRecording = new SeriesRecording.Builder()
+ .setTitle(PROGRAM_TITLE).setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
+ private final Program mBaseProgram = new Program.Builder().setTitle(PROGRAM_TITLE)
+ .setChannelId(CHANNEL_ID).setSeriesId(SERIES_ID).build();
+ private final TestableFeature mDvrFeature = CommonFeatures.DVR;
+
+ private DvrDataManagerInMemoryImpl mDataManager;
+
+ @Before
+ public void setUp() {
+ mDvrFeature.enableForTest();
+ FakeClock fakeClock = FakeClock.createWithCurrentTime();
+ mDataManager = new DvrDataManagerInMemoryImpl(getContext(), fakeClock);
+ }
+
+ @After
+ public void tearDown() {
+ mDvrFeature.resetForTests();
+ }
+
+ @Test
+ public void testPickOneProgramPerEpisode_onePerEpisode() {
+ SeriesRecording seriesRecording = SeriesRecording.buildFrom(mBaseSeriesRecording)
+ .setId(SERIES_RECORDING_ID1).build();
+ mDataManager.addSeriesRecording(seriesRecording);
+ List<Program> programs = new ArrayList<>();
+ Program program1 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER1)
+ .setEpisodeNumber(EPISODE_NUMBER1).build();
+ programs.add(program1);
+ Program program2 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER2)
+ .setEpisodeNumber(EPISODE_NUMBER2).build();
+ programs.add(program2);
+ LongSparseArray<List<Program>> result = SeriesRecordingScheduler.pickOneProgramPerEpisode(
+ mDataManager, Collections.singletonList(seriesRecording), programs);
+ MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program2);
+ }
+
+ @Test
+ public void testPickOneProgramPerEpisode_manyPerEpisode() {
+ SeriesRecording seriesRecording = SeriesRecording.buildFrom(mBaseSeriesRecording)
+ .setId(SERIES_RECORDING_ID1).build();
+ mDataManager.addSeriesRecording(seriesRecording);
+ List<Program> programs = new ArrayList<>();
+ Program program1 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER1)
+ .setEpisodeNumber(EPISODE_NUMBER1).setStartTimeUtcMillis(0).build();
+ programs.add(program1);
+ Program program2 = new Program.Builder(program1).setStartTimeUtcMillis(1).build();
+ programs.add(program2);
+ Program program3 = new Program.Builder(mBaseProgram).setSeasonNumber(SEASON_NUMBER2)
+ .setEpisodeNumber(EPISODE_NUMBER2).build();
+ programs.add(program3);
+ Program program4 = new Program.Builder(program1).setStartTimeUtcMillis(1).build();
+ programs.add(program4);
+ LongSparseArray<List<Program>> result = SeriesRecordingScheduler.pickOneProgramPerEpisode(
+ mDataManager, Collections.singletonList(seriesRecording), programs);
+ MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program3);
+ }
+
+ @Test
+ public void testPickOneProgramPerEpisode_nullEpisode() {
+ SeriesRecording seriesRecording = SeriesRecording.buildFrom(mBaseSeriesRecording)
+ .setId(SERIES_RECORDING_ID1).build();
+ mDataManager.addSeriesRecording(seriesRecording);
+ List<Program> programs = new ArrayList<>();
+ Program program1 = new Program.Builder(mBaseProgram).setStartTimeUtcMillis(0).build();
+ programs.add(program1);
+ Program program2 = new Program.Builder(mBaseProgram).setStartTimeUtcMillis(1).build();
+ programs.add(program2);
+ LongSparseArray<List<Program>> result = SeriesRecordingScheduler.pickOneProgramPerEpisode(
+ mDataManager, Collections.singletonList(seriesRecording), programs);
+ MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program2);
+ }
+}
diff --git a/tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java b/tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java
index a571e626..5667ee6b 100644
--- a/tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java
+++ b/tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java
@@ -22,6 +22,9 @@ import android.support.v17.leanback.widget.ObjectAdapter;
import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
@@ -31,29 +34,30 @@ import java.util.Objects;
*/
@SmallTest
public class SortedArrayAdapterTest extends TestCase {
-
- public static final TestData P1 = TestData.create(1, "one");
- public static final TestData P2 = TestData.create(2, "before");
- public static final TestData P3 = TestData.create(3, "other");
- public static final TestData EXTRA = TestData.create(4, "extra");
+ public static final TestData P1 = TestData.create(1, "c");
+ public static final TestData P2 = TestData.create(2, "b");
+ public static final TestData P3 = TestData.create(3, "a");
+ public static final TestData EXTRA = TestData.create(4, "k");
private TestSortedArrayAdapter mAdapter;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
mAdapter = new TestSortedArrayAdapter(Integer.MAX_VALUE, null);
}
+ @Test
public void testContents_empty() {
assertEmpty();
}
+ @Test
public void testAdd_one() {
mAdapter.add(P1);
assertNotEmpty();
assertContentsInOrder(mAdapter, P1);
}
+ @Test
public void testAdd_two() {
mAdapter.add(P1);
mAdapter.add(P2);
@@ -61,12 +65,14 @@ public class SortedArrayAdapterTest extends TestCase {
assertContentsInOrder(mAdapter, P2, P1);
}
+ @Test
public void testSetInitialItems_two() {
mAdapter.setInitialItems(Arrays.asList(P1, P2));
assertNotEmpty();
assertContentsInOrder(mAdapter, P2, P1);
}
+ @Test
public void testMaxInitialCount() {
mAdapter = new TestSortedArrayAdapter(1, null);
mAdapter.setInitialItems(Arrays.asList(P1, P2));
@@ -75,6 +81,7 @@ public class SortedArrayAdapterTest extends TestCase {
assertEquals(mAdapter.get(0), P2);
}
+ @Test
public void testExtraItem() {
mAdapter = new TestSortedArrayAdapter(Integer.MAX_VALUE, EXTRA);
mAdapter.setInitialItems(Arrays.asList(P1, P2));
@@ -88,6 +95,7 @@ public class SortedArrayAdapterTest extends TestCase {
assertEquals(mAdapter.get(0), EXTRA);
}
+ @Test
public void testExtraItemWithMaxCount() {
mAdapter = new TestSortedArrayAdapter(1, EXTRA);
mAdapter.setInitialItems(Arrays.asList(P1, P2));
@@ -100,6 +108,7 @@ public class SortedArrayAdapterTest extends TestCase {
assertEquals(mAdapter.get(0), EXTRA);
}
+ @Test
public void testRemove() {
mAdapter.add(P1);
mAdapter.add(P2);
@@ -111,8 +120,47 @@ public class SortedArrayAdapterTest extends TestCase {
assertContentsInOrder(mAdapter, P1);
mAdapter.remove(P1);
assertEmpty();
+ mAdapter.add(P1);
+ mAdapter.add(P2);
+ mAdapter.add(P3);
+ assertContentsInOrder(mAdapter, P3, P2, P1);
+ mAdapter.removeItems(0, 2);
+ assertContentsInOrder(mAdapter, P1);
+ mAdapter.add(P2);
+ mAdapter.add(P3);
+ mAdapter.addExtraItem(EXTRA);
+ assertContentsInOrder(mAdapter, P3, P2, P1, EXTRA);
+ mAdapter.removeItems(1, 1);
+ assertContentsInOrder(mAdapter, P3, P1, EXTRA);
+ mAdapter.removeItems(1, 2);
+ assertContentsInOrder(mAdapter, P3);
+ mAdapter.addExtraItem(EXTRA);
+ mAdapter.addExtraItem(P2);
+ mAdapter.add(P1);
+ assertContentsInOrder(mAdapter, P3, P1, EXTRA, P2);
+ mAdapter.removeItems(1, 2);
+ assertContentsInOrder(mAdapter, P3, P2);
+ mAdapter.add(P1);
+ assertContentsInOrder(mAdapter, P3, P1, P2);
+ }
+
+ @Test
+ public void testReplace() {
+ mAdapter.add(P1);
+ mAdapter.add(P2);
+ assertNotEmpty();
+ assertContentsInOrder(mAdapter, P2, P1);
+ mAdapter.replace(1, P3);
+ assertContentsInOrder(mAdapter, P3, P2);
+ mAdapter.replace(0, P1);
+ assertContentsInOrder(mAdapter, P2, P1);
+ mAdapter.addExtraItem(EXTRA);
+ assertContentsInOrder(mAdapter, P2, P1, EXTRA);
+ mAdapter.replace(2, P3);
+ assertContentsInOrder(mAdapter, P2, P1, P3);
}
+ @Test
public void testChange_sorting() {
TestData p2_changed = TestData.create(2, "z changed");
mAdapter.add(P1);
@@ -123,6 +171,7 @@ public class SortedArrayAdapterTest extends TestCase {
assertContentsInOrder(mAdapter, P1, p2_changed);
}
+ @Test
public void testChange_new() {
mAdapter.change(P1);
assertNotEmpty();
@@ -194,7 +243,7 @@ public class SortedArrayAdapterTest extends TestCase {
}
@Override
- long getId(TestData item) {
+ protected long getId(TestData item) {
return item.mId;
}
}
diff --git a/tests/unit/src/com/android/tv/experiments/ExperimentsTest.java b/tests/unit/src/com/android/tv/experiments/ExperimentsTest.java
new file mode 100644
index 00000000..3f827ce1
--- /dev/null
+++ b/tests/unit/src/com/android/tv/experiments/ExperimentsTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 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.tv.experiments;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.filters.SmallTest;
+
+import com.android.tv.common.BuildConfig;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link Experiments}.
+ */
+@SmallTest
+public class ExperimentsTest {
+ @Before
+ public void setUp() {
+ ExperimentFlag.initForTest();
+ }
+
+
+ @Test
+ public void testEngOnlyDefault() {
+ assertEquals("ENABLE_DEVELOPER_FEATURES", Boolean.valueOf(BuildConfig.ENG),
+ Experiments.ENABLE_DEVELOPER_FEATURES.get());
+ }
+
+
+}
diff --git a/tests/unit/src/com/android/tv/menu/MenuTest.java b/tests/unit/src/com/android/tv/menu/MenuTest.java
index 35e2a0fe..e8cfdbef 100644
--- a/tests/unit/src/com/android/tv/menu/MenuTest.java
+++ b/tests/unit/src/com/android/tv/menu/MenuTest.java
@@ -15,11 +15,16 @@
*/
package com.android.tv.menu;
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
import com.android.tv.menu.Menu.OnMenuVisibilityChangeListener;
+import org.junit.Before;
+import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
@@ -29,23 +34,23 @@ import org.mockito.stubbing.Answer;
* Tests for {@link Menu}.
*/
@SmallTest
-public class MenuTest extends AndroidTestCase {
+public class MenuTest {
private Menu mMenu;
private IMenuView mMenuView;
private OnMenuVisibilityChangeListener mVisibilityChangeListener;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
mMenuView = Mockito.mock(IMenuView.class);
MenuRowFactory factory = Mockito.mock(MenuRowFactory.class);
Mockito.when(factory.createMenuRow(Mockito.any(Menu.class), Mockito.any(Class.class)))
.thenReturn(null);
mVisibilityChangeListener = Mockito.mock(OnMenuVisibilityChangeListener.class);
- mMenu = new Menu(getContext(), mMenuView, factory, mVisibilityChangeListener);
+ mMenu = new Menu(getTargetContext(), mMenuView, factory, mVisibilityChangeListener);
mMenu.disableAnimationForTest();
}
+ @Test
public void testScheduleHide() {
mMenu.show(Menu.REASON_NONE);
setMenuVisible(true);
@@ -67,6 +72,7 @@ public class MenuTest extends AndroidTestCase {
assertFalse("Hide is scheduled", mMenu.isHideScheduled());
}
+ @Test
public void testShowHide_ReasonNone() {
// Show with REASON_NONE
mMenu.show(Menu.REASON_NONE);
@@ -87,6 +93,7 @@ public class MenuTest extends AndroidTestCase {
Mockito.verify(mMenuView).onHide();
}
+ @Test
public void testShowHide_ReasonGuide() {
// Show with REASON_GUIDE
mMenu.show(Menu.REASON_GUIDE);
@@ -107,6 +114,7 @@ public class MenuTest extends AndroidTestCase {
Mockito.verify(mMenuView).onHide();
}
+ @Test
public void testShowHide_ReasonPlayControlsFastForward() {
// Show with REASON_PLAY_CONTROLS_FAST_FORWARD
mMenu.show(Menu.REASON_PLAY_CONTROLS_FAST_FORWARD);
diff --git a/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java b/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
index 6b0726d9..49ba8514 100644
--- a/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
+++ b/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java
@@ -15,18 +15,24 @@
*/
package com.android.tv.menu;
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
import android.media.tv.TvTrackInfo;
import android.os.SystemClock;
import android.support.test.filters.MediumTest;
+import android.text.TextUtils;
import com.android.tv.BaseMainActivityTestCase;
-import com.android.tv.MainActivity;
-import com.android.tv.customization.CustomAction;
import com.android.tv.testing.Constants;
-import com.android.tv.testing.Utils;
+import com.android.tv.testing.testinput.ChannelState;
import com.android.tv.testing.testinput.ChannelStateData;
import com.android.tv.testing.testinput.TvTestInputConstants;
+import org.junit.Before;
+import org.junit.Test;
+
import java.util.Collections;
import java.util.List;
@@ -35,24 +41,22 @@ import java.util.List;
*/
@MediumTest
public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
- private static final int WAIT_TRACK_SIZE_TIMEOUT_MS = 300;
- public static final int TRACK_SIZE_CHECK_INTERVAL_MS = 10;
+ private static final int WAIT_TRACK_EVENT_TIMEOUT_MS = 300;
+ public static final int TRACK_CHECK_INTERVAL_MS = 10;
// TODO: Refactor TvOptionsRowAdapter so it does not rely on MainActivity
private TvOptionsRowAdapter mTvOptionsRowAdapter;
- public TvOptionsRowAdapterTest() {
- super(MainActivity.class);
- }
-
@Override
- protected void setUp() throws Exception {
+ @Before
+ public void setUp() {
super.setUp();
mTvOptionsRowAdapter = new TvOptionsRowAdapter(mActivity, Collections.emptyList());
tuneToChannel(TvTestInputConstants.CH_1_DEFAULT_DONT_MODIFY);
waitUntilAudioTracksHaveSize(1);
+ waitUntilAudioTrackSelected(ChannelState.DEFAULT.getSelectedAudioTrackId());
// update should be called on the main thread to avoid the multi-thread problem.
- Utils.runOnMainSync(new Runnable() {
+ getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
mTvOptionsRowAdapter.update();
@@ -60,11 +64,13 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
});
}
+ @Test
public void testUpdateAudioAction_2tracks() {
ChannelStateData data = new ChannelStateData();
data.mTvTrackInfos.add(Constants.GENERIC_AUDIO_TRACK);
updateThenTune(data, TvTestInputConstants.CH_2);
waitUntilAudioTracksHaveSize(2);
+ waitUntilAudioTrackSelected(Constants.EN_STEREO_AUDIO_TRACK.getId());
boolean result = mTvOptionsRowAdapter.updateMultiAudioAction();
assertEquals("update Action had change", true, result);
@@ -72,46 +78,87 @@ public class TvOptionsRowAdapterTest extends BaseMainActivityTestCase {
MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled());
}
+ @Test
public void testUpdateAudioAction_1track() {
ChannelStateData data = new ChannelStateData();
data.mTvTrackInfos.clear();
data.mTvTrackInfos.add(Constants.GENERIC_AUDIO_TRACK);
+ data.mSelectedVideoTrackId = null;
+ data.mSelectedAudioTrackId = Constants.GENERIC_AUDIO_TRACK.getId();
updateThenTune(data, TvTestInputConstants.CH_2);
waitUntilAudioTracksHaveSize(1);
+ waitUntilAudioTrackSelected(Constants.GENERIC_AUDIO_TRACK.getId());
boolean result = mTvOptionsRowAdapter.updateMultiAudioAction();
- assertEquals("update Action had change", false, result);
+ assertEquals("update Action had change", true, result);
assertEquals("Multi Audio enabled", false,
MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled());
}
+ @Test
public void testUpdateAudioAction_noTracks() {
ChannelStateData data = new ChannelStateData();
data.mTvTrackInfos.clear();
+ data.mTvTrackInfos.add(ChannelState.DEFAULT_VIDEO_TRACK);
+ data.mSelectedVideoTrackId = ChannelState.DEFAULT_VIDEO_TRACK.getId();
+ data.mSelectedAudioTrackId = null;
updateThenTune(data, TvTestInputConstants.CH_2);
- waitUntilAudioTracksHaveSize(0);
+ // Wait for the video tracks, because there's no audio track.
+ waitUntilVideoTracksHaveSize(1);
+ waitUntilVideoTrackSelected(data.mSelectedVideoTrackId);
boolean result = mTvOptionsRowAdapter.updateMultiAudioAction();
- assertEquals("update Action had change", false, result);
+ assertEquals("update Action had change", true, result);
assertEquals("Multi Audio enabled", false,
MenuAction.SELECT_AUDIO_LANGUAGE_ACTION.isEnabled());
}
private void waitUntilAudioTracksHaveSize(int expected) {
+ waitUntilTracksHaveSize(TvTrackInfo.TYPE_AUDIO, expected);
+ }
+
+ private void waitUntilVideoTracksHaveSize(int expected) {
+ waitUntilTracksHaveSize(TvTrackInfo.TYPE_VIDEO, expected);
+ }
+
+ private void waitUntilTracksHaveSize(int trackType, int expected) {
long start = SystemClock.elapsedRealtime();
int size = -1;
- while (SystemClock.elapsedRealtime() < start + WAIT_TRACK_SIZE_TIMEOUT_MS) {
+ while (SystemClock.elapsedRealtime() < start + WAIT_TRACK_EVENT_TIMEOUT_MS) {
getInstrumentation().waitForIdleSync();
- List<TvTrackInfo> tracks = mActivity.getTracks(TvTrackInfo.TYPE_AUDIO);
+ List<TvTrackInfo> tracks = mActivity.getTracks(trackType);
if (tracks != null) {
size = tracks.size();
if (size == expected) {
return;
}
}
- SystemClock.sleep(TRACK_SIZE_CHECK_INTERVAL_MS);
+ SystemClock.sleep(TRACK_CHECK_INTERVAL_MS);
}
- fail("Waited for " + WAIT_TRACK_SIZE_TIMEOUT_MS + " milliseconds for track size to be "
+ fail("Waited for " + WAIT_TRACK_EVENT_TIMEOUT_MS + " milliseconds for track size to be "
+ expected + " but was " + size);
}
+
+ private void waitUntilAudioTrackSelected(String trackId) {
+ waitUntilTrackSelected(TvTrackInfo.TYPE_AUDIO, trackId);
+ }
+
+ private void waitUntilVideoTrackSelected(String trackId) {
+ waitUntilTrackSelected(TvTrackInfo.TYPE_VIDEO, trackId);
+ }
+
+ private void waitUntilTrackSelected(int trackType, String trackId) {
+ long start = SystemClock.elapsedRealtime();
+ String selectedTrackId = null;
+ while (SystemClock.elapsedRealtime() < start + WAIT_TRACK_EVENT_TIMEOUT_MS) {
+ getInstrumentation().waitForIdleSync();
+ selectedTrackId = mActivity.getSelectedTrack(trackType);
+ if (TextUtils.equals(selectedTrackId, trackId)) {
+ return;
+ }
+ SystemClock.sleep(TRACK_CHECK_INTERVAL_MS);
+ }
+ fail("Waited for " + WAIT_TRACK_EVENT_TIMEOUT_MS + " milliseconds for track ID to be "
+ + trackId + " but was " + selectedTrackId);
+ }
}
diff --git a/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java b/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java
index c76de8fb..db765109 100644
--- a/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java
@@ -16,11 +16,16 @@
package com.android.tv.recommendation;
+import static android.support.test.InstrumentationRegistry.getContext;
+import static org.junit.Assert.assertEquals;
+
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
import com.android.tv.testing.Utils;
+import org.junit.Before;
+import org.junit.Test;
+
import java.util.Random;
import java.util.concurrent.TimeUnit;
@@ -28,31 +33,33 @@ import java.util.concurrent.TimeUnit;
* Unit tests for {@link ChannelRecord}.
*/
@SmallTest
-public class ChannelRecordTest extends AndroidTestCase {
+public class ChannelRecordTest {
private static final int CHANNEL_RECORD_MAX_HISTORY_SIZE = ChannelRecord.MAX_HISTORY_SIZE;
private Random mRandom;
private ChannelRecord mChannelRecord;
private long mLatestWatchEndTimeMs;
- @Override
- public void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
mLatestWatchEndTimeMs = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
mChannelRecord = new ChannelRecord(getContext(), null, false);
mRandom = Utils.createTestRandom();
}
+ @Test
public void testGetLastWatchEndTime_noHistory() {
assertEquals(0, mChannelRecord.getLastWatchEndTimeMs());
}
+ @Test
public void testGetLastWatchEndTime_oneHistory() {
addWatchLog();
assertEquals(mLatestWatchEndTimeMs, mChannelRecord.getLastWatchEndTimeMs());
}
+ @Test
public void testGetLastWatchEndTime_maxHistories() {
for (int i = 0; i < CHANNEL_RECORD_MAX_HISTORY_SIZE; ++i) {
addWatchLog();
@@ -61,6 +68,7 @@ public class ChannelRecordTest extends AndroidTestCase {
assertEquals(mLatestWatchEndTimeMs, mChannelRecord.getLastWatchEndTimeMs());
}
+ @Test
public void testGetLastWatchEndTime_moreThanMaxHistories() {
for (int i = 0; i < CHANNEL_RECORD_MAX_HISTORY_SIZE + 1; ++i) {
addWatchLog();
@@ -69,16 +77,19 @@ public class ChannelRecordTest extends AndroidTestCase {
assertEquals(mLatestWatchEndTimeMs, mChannelRecord.getLastWatchEndTimeMs());
}
+ @Test
public void testGetTotalWatchDuration_noHistory() {
assertEquals(0, mChannelRecord.getTotalWatchDurationMs());
}
+ @Test
public void testGetTotalWatchDuration_oneHistory() {
long durationMs = addWatchLog();
assertEquals(durationMs, mChannelRecord.getTotalWatchDurationMs());
}
+ @Test
public void testGetTotalWatchDuration_maxHistories() {
long totalWatchTimeMs = 0;
for (int i = 0; i < CHANNEL_RECORD_MAX_HISTORY_SIZE; ++i) {
@@ -89,6 +100,7 @@ public class ChannelRecordTest extends AndroidTestCase {
assertEquals(totalWatchTimeMs, mChannelRecord.getTotalWatchDurationMs());
}
+ @Test
public void testGetTotalWatchDuration_moreThanMaxHistories() {
long totalWatchTimeMs = 0;
long firstDurationMs = 0;
diff --git a/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java b/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java
index 0255947b..853fb245 100644
--- a/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java
+++ b/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java
@@ -16,30 +16,35 @@
package com.android.tv.recommendation;
-import android.test.AndroidTestCase;
+import static android.support.test.InstrumentationRegistry.getContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import com.android.tv.data.Channel;
import com.android.tv.recommendation.RecommendationUtils.ChannelRecordSortedMapHelper;
import com.android.tv.recommendation.Recommender.Evaluator;
import com.android.tv.testing.Utils;
+import org.junit.Before;
+
import java.util.ArrayList;
import java.util.List;
/**
* Base test case for Recommendation Evaluator Unit tests.
*/
-public abstract class EvaluatorTestCase<T extends Evaluator> extends AndroidTestCase {
+public abstract class EvaluatorTestCase<T extends Evaluator> {
private static final long INVALID_CHANNEL_ID = -1;
+ private static final double SCORE_DELTA = 0.01;
+
private ChannelRecordSortedMapHelper mChannelRecordSortedMap;
private RecommendationDataManager mDataManager;
public T mEvaluator;
- @Override
- public void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
mChannelRecordSortedMap = new ChannelRecordSortedMapHelper(getContext());
mDataManager = RecommendationUtils
.createMockRecommendationDataManager(mChannelRecordSortedMap);
@@ -91,8 +96,9 @@ public abstract class EvaluatorTestCase<T extends Evaluator> extends AndroidTest
* Check whether scores of each channels are valid.
*/
protected void assertChannelScoresValid() {
- assertEquals(Evaluator.NOT_RECOMMENDED, mEvaluator.evaluateChannel(INVALID_CHANNEL_ID));
- assertEquals(Evaluator.NOT_RECOMMENDED,
+ assertEqualScores(Evaluator.NOT_RECOMMENDED,
+ mEvaluator.evaluateChannel(INVALID_CHANNEL_ID));
+ assertEqualScores(Evaluator.NOT_RECOMMENDED,
mEvaluator.evaluateChannel(mChannelRecordSortedMap.size()));
for (long channelId : mChannelRecordSortedMap.keySet()) {
@@ -109,6 +115,14 @@ public abstract class EvaluatorTestCase<T extends Evaluator> extends AndroidTest
mEvaluator.onChannelRecordListChanged(new ArrayList<>(mChannelRecordSortedMap.values()));
}
+ void assertEqualScores(double expected, double actual) {
+ assertEquals(expected, actual, SCORE_DELTA);
+ }
+
+ void assertEqualScores(String message, double expected, double actual) {
+ assertEquals(message, expected, actual, SCORE_DELTA);
+ }
+
private class FakeRecommender extends Recommender {
public FakeRecommender() {
super(new Recommender.Listener() {
@@ -120,7 +134,7 @@ public abstract class EvaluatorTestCase<T extends Evaluator> extends AndroidTest
public void onRecommendationChanged() {
}
}, true, mDataManager);
- }
+ }
@Override
public ChannelRecord getChannelRecord(long channelId) {
diff --git a/tests/unit/src/com/android/tv/recommendation/FavoriteChannelEvaluatorTest.java b/tests/unit/src/com/android/tv/recommendation/FavoriteChannelEvaluatorTest.java
index aae3a932..ac701af9 100644
--- a/tests/unit/src/com/android/tv/recommendation/FavoriteChannelEvaluatorTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/FavoriteChannelEvaluatorTest.java
@@ -16,8 +16,12 @@
package com.android.tv.recommendation;
+import static org.junit.Assert.assertTrue;
+
import android.support.test.filters.SmallTest;
+import org.junit.Test;
+
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -38,14 +42,16 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
return new FavoriteChannelEvaluator();
}
+ @Test
public void testOneChannelWithNoWatchLog() {
long channelId = addChannel().getId();
notifyChannelAndWatchLogLoaded();
- assertEquals(Recommender.Evaluator.NOT_RECOMMENDED,
+ assertEqualScores(Recommender.Evaluator.NOT_RECOMMENDED,
mEvaluator.evaluateChannel(channelId));
}
+ @Test
public void testOneChannelWithRandomWatchLogs() {
addChannel();
addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
@@ -55,17 +61,19 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
assertChannelScoresValid();
}
+ @Test
public void testMultiChannelsWithNoWatchLog() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
notifyChannelAndWatchLogLoaded();
List<Long> channelIdList = getChannelIdListSorted();
for (long channelId : channelIdList) {
- assertEquals(Recommender.Evaluator.NOT_RECOMMENDED,
+ assertEqualScores(Recommender.Evaluator.NOT_RECOMMENDED,
mEvaluator.evaluateChannel(channelId));
}
}
+ @Test
public void testMultiChannelsWithRandomWatchLogs() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
@@ -75,6 +83,7 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
assertChannelScoresValid();
}
+ @Test
public void testMultiChannelsWithSimpleWatchLogs() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
// For two channels which has ID x and y (x < y), the channel y is more watched
@@ -99,6 +108,7 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
}
}
+ @Test
public void testTwoChannelsWithSameWatchDuration() {
long channelOne = addChannel().getId();
long channelTwo = addChannel().getId();
@@ -112,6 +122,7 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
mEvaluator.evaluateChannel(channelTwo));
}
+ @Test
public void testTwoChannelsWithDifferentWatchDuration() {
long channelOne = addChannel().getId();
long channelTwo = addChannel().getId();
@@ -131,6 +142,7 @@ public class FavoriteChannelEvaluatorTest extends EvaluatorTestCase<FavoriteChan
assertTrue(mEvaluator.evaluateChannel(channelOne) > mEvaluator.evaluateChannel(channelTwo));
}
+ @Test
public void testScoreIncreasesWithNewWatchLog() {
long channelId = addChannel().getId();
addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
diff --git a/tests/unit/src/com/android/tv/recommendation/RecentChannelEvaluatorTest.java b/tests/unit/src/com/android/tv/recommendation/RecentChannelEvaluatorTest.java
index 55a4e4ac..8f092238 100644
--- a/tests/unit/src/com/android/tv/recommendation/RecentChannelEvaluatorTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/RecentChannelEvaluatorTest.java
@@ -16,8 +16,12 @@
package com.android.tv.recommendation;
+import static org.junit.Assert.assertTrue;
+
import android.support.test.filters.SmallTest;
+import org.junit.Test;
+
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -40,14 +44,16 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
return new RecentChannelEvaluator();
}
+ @Test
public void testOneChannelWithNoWatchLog() {
long channelId = addChannel().getId();
notifyChannelAndWatchLogLoaded();
- assertEquals(Recommender.Evaluator.NOT_RECOMMENDED,
+ assertEqualScores(Recommender.Evaluator.NOT_RECOMMENDED,
mEvaluator.evaluateChannel(channelId));
}
+ @Test
public void testOneChannelWithRandomWatchLogs() {
addChannel();
addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
@@ -57,17 +63,19 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
assertChannelScoresValid();
}
+ @Test
public void testMultiChannelsWithNoWatchLog() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
notifyChannelAndWatchLogLoaded();
List<Long> channelIdList = getChannelIdListSorted();
for (long channelId : channelIdList) {
- assertEquals(Recommender.Evaluator.NOT_RECOMMENDED,
+ assertEqualScores(Recommender.Evaluator.NOT_RECOMMENDED,
mEvaluator.evaluateChannel(channelId));
}
}
+ @Test
public void testMultiChannelsWithRandomWatchLogs() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
@@ -77,6 +85,7 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
assertChannelScoresValid();
}
+ @Test
public void testMultiChannelsWithSimpleWatchLogs() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
// Every channel has one watch log with 1 hour. Also, for two channels
@@ -99,6 +108,7 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
}
}
+ @Test
public void testScoreIncreasesWithNewWatchLog() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
@@ -119,6 +129,7 @@ public class RecentChannelEvaluatorTest extends EvaluatorTestCase<RecentChannelE
}
}
+ @Test
public void testScoreDecreasesWithIncrementOfWatchedLogUpdatedTime() {
addChannels(DEFAULT_NUMBER_OF_CHANNELS);
addRandomWatchLogs(DEFAULT_WATCH_START_TIME_MS, DEFAULT_WATCH_END_TIME_MS,
diff --git a/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java b/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java
index 4a613995..b00ed16b 100644
--- a/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java
+++ b/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java
@@ -34,7 +34,6 @@ import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
public class RecommendationUtils {
- private static final String TAG = "RecommendationUtils";
private static final long INVALID_CHANNEL_ID = -1;
/**
diff --git a/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java b/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java
index 5270ffce..85524a82 100644
--- a/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java
@@ -16,14 +16,21 @@
package com.android.tv.recommendation;
+import static android.support.test.InstrumentationRegistry.getContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import com.android.tv.data.Channel;
import com.android.tv.recommendation.RecommendationUtils.ChannelRecordSortedMapHelper;
import com.android.tv.testing.Utils;
+import org.junit.Before;
+import org.junit.Test;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -34,7 +41,7 @@ import java.util.Map;
import java.util.concurrent.TimeUnit;
@SmallTest
-public class RecommenderTest extends AndroidTestCase {
+public class RecommenderTest {
private static final int DEFAULT_NUMBER_OF_CHANNELS = 5;
private static final long DEFAULT_WATCH_START_TIME_MS =
System.currentTimeMillis() - TimeUnit.DAYS.toMillis(2);
@@ -72,16 +79,15 @@ public class RecommenderTest extends AndroidTestCase {
private Channel mChannel_3;
private Channel mChannel_4;
- @Override
- public void setUp() throws Exception {
- super.setUp();
-
+ @Before
+ public void setUp() {
mChannelRecordSortedMap = new ChannelRecordSortedMapHelper(getContext());
mDataManager = RecommendationUtils
.createMockRecommendationDataManager(mChannelRecordSortedMap);
mChannelRecordSortedMap.resetRandom(Utils.createTestRandom());
}
+ @Test
public void testRecommendChannels_includeRecommendedOnly_allChannelsHaveNoScore() {
createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
@@ -94,6 +100,7 @@ public class RecommenderTest extends AndroidTestCase {
assertEquals(0, mRecommender.recommendChannels(5).size());
}
+ @Test
public void testRecommendChannels_notIncludeRecommendedOnly_allChannelsHaveNoScore() {
createRecommender(false, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
@@ -106,6 +113,7 @@ public class RecommenderTest extends AndroidTestCase {
assertEquals(4, mRecommender.recommendChannels(5).size());
}
+ @Test
public void testRecommendChannels_includeRecommendedOnly_allChannelsHaveScore() {
createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
@@ -125,6 +133,7 @@ public class RecommenderTest extends AndroidTestCase {
mChannel_4, mChannel_3, mChannel_2, mChannel_1);
}
+ @Test
public void testRecommendChannels_notIncludeRecommendedOnly_allChannelsHaveScore() {
createRecommender(false, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
@@ -144,6 +153,7 @@ public class RecommenderTest extends AndroidTestCase {
mChannel_4, mChannel_3, mChannel_2, mChannel_1);
}
+ @Test
public void testRecommendChannels_includeRecommendedOnly_fewChannelsHaveScore() {
createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
@@ -163,6 +173,7 @@ public class RecommenderTest extends AndroidTestCase {
mChannel_1, mChannel_2);
}
+ @Test
public void testRecommendChannels_notIncludeRecommendedOnly_fewChannelsHaveScore() {
createRecommender(false, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
@@ -189,6 +200,7 @@ public class RecommenderTest extends AndroidTestCase {
mChannel_1, mChannel_2);
}
+ @Test
public void testGetChannelSortKey_recommendAllChannels() {
createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
@@ -203,6 +215,7 @@ public class RecommenderTest extends AndroidTestCase {
assertSortKeyNotInvalid(channelList);
}
+ @Test
public void testGetChannelSortKey_recommendFewChannels() {
// Test with recommending 3 channels.
createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
@@ -221,6 +234,7 @@ public class RecommenderTest extends AndroidTestCase {
assertSortKeyNotInvalid(channelList);
}
+ @Test
public void testListener_onRecommendationChanged() {
createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS);
// FakeEvaluator doesn't recommend a channel with empty watch log. As every channel
@@ -245,6 +259,7 @@ public class RecommenderTest extends AndroidTestCase {
assertTrue(mOnRecommendationChanged);
}
+ @Test
public void testListener_onRecommenderReady() {
createRecommender(true, new Runnable() {
@Override
diff --git a/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java b/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java
index c9e21e9d..7b8e256d 100644
--- a/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java
+++ b/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java
@@ -16,12 +16,16 @@
package com.android.tv.recommendation;
+import static org.junit.Assert.assertEquals;
+
import android.support.test.filters.SmallTest;
import android.test.MoreAsserts;
import com.android.tv.data.Program;
import com.android.tv.recommendation.RoutineWatchEvaluator.ProgramTime;
+import org.junit.Test;
+
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
@@ -61,6 +65,7 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
return new RoutineWatchEvaluator();
}
+ @Test
public void testSplitTextToWords() {
assertSplitTextToWords("");
assertSplitTextToWords("Google", "Google");
@@ -71,6 +76,7 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
assertSplitTextToWords("A.I.", "A.I");
}
+ @Test
public void testCalculateMaximumMatchedWordSequenceLength() {
assertMaximumMatchedWordSequenceLength(0, "", "Google");
assertMaximumMatchedWordSequenceLength(2, "The Big Bang Theory", "Big Bang");
@@ -82,25 +88,29 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
assertMaximumMatchedWordSequenceLength(0, "Dexter", "Friends");
}
+ @Test
public void testCalculateTitleMatchScore_empty() {
- assertEquals(0.0, RoutineWatchEvaluator.calculateTitleMatchScore("", ""));
- assertEquals(0.0, RoutineWatchEvaluator.calculateTitleMatchScore("foo", ""));
- assertEquals(0.0, RoutineWatchEvaluator.calculateTitleMatchScore("", "foo"));
+ assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore("", ""));
+ assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore("foo", ""));
+ assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore("", "foo"));
}
+ @Test
public void testCalculateTitleMatchScore_spaces() {
- assertEquals(0.0, RoutineWatchEvaluator.calculateTitleMatchScore(" ", " "));
- assertEquals(0.0, RoutineWatchEvaluator.calculateTitleMatchScore("foo", " "));
- assertEquals(0.0, RoutineWatchEvaluator.calculateTitleMatchScore(" ", "foo"));
+ assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore(" ", " "));
+ assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore("foo", " "));
+ assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore(" ", "foo"));
}
+ @Test
public void testCalculateTitleMatchScore_null() {
- assertEquals(0.0, RoutineWatchEvaluator.calculateTitleMatchScore(null, null));
- assertEquals(0.0, RoutineWatchEvaluator.calculateTitleMatchScore("foo", null));
- assertEquals(0.0, RoutineWatchEvaluator.calculateTitleMatchScore(null, "foo"));
+ assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore(null, null));
+ assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore("foo", null));
+ assertEqualScores(0.0, RoutineWatchEvaluator.calculateTitleMatchScore(null, "foo"));
}
+ @Test
public void testCalculateTitleMatchScore_longerMatchIsBetter() {
String base = "foo bar baz";
assertInOrder(
@@ -110,6 +120,7 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
score(base, "foo bar baz"));
}
+ @Test
public void testProgramTime_createFromProgram() {
Calendar time = Calendar.getInstance();
int todayDayOfWeek = time.get(Calendar.DAY_OF_WEEK);
@@ -149,6 +160,7 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
programTimeToday1800_3600);
}
+ @Test
public void testCalculateOverlappedIntervalScore() {
// Today 21:00 - 24:00.
ProgramTime programTimeToday2100_2400 = ProgramTime.createFromProgram(
@@ -179,6 +191,7 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
programTimeTomorrow2000_2300);
}
+ @Test
public void testGetTimeOfDayInSec() {
// Time was set as 00:00:00. So, getTimeOfDay must returns 0 (= 0 * 60 * 60 + 0 * 60 + 0).
assertEquals("TimeOfDayInSec", hourMinuteToSec(0, 0),
@@ -222,9 +235,9 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva
score *= RoutineWatchEvaluator.MULTIPLIER_FOR_UNMATCHED_DAY_OF_WEEK;
}
// Two tests for testing commutative law.
- assertEquals("OverlappedIntervalScore", score,
+ assertEqualScores("OverlappedIntervalScore", score,
RoutineWatchEvaluator.calculateOverlappedIntervalScore(t1, t2));
- assertEquals("OverlappedIntervalScore", score,
+ assertEqualScores("OverlappedIntervalScore", score,
RoutineWatchEvaluator.calculateOverlappedIntervalScore(t2, t1));
}
diff --git a/tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java b/tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java
new file mode 100644
index 00000000..b0d342c6
--- /dev/null
+++ b/tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2017 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.tv.search;
+
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.verify;
+
+import android.app.SearchManager;
+import android.database.Cursor;
+import android.net.Uri;
+import android.support.test.filters.SmallTest;
+import android.test.ProviderTestCase2;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.TvApplication;
+import com.android.tv.perf.PerformanceMonitor;
+import com.android.tv.util.MockApplicationSingletons;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Unit test for {@link LocalSearchProvider}. */
+@SmallTest
+public class LocalSearchProviderTest extends ProviderTestCase2<LocalSearchProvider> {
+ private static final String AUTHORITY = "com.android.tv.search";
+ private static final String KEYWORD = "keyword";
+ private static final Uri BASE_SEARCH_URI = Uri.parse("content://" + AUTHORITY + "/"
+ + SearchManager.SUGGEST_URI_PATH_QUERY + "/" + KEYWORD);
+ private static final Uri WRONG_SERACH_URI = Uri.parse("content://" + AUTHORITY + "/wrong_path/"
+ + KEYWORD);
+
+ private ApplicationSingletons mOldAppSingletons;
+ MockApplicationSingletons mMockAppSingletons;
+ @Mock PerformanceMonitor mMockPerformanceMointor;
+ @Mock SearchInterface mMockSearchInterface;
+
+ public LocalSearchProviderTest() {
+ super(LocalSearchProvider.class, AUTHORITY);
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ setContext(getTargetContext());
+ mOldAppSingletons = TvApplication.sAppSingletons;
+ mMockAppSingletons = new MockApplicationSingletons(getTargetContext());
+ mMockAppSingletons.setPerformanceMonitor(mMockPerformanceMointor);
+ TvApplication.sAppSingletons = mMockAppSingletons;
+ super.setUp();
+ getProvider().setSearchInterface(mMockSearchInterface);
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ TvApplication.sAppSingletons = mOldAppSingletons;
+ super.tearDown();
+ }
+
+ @Test
+ public void testQuery_normalUri() {
+ verifyQueryWithArguments(null, null);
+ verifyQueryWithArguments(1, null);
+ verifyQueryWithArguments(null, 1);
+ verifyQueryWithArguments(1, 1);
+ }
+
+ @Test
+ public void testQuery_invalidUri() {
+ try (Cursor c = getProvider().query(WRONG_SERACH_URI, null, null, null, null)) {
+ fail("Query with invalid URI should fail.");
+ } catch (IllegalArgumentException e) {
+ // Success.
+ }
+ }
+
+ @Test
+ public void testQuery_invalidLimit() {
+ verifyQueryWithArguments(-1, null);
+ }
+
+ @Test
+ public void testQuery_invalidAction() {
+ verifyQueryWithArguments(null, SearchInterface.ACTION_TYPE_START - 1);
+ verifyQueryWithArguments(null, SearchInterface.ACTION_TYPE_END + 1);
+ }
+
+ private void verifyQueryWithArguments(Integer limit, Integer action) {
+ Uri uri = BASE_SEARCH_URI;
+ if (limit != null || action != null) {
+ Uri.Builder builder = uri.buildUpon();
+ if (limit != null) {
+ builder.appendQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT,
+ limit.toString());
+ }
+ if (action != null) {
+ builder.appendQueryParameter(LocalSearchProvider.SUGGEST_PARAMETER_ACTION,
+ action.toString());
+ }
+ uri = builder.build();
+ }
+ try (Cursor c = getProvider().query(uri, null, null, null, null)) {
+ // Do nothing.
+ }
+ int expectedLimit = limit == null || limit <= 0 ?
+ LocalSearchProvider.DEFAULT_SEARCH_LIMIT : limit;
+ int expectedAction = (action == null || action < SearchInterface.ACTION_TYPE_START
+ || action > SearchInterface.ACTION_TYPE_END) ?
+ LocalSearchProvider.DEFAULT_SEARCH_ACTION : action;
+ verify(mMockSearchInterface).search(KEYWORD, expectedLimit, expectedAction);
+ clearInvocations(mMockSearchInterface);
+ }
+}
diff --git a/tests/unit/src/com/android/tv/tests/TvActivityTest.java b/tests/unit/src/com/android/tv/tests/TvActivityTest.java
index 3479785f..aa33f770 100644
--- a/tests/unit/src/com/android/tv/tests/TvActivityTest.java
+++ b/tests/unit/src/com/android/tv/tests/TvActivityTest.java
@@ -16,19 +16,28 @@
package com.android.tv.tests;
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
import android.support.test.filters.MediumTest;
-import android.test.ActivityInstrumentationTestCase2;
+import android.support.test.rule.ActivityTestRule;
import com.android.tv.TvActivity;
+import com.android.tv.testing.Utils;
-@MediumTest
-public class TvActivityTest extends ActivityInstrumentationTestCase2<TvActivity> {
+import org.junit.Rule;
+import org.junit.Test;
- public TvActivityTest() {
- super(TvActivity.class);
- }
+@MediumTest
+public class TvActivityTest {
+ @Rule
+ public ActivityTestRule<TvActivity> mActivityTestRule =
+ new ActivityTestRule<>(TvActivity.class, false, false);
+ @Test
public void testLifeCycle() {
- getActivity();
+ assertTrue("TvActivity should be enabled.", Utils.isTvActivityEnabled(getTargetContext()));
+ assertNotNull(mActivityTestRule.launchActivity(null));
}
}
diff --git a/tests/unit/src/com/android/tv/util/ImageCacheTest.java b/tests/unit/src/com/android/tv/util/ImageCacheTest.java
index e185d5f1..a76194b8 100644
--- a/tests/unit/src/com/android/tv/util/ImageCacheTest.java
+++ b/tests/unit/src/com/android/tv/util/ImageCacheTest.java
@@ -17,19 +17,21 @@
package com.android.tv.util;
import static com.android.tv.util.BitmapUtils.createScaledBitmapInfo;
+import static org.junit.Assert.assertSame;
import android.graphics.Bitmap;
import android.support.test.filters.MediumTest;
import com.android.tv.util.BitmapUtils.ScaledBitmapInfo;
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
/**
* Tests for {@link ImageCache}.
*/
@MediumTest
-public class ImageCacheTest extends TestCase {
+public class ImageCacheTest {
private static final Bitmap ORIG = Bitmap.createBitmap(100, 100, Bitmap.Config.RGB_565);
private static final String KEY = "same";
@@ -40,14 +42,14 @@ public class ImageCacheTest extends TestCase {
private ImageCache mImageCache;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
mImageCache = ImageCache.newInstance(0.1f);
}
//TODO: Empty the cache in the setup. Try using @VisibleForTesting
+ @Test
public void testPutIfLarger_smaller() throws Exception {
mImageCache.putIfNeeded( INFO_50);
@@ -57,6 +59,7 @@ public class ImageCacheTest extends TestCase {
assertSame("after", INFO_50, mImageCache.get(KEY));
}
+ @Test
public void testPutIfLarger_larger() throws Exception {
mImageCache.putIfNeeded( INFO_50);
assertSame("before", INFO_50, mImageCache.get(KEY));
@@ -65,6 +68,7 @@ public class ImageCacheTest extends TestCase {
assertSame("after", INFO_100, mImageCache.get(KEY));
}
+ @Test
public void testPutIfLarger_alreadyMax() throws Exception {
mImageCache.putIfNeeded( INFO_100);
diff --git a/tests/unit/src/com/android/tv/util/MockApplicationSingletons.java b/tests/unit/src/com/android/tv/util/MockApplicationSingletons.java
new file mode 100644
index 00000000..4cfc7f8a
--- /dev/null
+++ b/tests/unit/src/com/android/tv/util/MockApplicationSingletons.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2017 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.tv.util;
+
+import android.content.Context;
+
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.InputSessionManager;
+import com.android.tv.MainActivityWrapper;
+import com.android.tv.TvApplication;
+import com.android.tv.analytics.Analytics;
+import com.android.tv.analytics.Tracker;
+import com.android.tv.config.RemoteConfig;
+import com.android.tv.data.ChannelDataManager;
+import com.android.tv.data.PreviewDataManager;
+import com.android.tv.data.ProgramDataManager;
+import com.android.tv.dvr.DvrDataManager;
+import com.android.tv.dvr.DvrManager;
+import com.android.tv.dvr.DvrScheduleManager;
+import com.android.tv.dvr.DvrStorageStatusManager;
+import com.android.tv.dvr.DvrWatchedPositionManager;
+import com.android.tv.dvr.recorder.RecordingScheduler;
+import com.android.tv.perf.PerformanceMonitor;
+
+/**
+ * Mock {@link ApplicationSingletons} class.
+ */
+public class MockApplicationSingletons implements ApplicationSingletons {
+ private final TvApplication mApp;
+
+ private PerformanceMonitor mPerformanceMonitor;
+
+ public MockApplicationSingletons(Context context) {
+ mApp = (TvApplication) context.getApplicationContext();
+ }
+
+ @Override
+ public Analytics getAnalytics() {
+ return mApp.getAnalytics();
+ }
+
+ @Override
+ public ChannelDataManager getChannelDataManager() {
+ return mApp.getChannelDataManager();
+ }
+
+ @Override
+ public boolean isChannelDataManagerLoadFinished() {
+ return mApp.isChannelDataManagerLoadFinished();
+ }
+
+ @Override
+ public ProgramDataManager getProgramDataManager() {
+ return mApp.getProgramDataManager();
+ }
+
+ @Override
+ public boolean isProgramDataManagerCurrentProgramsLoadFinished() {
+ return mApp.isProgramDataManagerCurrentProgramsLoadFinished();
+ }
+
+ @Override
+ public PreviewDataManager getPreviewDataManager() {
+ return mApp.getPreviewDataManager();
+ }
+
+ @Override
+ public DvrDataManager getDvrDataManager() {
+ return mApp.getDvrDataManager();
+ }
+
+ @Override
+ public DvrStorageStatusManager getDvrStorageStatusManager() {
+ return mApp.getDvrStorageStatusManager();
+ }
+
+ @Override
+ public DvrScheduleManager getDvrScheduleManager() {
+ return mApp.getDvrScheduleManager();
+ }
+
+ @Override
+ public DvrManager getDvrManager() {
+ return mApp.getDvrManager();
+ }
+
+ @Override
+ public RecordingScheduler getRecordingScheduler() {
+ return mApp.getRecordingScheduler();
+ }
+
+ @Override
+ public DvrWatchedPositionManager getDvrWatchedPositionManager() {
+ return mApp.getDvrWatchedPositionManager();
+ }
+
+ @Override
+ public InputSessionManager getInputSessionManager() {
+ return mApp.getInputSessionManager();
+ }
+
+ @Override
+ public Tracker getTracker() {
+ return mApp.getTracker();
+ }
+
+ @Override
+ public TvInputManagerHelper getTvInputManagerHelper() {
+ return mApp.getTvInputManagerHelper();
+ }
+
+ @Override
+ public MainActivityWrapper getMainActivityWrapper() {
+ return mApp.getMainActivityWrapper();
+ }
+
+ @Override
+ public AccountHelper getAccountHelper() {
+ return mApp.getAccountHelper();
+ }
+
+ @Override
+ public RemoteConfig getRemoteConfig() {
+ return mApp.getRemoteConfig();
+ }
+
+ @Override
+ public boolean isRunningInMainProcess() {
+ return mApp.isRunningInMainProcess();
+ }
+
+ @Override
+ public PerformanceMonitor getPerformanceMonitor() {
+ return mPerformanceMonitor != null ? mPerformanceMonitor : mApp.getPerformanceMonitor();
+ }
+
+ public void setPerformanceMonitor(PerformanceMonitor performanceMonitor) {
+ mPerformanceMonitor = performanceMonitor;
+ }
+}
diff --git a/tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java b/tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java
index fe094fb3..7335f207 100644
--- a/tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java
+++ b/tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java
@@ -16,10 +16,13 @@
package com.android.tv.util;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
import android.support.test.filters.SmallTest;
import android.test.MoreAsserts;
-import junit.framework.TestCase;
+import org.junit.Test;
import java.util.Collections;
@@ -27,19 +30,21 @@ import java.util.Collections;
* Tests for {@link MultiLongSparseArray}.
*/
@SmallTest
-public class MultiLongSparseArrayTest extends TestCase {
-
+public class MultiLongSparseArrayTest {
+ @Test
public void testEmpty() {
MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
assertSame(Collections.EMPTY_SET, sparseArray.get(0));
}
+ @Test
public void testOneElement() {
MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
sparseArray.put(0, "foo");
MoreAsserts.assertContentsInAnyOrder(sparseArray.get(0), "foo");
}
+ @Test
public void testTwoElements() {
MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
sparseArray.put(0, "foo");
@@ -48,6 +53,7 @@ public class MultiLongSparseArrayTest extends TestCase {
}
+ @Test
public void testClearEmptyCache() {
MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
sparseArray.clearEmptyCache();
@@ -59,6 +65,7 @@ public class MultiLongSparseArrayTest extends TestCase {
assertEquals(0, sparseArray.getEmptyCacheSize());
}
+ @Test
public void testMaxEmptyCacheSize() {
MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
sparseArray.clearEmptyCache();
@@ -75,6 +82,7 @@ public class MultiLongSparseArrayTest extends TestCase {
assertEquals(0, sparseArray.getEmptyCacheSize());
}
+ @Test
public void testReuseEmptySets() {
MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>();
sparseArray.clearEmptyCache();
diff --git a/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java b/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java
index 36d25a10..2714e2e9 100644
--- a/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java
+++ b/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java
@@ -1,24 +1,29 @@
package com.android.tv.util;
+import static org.junit.Assert.assertEquals;
+
import android.graphics.Bitmap;
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
import com.android.tv.util.BitmapUtils.ScaledBitmapInfo;
+import org.junit.Test;
+
/**
* Tests for {@link ScaledBitmapInfo}.
*/
@SmallTest
-public class ScaledBitmapInfoTest extends AndroidTestCase {
+public class ScaledBitmapInfoTest {
private static final Bitmap B80x100 = Bitmap.createBitmap(80, 100, Bitmap.Config.RGB_565);
private static final Bitmap B960x1440 = Bitmap.createBitmap(960, 1440, Bitmap.Config.RGB_565);
+ @Test
public void testSize_B100x100to50x50() {
ScaledBitmapInfo actual = BitmapUtils.createScaledBitmapInfo("B80x100", B80x100, 50, 50);
assertScaledBitmapSize(2, 40, 50, actual);
}
+ @Test
public void testNeedsToReload_B100x100to50x50() {
ScaledBitmapInfo actual = BitmapUtils.createScaledBitmapInfo("B80x100", B80x100, 50, 50);
assertNeedsToReload(false, actual, 25, 25);
@@ -31,6 +36,7 @@ public class ScaledBitmapInfoTest extends AndroidTestCase {
/**
* Reproduces <a href="http://b/20488453">b/20488453</a>.
*/
+ @Test
public void testBug20488453() {
ScaledBitmapInfo actual = BitmapUtils
.createScaledBitmapInfo("B960x1440", B960x1440, 284, 160);
diff --git a/tests/unit/src/com/android/tv/util/TestUtils.java b/tests/unit/src/com/android/tv/util/TestUtils.java
index e3bda138..d200733d 100644
--- a/tests/unit/src/com/android/tv/util/TestUtils.java
+++ b/tests/unit/src/com/android/tv/util/TestUtils.java
@@ -21,8 +21,8 @@ import android.content.pm.ServiceInfo;
import android.graphics.drawable.Icon;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.media.tv.TvInputInfo;
+import android.os.Build;
import android.os.Bundle;
-import android.support.v4.os.BuildCompat;
import java.lang.reflect.Constructor;
@@ -47,7 +47,11 @@ public class TestUtils {
int type, boolean isHardwareInput, boolean canRecord, int tunerCount) throws Exception {
// Create a mock TvInputInfo by using private constructor
// Note that mockito doesn't support mock/spy on final object.
- if (BuildCompat.isAtLeastN()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ return createTvInputInfoForO(service, id, parentId, type, isHardwareInput, canRecord,
+ tunerCount);
+
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return createTvInputInfoForNyc(service, id, parentId, type, isHardwareInput, canRecord,
tunerCount);
}
@@ -57,6 +61,24 @@ public class TestUtils {
/**
* private TvInputInfo(ResolveInfo service, String id, int type, boolean isHardwareInput,
* CharSequence label, int labelResId, Icon icon, Icon iconStandby, Icon iconDisconnected,
+ * String setupActivity, boolean canRecord, int tunerCount, HdmiDeviceInfo hdmiDeviceInfo,
+ * boolean isConnectedToHdmiSwitch, String parentId, Bundle extras) {
+ */
+ private static TvInputInfo createTvInputInfoForO(ResolveInfo service, String id,
+ String parentId, int type, boolean isHardwareInput, boolean canRecord, int tunerCount)
+ throws Exception {
+ Constructor<TvInputInfo> constructor = TvInputInfo.class.getDeclaredConstructor(
+ ResolveInfo.class, String.class, int.class, boolean.class, CharSequence.class,
+ int.class, Icon.class, Icon.class, Icon.class, String.class, boolean.class,
+ int.class, HdmiDeviceInfo.class, boolean.class, String.class, Bundle.class);
+ constructor.setAccessible(true);
+ return constructor.newInstance(service, id, type, isHardwareInput, null, 0, null, null,
+ null, null, canRecord, tunerCount, null, false, parentId, null);
+ }
+
+ /**
+ * private TvInputInfo(ResolveInfo service, String id, int type, boolean isHardwareInput,
+ * CharSequence label, int labelResId, Icon icon, Icon iconStandby, Icon iconDisconnected,
* String setupActivity, String settingsActivity, boolean canRecord, int tunerCount,
* HdmiDeviceInfo hdmiDeviceInfo, boolean isConnectedToHdmiSwitch, String parentId,
* Bundle extras) {
@@ -87,6 +109,7 @@ public class TestUtils {
resolveInfo.serviceInfo = new ServiceInfo();
resolveInfo.serviceInfo.packageName = packageName;
resolveInfo.serviceInfo.name = name;
+ resolveInfo.serviceInfo.metaData = new Bundle();
return resolveInfo;
}
}
diff --git a/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java b/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java
index ba1e0b0b..404ee5d3 100644
--- a/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java
+++ b/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java
@@ -16,58 +16,155 @@
package com.android.tv.util;
+import static android.support.test.InstrumentationRegistry.getContext;
+
import android.content.pm.ResolveInfo;
import android.media.tv.TvInputInfo;
import android.support.test.filters.SmallTest;
-import android.support.test.filters.Suppress;
-import android.test.AndroidTestCase;
import com.android.tv.testing.ComparatorTester;
+import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import java.util.LinkedHashMap;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
/**
* Test for {@link TvInputManagerHelper}
*/
@SmallTest
-public class TvInputManagerHelperTest extends AndroidTestCase {
- public void testComparator() throws Exception {
- final LinkedHashMap<String, Boolean> INPUT_ID_TO_PARTNER_INPUT = new LinkedHashMap<>();
- INPUT_ID_TO_PARTNER_INPUT.put("2_partner_input", true);
- INPUT_ID_TO_PARTNER_INPUT.put("3_partner_input", true);
- INPUT_ID_TO_PARTNER_INPUT.put("1_3rd_party_input", false);
- INPUT_ID_TO_PARTNER_INPUT.put("4_3rd_party_input", false);
+public class TvInputManagerHelperTest {
+ final HashMap<String, TvInputInfoWrapper> TEST_INPUT_MAP = new HashMap<>();
+
+ @Test
+ public void testComparatorInternal() {
+ ResolveInfo resolveInfo = TestUtils.createResolveInfo("test", "test");
+
+ List<TvInputInfo> inputs = new ArrayList<>();
+ inputs.add(createTvInputInfo(resolveInfo, "2_partner_input", null, 0, false,
+ "2_partner_input", null, true));
+ inputs.add(createTvInputInfo(resolveInfo, "3_partner_input", null, 0, false,
+ "3_partner_input", null, true));
+ inputs.add(createTvInputInfo(resolveInfo, "1_3rd_party_input", null, 0, false,
+ "1_3rd_party_input", null, false));
+ inputs.add(createTvInputInfo(resolveInfo, "4_3rd_party_input", null, 0, false,
+ "4_3rd_party_input", null, false));
+
+ TvInputManagerHelper manager = createMockTvInputManager();
+
+ ComparatorTester<TvInputInfo> comparatorTester = ComparatorTester.withoutEqualsTest(
+ new TvInputManagerHelper.InputComparatorInternal(manager));
+ for (TvInputInfo input : inputs) {
+ comparatorTester.addComparableGroup(input);
+ }
+ comparatorTester.test();
+ }
+
+ @Test
+ public void testHardwareInputComparatorHdmi() {
+ ResolveInfo resolveInfo = TestUtils.createResolveInfo("test", "test");
+
+ TvInputInfo hdmi1 = createTvInputInfo(resolveInfo, "HDMI1", null, TvInputInfo.TYPE_HDMI,
+ true, "HDMI1", null, false);
+ TvInputInfo hdmi2 = createTvInputInfo(resolveInfo, "HDMI2", null, TvInputInfo.TYPE_HDMI,
+ true, "HDMI2", "DVD", false);
+ TvInputInfo hdmi3 = createTvInputInfo(resolveInfo, "HDMI3", null, TvInputInfo.TYPE_HDMI,
+ true, "HDMI3", "Cable", false);
+ TvInputInfo hdmi4 = createTvInputInfo(resolveInfo, "HDMI4", null, TvInputInfo.TYPE_HDMI,
+ true, "HDMI4", null, false);
+
+ TvInputManagerHelper manager = createMockTvInputManager();
+
+ ComparatorTester<TvInputInfo> comparatorTester = ComparatorTester.withoutEqualsTest(
+ new TvInputManagerHelper.HardwareInputComparator(getContext(), manager));
+ comparatorTester.addComparableGroup(hdmi3)
+ .addComparableGroup(hdmi2)
+ .addComparableGroup(hdmi1)
+ .addComparableGroup(hdmi4)
+ .test();
+ }
+
+ @Test
+ public void testHardwareInputComparatorCec() {
+ ResolveInfo resolveInfo = TestUtils.createResolveInfo("test", "test");
+
+ TvInputInfo hdmi1 = createTvInputInfo(resolveInfo, "HDMI1", null, TvInputInfo.TYPE_HDMI,
+ true, "HDMI1", null, false);
+ TvInputInfo hdmi2 = createTvInputInfo(resolveInfo, "HDMI2", null, TvInputInfo.TYPE_HDMI,
+ true, "HDMI2", null, false);
+ TvInputInfo cec1 = createTvInputInfo(resolveInfo, "2_cec", "HDMI1", TvInputInfo.TYPE_HDMI,
+ true, "2_cec", null, false);
+ TvInputInfo cec2 = createTvInputInfo(resolveInfo, "1_cec", "HDMI2", TvInputInfo.TYPE_HDMI,
+ true, "1_cec", null, false);
+
+ TvInputManagerHelper manager = createMockTvInputManager();
+
+ ComparatorTester<TvInputInfo> comparatorTester = ComparatorTester.withoutEqualsTest(
+ new TvInputManagerHelper.HardwareInputComparator(getContext(), manager));
+ comparatorTester.addComparableGroup(cec1)
+ .addComparableGroup(cec2)
+ .test();
+ }
+
+ private TvInputManagerHelper createMockTvInputManager() {
TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class);
Mockito.doAnswer(new Answer<Boolean>() {
@Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
TvInputInfo info = (TvInputInfo) invocation.getArguments()[0];
- return INPUT_ID_TO_PARTNER_INPUT.get(info.getId());
+ return TEST_INPUT_MAP.get(info.getId()).mIsPartnerInput;
}
}).when(manager).isPartnerInput(Mockito.<TvInputInfo>any());
Mockito.doAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
TvInputInfo info = (TvInputInfo) invocation.getArguments()[0];
- return info.getId();
+ return TEST_INPUT_MAP.get(info.getId()).mLabel;
}
}).when(manager).loadLabel(Mockito.<TvInputInfo>any());
+ Mockito.doAnswer(new Answer<String>() {
+ @Override
+ public String answer(InvocationOnMock invocation) throws Throwable {
+ TvInputInfo info = (TvInputInfo) invocation.getArguments()[0];
+ return TEST_INPUT_MAP.get(info.getId()).mCustomLabel;
+ }
+ }).when(manager).loadCustomLabel(Mockito.<TvInputInfo>any());
+ Mockito.doAnswer(new Answer<TvInputInfo>() {
+ @Override
+ public TvInputInfo answer(InvocationOnMock invocation) throws Throwable {
+ String inputId = (String) invocation.getArguments()[0];
+ TvInputInfoWrapper inputWrapper = TEST_INPUT_MAP.get(inputId);
+ return inputWrapper == null ? null : inputWrapper.mInput;
+ }
+ }).when(manager).getTvInputInfo(Mockito.<String>any());
+ return manager;
+ }
- ComparatorTester<TvInputInfo> comparatorTester =
- ComparatorTester.withoutEqualsTest(
- new TvInputManagerHelper.TvInputInfoComparator(manager));
- ResolveInfo resolveInfo1 = TestUtils.createResolveInfo("1_test", "1_test");
- ResolveInfo resolveInfo2 = TestUtils.createResolveInfo("2_test", "2_test");
- for (String inputId : INPUT_ID_TO_PARTNER_INPUT.keySet()) {
- TvInputInfo info1 = TestUtils.createTvInputInfo(resolveInfo1, inputId, null, 0, false);
- TvInputInfo info2 = TestUtils.createTvInputInfo(resolveInfo2, inputId, null, 0, false);
- comparatorTester.addComparableGroup(info1, info2);
+ private TvInputInfo createTvInputInfo(ResolveInfo service, String id,
+ String parentId, int type, boolean isHardwareInput, String label, String customLabel,
+ boolean isPartnerInput) {
+ TvInputInfoWrapper inputWrapper = new TvInputInfoWrapper();
+ try {
+ inputWrapper.mInput =
+ TestUtils.createTvInputInfo(service, id, parentId, type, isHardwareInput);
+ } catch (Exception e) {
}
- comparatorTester.test();
+ inputWrapper.mLabel = label;
+ inputWrapper.mIsPartnerInput = isPartnerInput;
+ inputWrapper.mCustomLabel = customLabel;
+ TEST_INPUT_MAP.put(id, inputWrapper);
+ return inputWrapper.mInput;
+ }
+
+ private static class TvInputInfoWrapper {
+ TvInputInfo mInput;
+ String mLabel;
+ String mCustomLabel;
+ boolean mIsPartnerInput;
}
}
diff --git a/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java b/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java
index 9600fc0b..4512bb7d 100644
--- a/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java
+++ b/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java
@@ -16,13 +16,14 @@
package com.android.tv.util;
import static com.android.tv.util.TvTrackInfoUtils.getBestTrackInfo;
+import static org.junit.Assert.assertEquals;
import android.media.tv.TvTrackInfo;
import android.support.test.filters.SmallTest;
import com.android.tv.testing.ComparatorTester;
-import junit.framework.TestCase;
+import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
@@ -33,8 +34,7 @@ import java.util.List;
* Tests for {@link com.android.tv.util.TvTrackInfoUtils}.
*/
@SmallTest
-public class TvTrackInfoUtilsTest extends TestCase {
-
+public class TvTrackInfoUtilsTest {
private static final String UN_MATCHED_ID = "no matching ID";
private static final TvTrackInfo INFO_1_EN_1 = create("1", "en", 1);
@@ -59,46 +59,55 @@ public class TvTrackInfoUtilsTest extends TestCase {
private static final List<TvTrackInfo> NULL_LANGUAGE_TRACKS = Arrays.asList(INFO_4_NULL_2,
INFO_5_NULL_6);
+ @Test
public void testGetBestTrackInfo_empty() {
TvTrackInfo result = getBestTrackInfo(Collections.emptyList(), UN_MATCHED_ID, "en", 1);
assertEquals("best track ", null, result);
}
+ @Test
public void testGetBestTrackInfo_exactMatch() {
TvTrackInfo result = getBestTrackInfo(ALL, "1", "en", 1);
assertEquals("best track ", INFO_1_EN_1, result);
}
+ @Test
public void testGetBestTrackInfo_langAndChannelCountMatch() {
TvTrackInfo result = getBestTrackInfo(ALL, UN_MATCHED_ID, "en", 5);
assertEquals("best track ", INFO_2_EN_5, result);
}
+ @Test
public void testGetBestTrackInfo_languageOnlyMatch() {
TvTrackInfo result = getBestTrackInfo(ALL, UN_MATCHED_ID, "fr", 1);
assertEquals("best track ", INFO_3_FR_8, result);
}
+ @Test
public void testGetBestTrackInfo_channelCountOnlyMatchWithNullLanguage() {
TvTrackInfo result = getBestTrackInfo(ALL, UN_MATCHED_ID, null, 8);
assertEquals("best track ", INFO_3_FR_8, result);
}
+ @Test
public void testGetBestTrackInfo_noMatches() {
TvTrackInfo result = getBestTrackInfo(ALL, UN_MATCHED_ID, "kr", 1);
assertEquals("best track ", INFO_1_EN_1, result);
}
+ @Test
public void testGetBestTrackInfo_noMatchesWithNullLanguage() {
TvTrackInfo result = getBestTrackInfo(ALL, UN_MATCHED_ID, null, 0);
assertEquals("best track ", INFO_1_EN_1, result);
}
+ @Test
public void testGetBestTrackInfo_channelCountAndIdMatch() {
TvTrackInfo result = getBestTrackInfo(NULL_LANGUAGE_TRACKS, "5", null, 6);
assertEquals("best track ", INFO_5_NULL_6, result);
}
+ @Test
public void testComparator() {
Comparator<TvTrackInfo> comparator = TvTrackInfoUtils.createComparator("1", "en", 1);
ComparatorTester.withoutEqualsTest(comparator)
diff --git a/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java b/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java
index 9dfb992e..e61802f5 100644
--- a/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java
+++ b/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java
@@ -15,10 +15,16 @@
*/
package com.android.tv.util;
+import static android.support.test.InstrumentationRegistry.getContext;
+import static org.junit.Assert.assertEquals;
+
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
import android.text.format.DateUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
@@ -32,7 +38,7 @@ import java.util.Locale;
* and it should be defined in TV app, not this test.
*/
@SmallTest
-public class UtilsTest_GetDurationString extends AndroidTestCase {
+public class UtilsTest_GetDurationString {
// TODO: Mock Context so we can specify current time and locale for test.
private Locale mLocale;
private static final long DATE_THIS_YEAR_2_1_MS = getFebOfThisYearInMillis(1, 0, 0);
@@ -40,14 +46,19 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
// All possible list for a parameter to test parameter independent result.
private static final boolean[] PARAM_USE_SHORT_FORMAT = {false, true};
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
// Set locale to US
mLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
}
+ @After
+ public void tearDown() {
+ // Revive system locale.
+ Locale.setDefault(mLocale);
+ }
+
/**
* Return time in millis assuming that whose year is this year and month is Jan.
*/
@@ -76,6 +87,7 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
return new GregorianCalendar().get(GregorianCalendar.YEAR);
}
+ @Test
public void testSameDateAndTime() {
assertEquals("3:00 AM", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
getFebOfThisYearInMillis(1, 3), getFebOfThisYearInMillis(1, 3), false,
@@ -85,6 +97,7 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
DateUtils.FORMAT_24HOUR));
}
+ @Test
public void testDurationWithinToday() {
assertEquals("12:00 – 3:00 AM",
Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS,
@@ -96,6 +109,7 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
DateUtils.FORMAT_24HOUR));
}
+ @Test
public void testDurationFromYesterdayToToday() {
assertEquals("Jan 31, 3:00 AM – Feb 1, 4:00 AM",
Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
@@ -115,6 +129,7 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
true, DateUtils.FORMAT_24HOUR));
}
+ @Test
public void testDurationFromTodayToTomorrow() {
assertEquals("Feb 1, 3:00 AM – Feb 2, 4:00 AM",
Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
@@ -154,6 +169,7 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
DateUtils.FORMAT_24HOUR));
}
+ @Test
public void testDurationWithinTomorrow() {
assertEquals("Feb 2, 2:00 – 4:00 AM",
Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
@@ -173,6 +189,7 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
DateUtils.FORMAT_24HOUR));
}
+ @Test
public void testStartOfDay() {
assertEquals("12:00 – 1:00 AM",
Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS, DATE_THIS_YEAR_2_1_MS,
@@ -201,6 +218,7 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
DateUtils.FORMAT_24HOUR));
}
+ @Test
public void testEndOfDay() {
for (boolean useShortFormat : PARAM_USE_SHORT_FORMAT) {
assertEquals("11:00 PM – 12:00 AM",
@@ -241,6 +259,7 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
DateUtils.FORMAT_24HOUR));
}
+ @Test
public void testMidnight() {
for (boolean useShortFormat : PARAM_USE_SHORT_FORMAT) {
assertEquals("12:00 AM", Utils.getDurationString(getContext(), DATE_THIS_YEAR_2_1_MS,
@@ -251,11 +270,4 @@ public class UtilsTest_GetDurationString extends AndroidTestCase {
DateUtils.FORMAT_24HOUR));
}
}
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- // Revive system locale.
- Locale.setDefault(mLocale);
- }
}
diff --git a/tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java b/tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java
index 8a6f3e3b..1e75342b 100644
--- a/tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java
+++ b/tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java
@@ -16,21 +16,26 @@
package com.android.tv.util;
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+import static org.junit.Assert.assertEquals;
+
import android.content.Context;
import android.media.tv.TvTrackInfo;
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
+
+import org.junit.Test;
/**
* Tests for {@link com.android.tv.util.Utils#getMultiAudioString}.
*/
@SmallTest
-public class UtilsTest_GetMultiAudioString extends AndroidTestCase {
+public class UtilsTest_GetMultiAudioString {
private static final String TRACK_ID = "test_track_id";
private static final int AUDIO_SAMPLE_RATE = 48000;
+ @Test
public void testAudioTrackLanguage() {
- Context context = getContext();
+ Context context = getTargetContext();
assertEquals("Korean",
Utils.getMultiAudioString(context, createAudioTrackInfo("kor"), false));
assertEquals("English",
@@ -42,8 +47,9 @@ public class UtilsTest_GetMultiAudioString extends AndroidTestCase {
assertEquals("abc", Utils.getMultiAudioString(context, createAudioTrackInfo("abc"), false));
}
+ @Test
public void testAudioTrackCount() {
- Context context = getContext();
+ Context context = getTargetContext();
assertEquals("English",
Utils.getMultiAudioString(context, createAudioTrackInfo("eng", -1), false));
assertEquals("English",
@@ -66,11 +72,14 @@ public class UtilsTest_GetMultiAudioString extends AndroidTestCase {
Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 8), false));
}
+ @Test
public void testShowSampleRate() {
assertEquals("Korean (48kHz)",
- Utils.getMultiAudioString(getContext(), createAudioTrackInfo("kor", 0), true));
+ Utils.getMultiAudioString(getTargetContext(),
+ createAudioTrackInfo("kor", 0), true));
assertEquals("Korean (7.1 surround, 48kHz)",
- Utils.getMultiAudioString(getContext(), createAudioTrackInfo("kor", 8), true));
+ Utils.getMultiAudioString(getTargetContext(),
+ createAudioTrackInfo("kor", 8), true));
}
private static TvTrackInfo createAudioTrackInfo(String language) {
diff --git a/tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java b/tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java
index 926deb07..2b43abc1 100644
--- a/tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java
+++ b/tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java
@@ -16,8 +16,12 @@
package com.android.tv.util;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
+
+import org.junit.Test;
import java.util.Calendar;
import java.util.GregorianCalendar;
@@ -27,19 +31,22 @@ import java.util.TimeZone;
* Tests for {@link com.android.tv.util.Utils#isInGivenDay}.
*/
@SmallTest
-public class UtilsTest_IsInGivenDay extends AndroidTestCase {
+public class UtilsTest_IsInGivenDay {
+ @Test
public void testIsInGivenDay() {
assertTrue(Utils.isInGivenDay(
new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis(),
new GregorianCalendar(2015, Calendar.JANUARY, 1, 0, 30).getTimeInMillis()));
}
+ @Test
public void testIsNotInGivenDay() {
assertFalse(Utils.isInGivenDay(
new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis(),
new GregorianCalendar(2015, Calendar.JANUARY, 2).getTimeInMillis()));
}
+ @Test
public void testIfTimeZoneApplied() {
TimeZone timeZone = TimeZone.getDefault();
diff --git a/usbtuner-res/animator/setup_before_entry.xml b/usbtuner-res/animator/setup_before_entry.xml
deleted file mode 100644
index 82ed7992..00000000
--- a/usbtuner-res/animator/setup_before_entry.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:ordering="together" >
- <objectAnimator
- android:duration="@android:integer/config_longAnimTime"
- android:propertyName="translationX"
- android:valueFrom="@dimen/ut_guidedstep_entry_slide_from"
- android:valueTo="@dimen/ut_guidedstep_entry_slide_from"
- android:valueType="floatType" />
-
- <objectAnimator
- android:duration="@android:integer/config_longAnimTime"
- android:propertyName="alpha"
- android:valueFrom="0.0"
- android:valueTo="0.0"
- android:valueType="floatType" />
-</set>
diff --git a/usbtuner-res/animator/setup_before_exit.xml b/usbtuner-res/animator/setup_before_exit.xml
deleted file mode 100644
index 5c00064c..00000000
--- a/usbtuner-res/animator/setup_before_exit.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:ordering="together" >
-
- <objectAnimator
- android:duration="@android:integer/config_longAnimTime"
- android:propertyName="translationX"
- android:valueFrom="0.0"
- android:valueTo="0.0"
- android:valueType="floatType" />
-
- <objectAnimator
- android:duration="@android:integer/config_longAnimTime"
- android:propertyName="alpha"
- android:valueFrom="1.0"
- android:valueTo="1.0"
- android:valueType="floatType" />
-
-</set>
diff --git a/usbtuner-res/animator/setup_entry.xml b/usbtuner-res/animator/setup_entry.xml
deleted file mode 100644
index 35fcd4a3..00000000
--- a/usbtuner-res/animator/setup_entry.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/linear_out_slow_in"
- android:ordering="together" >
-
- <objectAnimator
- android:duration="@integer/ut_entry_anim_duration"
- android:propertyName="translationX"
- android:valueFrom="@dimen/ut_guidedstep_entry_slide_from"
- android:valueTo="0.0"
- android:valueType="floatType" />
-
- <objectAnimator
- android:duration="@integer/ut_entry_anim_duration"
- android:propertyName="alpha"
- android:valueFrom="0.0"
- android:valueTo="1.0"
- android:valueType="floatType" />
-
-</set>
diff --git a/usbtuner-res/animator/setup_exit.xml b/usbtuner-res/animator/setup_exit.xml
deleted file mode 100644
index 4ce89cd6..00000000
--- a/usbtuner-res/animator/setup_exit.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/fast_out_linear_in"
- android:ordering="together" >
-
- <objectAnimator
- android:duration="@integer/ut_exit_anim_duration"
- android:propertyName="translationX"
- android:valueFrom="0.0"
- android:valueTo="@dimen/ut_guidedstep_exit_slide_to"
- android:valueType="floatType" />
-
- <objectAnimator
- android:duration="@integer/ut_exit_anim_duration"
- android:propertyName="alpha"
- android:valueFrom="1.0"
- android:valueTo="0.0"
- android:valueType="floatType" />
-
-</set>
diff --git a/usbtuner-res/drawable-xhdpi/ic_setup_antenna.png b/usbtuner-res/drawable-xhdpi/ic_setup_antenna.png
deleted file mode 100644
index bb6d416e..00000000
--- a/usbtuner-res/drawable-xhdpi/ic_setup_antenna.png
+++ /dev/null
Binary files differ
diff --git a/usbtuner-res/drawable/ut_selector_background.xml b/usbtuner-res/drawable/ut_selector_background.xml
deleted file mode 100644
index fb3899aa..00000000
--- a/usbtuner-res/drawable/ut_selector_background.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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.
- -->
-
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:enterFadeDuration="@android:integer/config_shortAnimTime"
- android:exitFadeDuration="@android:integer/config_shortAnimTime"
- android:color="?android:attr/colorControlHighlight">
- <item android:id="@android:id/mask">
- <shape android:shape="rectangle" >
- <solid android:color="@android:color/white" />
- <corners android:radius="2dp" />
- </shape>
- </item>
-</ripple>
diff --git a/usbtuner-res/layout/ut_activity_playback.xml b/usbtuner-res/layout/ut_activity_playback.xml
deleted file mode 100644
index b640e6d5..00000000
--- a/usbtuner-res/layout/ut_activity_playback.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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.
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:keepScreenOn="true"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- <SurfaceView
- android:id="@+id/surface1"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-</LinearLayout>
diff --git a/usbtuner-res/layout/ut_guidance.xml b/usbtuner-res/layout/ut_guidance.xml
deleted file mode 100644
index 4f7d3f7a..00000000
--- a/usbtuner-res/layout/ut_guidance.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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.
- -->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"
- android:paddingStart="@dimen/ut_guidance_padding_start"
- android:paddingEnd="@dimen/ut_guidance_padding_end"
- android:paddingTop="@dimen/ut_guidance_padding_top"
- android:clipToPadding="false"
- android:clipChildren="false" >
- <ImageView
- android:id="@+id/guidance_icon"
- android:visibility="gone"
- style="?attr/guidanceIconStyle"
- tools:ignore="ContentDescription" />
- <RelativeLayout
- style="?attr/guidanceContainerStyle" >
- <Space
- android:id="@+id/guidance_anchor_space"
- style="@style/ut_guidance_anchor" />
- <TextView
- android:id="@+id/guidance_title"
- style="?attr/guidanceTitleStyle" />
- <TextView
- android:id="@+id/guidance_breadcrumb"
- style="?attr/guidanceBreadcrumbStyle" />
- <TextView
- android:id="@+id/guidance_description"
- style="?attr/guidanceDescriptionStyle" />
- </RelativeLayout>
-</FrameLayout>
diff --git a/usbtuner-res/layout/ut_guidedactions.xml b/usbtuner-res/layout/ut_guidedactions.xml
deleted file mode 100644
index ae7efc0d..00000000
--- a/usbtuner-res/layout/ut_guidedactions.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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.
- -->
-
-<!-- Layout for the settings list fragment -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@null"
- android:paddingStart="@dimen/ut_guidedactions_padding_start"
- android:paddingEnd="@dimen/ut_guidedactions_padding_end"
- android:paddingTop="@dimen/ut_guidedactions_padding_top"
- android:paddingBottom="@dimen/ut_guidedactions_padding_bottom"
- android:clipToPadding="false"
- android:clipChildren="false" >
- <RelativeLayout
- style="?attr/guidedActionsContainerStyle" >
- <Space
- android:id="@+id/guidedactions_anchor_space"
- style="@style/ut_guidedactions_anchor" />
- <FrameLayout
- android:id="@+id/guidedactions_selector"
- style="@style/ut_guidedactions_null_selector" />
- <android.support.v17.leanback.widget.VerticalGridView
- android:id="@+id/guidedactions_list"
- style="?attr/guidedActionsListStyle" />
- </RelativeLayout>
-</FrameLayout> \ No newline at end of file
diff --git a/usbtuner-res/raw/ut_euro_dvbt_all b/usbtuner-res/raw/ut_euro_dvbt_all
new file mode 100644
index 00000000..101ee3eb
--- /dev/null
+++ b/usbtuner-res/raw/ut_euro_dvbt_all
@@ -0,0 +1,287 @@
+# Euro DVB-T frequencies
+# Only Germany and England frequencies are added now.
+
+# Frequencies from Germany
+T 474000000 QAM16
+T 474000000 QAM64
+T 482000000 QAM16
+T 490000000 QAM16
+T 498000000 QAM16
+T 498000000 QAM64
+T 506000000 QAM16
+T 506000000 QAM64
+T 514000000 QAM16
+T 522000000 QAM16
+T 522000000 QAM64
+T 530000000 QAM16
+T 538000000 QAM16
+T 538000000 QAM64
+T 546000000 QAM16
+T 554000000 QAM16
+T 554000000 QAM64
+T 562000000 QAM16
+T 562000000 QAM64
+T 570000000 QAM16
+T 578000000 QAM16
+T 578000000 QAM64
+T 586000000 QAM16
+T 594000000 QAM16
+T 602000000 QAM16
+T 602000000 QAM64
+T 610000000 QAM16
+T 610000000 QAM64
+T 618000000 QAM16
+T 618000000 QAM64
+T 626000000 QAM16
+T 634000000 QAM16
+T 634000000 QAM64
+T 642000000 QAM16
+T 650000000 QAM16
+T 658000000 QAM16
+T 666000000 QAM16
+T 674000000 QAM16
+T 674000000 QAM64
+T 682000000 QAM16
+T 690000000 QAM16
+T 690000000 QAM64
+T 698000000 QAM16
+T 698000000 QAM64
+T 706000000 QAM16
+T 722000000 QAM16
+T 730000000 QAM16
+T 730000000 QAM64
+T 738000000 QAM16
+T 738000000 QAM64
+T 746000000 QAM16
+T 746000000 QPSK
+T 754000000 QAM16
+T 762000000 QAM16
+T 770000000 QAM16
+T 778000000 QAM16
+T 786000000 QAM16
+
+# Frequencies from England
+T 474000000 QAM16
+T 474000000 QAM64
+T 474167000 QAM16
+T 474167000 QAM64
+T 481833000 QAM16
+T 481833000 QAM64
+T 481833330 QAM64
+T 482000000 QAM16
+T 482167000 QAM16
+T 482167000 QAM64
+T 489833000 QAM16
+T 489833000 QAM64
+T 490000000 QAM16
+T 490000000 QAM64
+T 490167000 QAM16
+T 490167000 QAM64
+T 497833000 QAM16
+T 497833000 QAM64
+T 498000000 QAM16
+T 498000000 QAM64
+T 498167000 QAM16
+T 498167000 QAM64
+T 505833000 QAM16
+T 505833000 QAM64
+T 505833330 QAM16
+T 506000000 QAM16
+T 506000000 QAM64
+T 506167000 QAM16
+T 506167000 QAM64
+T 513833000 QAM16
+T 514000000 QAM16
+T 514000000 QAM64
+T 514167000 QAM16
+T 514167000 QAM64
+T 521833000 QAM64
+T 522000000 QAM16
+T 522000000 QAM64
+T 522167000 QAM16
+T 529833000 QAM16
+T 529833000 QAM64
+T 529833330 QAM16
+T 530000000 QAM16
+T 530000000 QAM64
+T 530167000 QAM16
+T 530167000 QAM64
+T 537833000 QAM64
+T 537833330 QAM16
+T 538000000 QAM16
+T 538000000 QAM64
+T 538167000 QAM16
+T 538167000 QAM64
+T 545833000 QAM16
+T 545833000 QAM64
+T 546000000 QAM16
+T 546000000 QAM64
+T 546167000 QAM16
+T 546167000 QAM64
+T 553833000 QAM16
+T 553833000 QAM64
+T 554000000 QAM16
+T 554000000 QAM64
+T 561833000 QAM16
+T 561833000 QAM64
+T 561833330 QAM64
+T 562000000 QAM16
+T 562000000 QAM64
+T 562167000 QAM16
+T 569833000 QAM64
+T 570000000 QAM16
+T 570167000 QAM16
+T 577833000 QAM16
+T 578000000 QAM16
+T 578000000 QAM64
+T 578166670 QAM16
+T 578167000 QAM16
+T 578167000 QAM64
+T 586000000 QAM16
+T 594000000 QAM16
+T 602000000 QAM16
+T 602000000 QAM64
+T 610000000 QAM16
+T 610000000 QAM64
+T 618000000 QAM16
+T 618000000 QAM64
+T 618167000 QAM16
+T 625833000 QAM64
+T 626000000 QAM16
+T 626000000 QAM64
+T 626167000 QAM16
+T 626167000 QAM64
+T 633833000 QAM64
+T 634000000 QAM16
+T 634000000 QAM64
+T 634167000 QAM16
+T 634167000 QAM64
+T 641833000 QAM16
+T 642000000 QAM16
+T 642000000 QAM64
+T 642167000 QAM64
+T 649833000 QAM16
+T 650000000 QAM16
+T 650000000 QAM64
+T 650167000 QAM16
+T 650167000 QAM64
+T 657833000 QAM16
+T 657833000 QAM64
+T 658000000 QAM64
+T 658000000 QAM16
+T 658167000 QAM16
+T 658167000 QAM64
+T 665833000 QAM16
+T 665833000 QAM64
+T 666000000 QAM16
+T 666000000 QAM64
+T 666167000 QAM16
+T 673833000 QAM16
+T 674000000 QAM16
+T 674000000 QAM64
+T 674167000 QAM16
+T 681833000 QAM16
+T 682000000 QAM16
+T 682000000 QAM64
+T 682167000 QAM16
+T 682167000 QAM64
+T 689833000 QAM64
+T 690000000 QAM16
+T 690000000 QAM64
+T 690167000 QAM16
+T 690167000 QAM64
+T 697833000 QAM16
+T 698000000 QAM16
+T 698000000 QAM64
+T 698167000 QAM16
+T 705833000 QAM16
+T 706000000 QAM16
+T 706000000 QAM64
+T 706167000 QAM16
+T 706167000 QAM64
+T 713833000 QAM16
+T 713833000 QAM64
+T 714000000 QAM16
+T 714000000 QAM64
+T 714167000 QAM16
+T 714167000 QAM64
+T 721833000 QAM16
+T 722000000 QAM16
+T 722167000 QAM16
+T 722167000 QAM64
+T 729833000 QAM16
+T 729833000 QAM64
+T 730000000 QAM16
+T 730000000 QAM64
+T 730167000 QAM16
+T 737833000 QAM16
+T 738000000 QAM16
+T 738000000 QAM64
+T 738167000 QAM16
+T 738167000 QAM64
+T 745833000 QAM16
+T 745833000 QAM64
+T 746000000 QAM16
+T 746000000 QAM64
+T 746000000 QPSK
+T 746167000 QAM64
+T 753833000 QAM16
+T 753833000 QAM64
+T 754000000 QAM16
+T 754000000 QAM64
+T 754167000 QAM16
+T 761833000 QAM16
+T 761833000 QAM64
+T 762000000 QAM16
+T 762000000 QAM256
+T 762000000 QAM64
+T 762167000 QAM16
+T 762167000 QAM64
+T 769833000 QAM64
+T 770000000 QAM16
+T 770000000 QAM64
+T 770167000 QAM16
+T 770167000 QAM64
+T 777833000 QAM16
+T 777833000 QAM64
+T 778000000 QAM16
+T 778000000 QAM64
+T 778167000 QAM16
+T 778167000 QAM64
+T 785833000 QAM16
+T 785833000 QAM64
+T 786000000 QAM16
+T 786000000 QAM64
+T 786167000 QAM16
+T 786167000 QAM64
+T 793833000 QAM64
+T 794000000 QAM64
+T 794167000 QAM16
+T 794167000 QAM64
+T 801833000 QAM16
+T 801833000 QAM64
+T 802000000 QAM16
+T 802000000 QAM64
+T 802167000 QAM16
+T 802167000 QAM64
+T 809833000 QAM16
+T 810000000 QAM16
+T 810167000 QAM16
+T 817833000 QAM16
+T 818000000 QAM16
+T 818167000 QAM16
+T 825833000 QAM16
+T 825833000 QAM64
+T 826000000 QAM16
+T 826167000 QAM16
+T 826167000 QAM64
+T 833833000 QAM64
+T 834000000 QAM16
+T 834000000 QAM64
+T 834167000 QAM16
+T 834167000 QAM64
+T 842000000 QAM16
+T 842000000 QAM64
+T 842167000 QAM64
+T 850000000 QAM16
+T 850000000 QAM64 \ No newline at end of file
diff --git a/usbtuner-res/raw/ut_kr_all b/usbtuner-res/raw/ut_kr_all
index 85320125..9c4d7e64 100644
--- a/usbtuner-res/raw/ut_kr_all
+++ b/usbtuner-res/raw/ut_kr_all
@@ -1,5 +1,4 @@
# KR ATSC center frequencies
-# TODO: Verify this.
A 473028615 8VSB
A 479028615 8VSB
diff --git a/usbtuner-res/raw/ut_kr_atsc_center_frequencies_8vsb b/usbtuner-res/raw/ut_kr_atsc_center_frequencies_8vsb
index 4ddbf0b6..14678d3a 100644
--- a/usbtuner-res/raw/ut_kr_atsc_center_frequencies_8vsb
+++ b/usbtuner-res/raw/ut_kr_atsc_center_frequencies_8vsb
@@ -1,5 +1,4 @@
# KR ATSC center frequencies
-# TODO: Verify this.
A 473028615 8VSB
A 479028615 8VSB
diff --git a/usbtuner-res/raw/ut_us_all b/usbtuner-res/raw/ut_us_all
index f3d2d8fa..a5bd846a 100644
--- a/usbtuner-res/raw/ut_us_all
+++ b/usbtuner-res/raw/ut_us_all
@@ -1,5 +1,4 @@
# US ATSC center frequencies
-# TODO: Verify this.
A 57028615 8VSB 2
A 63028615 8VSB 3
@@ -71,7 +70,6 @@ A 797028615 8VSB 68
A 803028615 8VSB 69
# US EIA/NCTA Standard Cable center frequencies
# Channels are in ascending EIA/NCTA channel designation order
-# TODO: Verify this.
#2
A 57000000 QAM256
diff --git a/usbtuner-res/raw/ut_us_atsc_center_frequencies_8vsb b/usbtuner-res/raw/ut_us_atsc_center_frequencies_8vsb
index bb59e07e..245a68a8 100644
--- a/usbtuner-res/raw/ut_us_atsc_center_frequencies_8vsb
+++ b/usbtuner-res/raw/ut_us_atsc_center_frequencies_8vsb
@@ -1,5 +1,4 @@
# US ATSC center frequencies
-# TODO: Verify this.
A 57028615 8VSB 2
A 63028615 8VSB 3
diff --git a/usbtuner-res/raw/ut_us_cable_standard_center_frequencies_qam256 b/usbtuner-res/raw/ut_us_cable_standard_center_frequencies_qam256
index d2d5e302..f42a5141 100644
--- a/usbtuner-res/raw/ut_us_cable_standard_center_frequencies_qam256
+++ b/usbtuner-res/raw/ut_us_cable_standard_center_frequencies_qam256
@@ -1,6 +1,5 @@
# US EIA/NCTA Standard Cable center frequencies
# Channels are in ascending EIA/NCTA channel designation order
-# TODO: Verify this.
#2
A 57000000 QAM256
diff --git a/usbtuner-res/values-af/strings.xml b/usbtuner-res/values-af/strings.xml
index 4337a696..8fd50706 100644
--- a/usbtuner-res/values-af/strings.xml
+++ b/usbtuner-res/values-af/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV-ontvanger"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB-TV-ontvanger"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Aan"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Af"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Netwerk-TV-ontvanger (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Wag asseblief dat verwerking voltooi word"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Kies jou kanaalbron"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Geen sein nie"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Kon nie op <xliff:g id="CHANNEL_NAME">%s</xliff:g> inskakel nie"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Kon nie inskakel nie"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Ontvangersagteware is onlangs opgedateer. Herskandeer die kanale asseblief."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Aktiveer omringklank in stelselklankinstellings om oudio te aktiveer"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Kan nie oudio speel nie. Probeer asseblief \'n ander TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Opstelling van kanaalontvanger"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Opstelling van TV-ontvanger"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Opstelling van USB-kanaalontvanger"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Opstelling van netwerkontvanger"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Maak seker dat jou TV aan \'n TV-seinbron gekoppel is.\n\nAs jy \'n oor-die-lug-antenna gebruik, sal jy dalk sy plasing of rigting moet verander om die meeste kanale te ontvang. Plaas dit vir die beste resultate hoog en naby \'n venster."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Maak seker dat die USB-ontvanger ingeprop en aan \'n TV-seinbron gekoppel is.\n\nAs jy \'n oor-die-lug-antenna gebruik, sal jy dalk sy posisie of rigting moet verander om die meeste kanale te ontvang. Plaas dit vir die beste resultate hoog en naby \'n venster."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Maak seker dat die netwerkontvanger aangeskakel is en aan \'n TV-seinbron gekoppel is.\n\nAs jy \'n oor-die-lug-antenna gebruik, sal jy dalk sy plasing of rigting waarin hy wys, moet verstel om die meeste kanale te ontvang. Plaas dit vir die beste resultate hoog en naby \'n venster."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Gaan voort"</item>
<item msgid="727245208787621142">"Nie nou nie"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Doen kanaalopstelling weer?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Dit sal die kanale wat ontvang is, uit die TV-ontvanger verwyder en weer nuwe kanale soek.\n\nMaak seker dat jou TV aan \'n TV-seinbron gekoppel is.\n\nAs jy \'n oor-die-lug-antenna gebruik, sal jy dalk sy plasing of rigting moet verander om die meeste kanale te ontvang. Plaas dit vir die beste resultate hoog en naby \'n venster."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Dit sal die kanale wat gevind is, uit die USB-ontvanger verwyder en weer nuwe kanale soek.\n\nMaak seker dat die USB-ontvanger ingeprop en aan \'n TV-seinbron gekoppel is.\n\nAs jy \'n oor-die-lug-antenna gebruik, sal jy dalk sy posisie of rigting moet verander om die meeste kanale te ontvang. Plaas dit vir die beste resultate hoog en naby \'n venster."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Dit sal die kanale wat gevind is van die netwerkontvanger af verwyder en weer na nuwe kanale soek.\n\nMaak seker dat die netwerkontvanger aangeskakel is en aan \'n TV-seinbron gekoppel is.\n\nAs jy \'n oor-die-lug-antenna gebruik, sal jy dalk sy plasing of rigting waarin hy wys, moet verstel om die meeste kanale te ontvang. Plaas dit vir die beste resultate hoog en naby \'n venster."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Gaan voort"</item>
<item msgid="235450158666155406">"Kanselleer"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Opstelling van TV-ontvanger"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Opstelling van USB-kanaalontvanger"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Opstelling van netwerkkanaalontvanger"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Dit kan \'n paar minute neem"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Seinontvanger is tydelik nie beskikbaar nie of word reeds deur opname gebruik."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Geen kanale gevind nie"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Geen kanale is in die soektog gevind nie. Maak seker dat jou TV aan \'n TV-seinbron gekoppel is.\n\nAs jy \'n oor-die-lug-antenna gebruik, verander sy plasing of rigting. Plaas dit vir die beste resultate hoog en naby \'n venster en soek weer."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Geen kanale is in die soektog gevind nie. Maak seker dat die USB-ontvanger ingeprop en aan \'n TV-seinbron gekoppel is.\n\nAs jy \'n oor-die-lug-antenna gebruik, verander sy posisie of rigting. Plaas dit vir die beste resultate hoog en naby \'n venster en soek weer."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Geen kanale is in die soektog gevind nie. Maak seker dat die netwerkontvanger aangeskakel is en aan \'n TV-seinbron gekoppel is.\n\nAs jy \'n oor-die-lug-antenna gebruik, verstel sy plasing of rigting waarin hy wys. Plaas dit vir die beste resultate hoog en naby \'n venster en soek weer."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Soek weer"</item>
<item msgid="2092797862490235174">"Klaar"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Soek TV-kanale"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Opstelling van TV-ontvanger"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Opstelling van USB-TV-ontvanger"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB-TV-ontvanger is ontkoppel."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Soek TV-kanale"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Opstelling van TV-ontvanger"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Opstelling van USB-TV-ontvanger"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Opstelling van netwerk-TV-ontvanger"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-TV-ontvanger is ontkoppel."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Netwerkontvanger is ontkoppel."</string>
</resources>
diff --git a/usbtuner-res/values-am/strings.xml b/usbtuner-res/values-am/strings.xml
index a903ee76..cbf1e9fe 100644
--- a/usbtuner-res/values-am/strings.xml
+++ b/usbtuner-res/values-am/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"የቴሌቪዥን መቃኛ"</string>
<string name="ut_app_name" msgid="8557698013780762454">"የዩኤስቢ ቴሌቪዥን መቃኛ"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"በርቷል"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"ጠፍቷል"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"የአውታረ መረብ ቴሌቪዥን መቃኛ (ቅድመ-ይሁንታ)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"ማስኬድን ለማጠናቀቅ እባክዎ ይጠብቁ"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"የጣቢያ ምንጭዎን ይምረጡ"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"ምንም ሲግናል የለም"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"ወደ <xliff:g id="CHANNEL_NAME">%s</xliff:g> መቃኘት አልተሳካም"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"መቃኘት አልተሳካም"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"የቴሌቪዥን መቃኛ ሶፍትዌር በቅርብ ጊዜ ተዘምኗል። እባክዎ ሰርጦቹን እንደገና ይቃኟቸው።"</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ኦዲዮን ለማንቃት በስርዓት ድምጽ ቅንብሮች ውስጥ የዙሪያ ድምጽን ያንቁ"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"ኦዲዮ ማጫወት አይቻልም። እባክዎ ሌላ ቲቪ ይሞክሩ።"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"የጣቢያ መቃኛ ማዋቀር"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"የቴሌቪዥን መቃኛ ማዋቀር"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"የዩኤስቢ ጣቢያ መቃኛ ማዋቀር"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"የአውታረ መረብ መቃኛ ማዋቀር"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"የእርስዎ ቴሌቪዥን ከቴሌቪዥን ሲግናል ምልክት ምንጭ ጋር መገናኘቱን ያረጋግጡ።\n\nየአየር ላይ አንቴና የሚጠቀሙ ከሆነ አብዛኛዎቹን ጣቢያዎች ለመቀበል አቀማመጡን ወይም አቅጣጫውን ማስተካከል ሊኖርብዎት ይችላል። ለተሻሉ ውጤቶች ከፍ አድርገው ከመስኮት አጠገብ ያስቀምጡት።"</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"የዩኤስቢ መቃኛው መሰካቱን እና ከቴሌቪዥን ምልክት ምንጭ ጋር መገናኘቱን ያረጋግጡ።\n\nየአየር ላይ አንቴና የሚጠቀሙ ከሆነ አቀማመጡን ወይም አቅጣጫውን ያስተካክሉ። ለተሻሉ ውጤቶች ከፍ አድርገው ከመስኮት አጠገብ ያስቀምጡት።"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"የአውታረ መረብ መቃኛው እና ከቴሌቪዥን ምልክት ምንጭ ጋር መገናኘቱን ያረጋግጡ።\n\nየአየር ላይ አንቴና የሚጠቀሙ ከሆነ አቀማመጡን ወይም አቅጣጫውን ያስተካክሉ። ለተሻሉ ውጤቶች ከፍ አድርገው ከመስኮት አጠገብ ያስቀምጡት።"</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"ቀጥል"</item>
<item msgid="727245208787621142">"አሁን አይደለም"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"የጣቢያ ቅንብር እንደገና እንዲሄድ ይደረግ?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"ይሄ ከቴሌቪዥን መቃኛ የተገኙ ጣቢያዎችን አስወግዶ አዲስ ጣቢያዎችን እንደገና ይቃኛል።\n\nየእርስዎ ቴሌቪዥን ከቴሌቪዥን ሲግናል ምልክት ምንጭ ጋር መገናኘቱን ያረጋግጡ።\n\nየአየር ላይ አንቴና የሚጠቀሙ ከሆነ አብዛኛዎቹን ጣቢያዎች ለመቀበል አቀማመጡን ወይም አቅጣጫውን ማስተካከል ሊኖርብዎት ይችላል። ለተሻሉ ውጤቶች ከፍ አድርገው ከመስኮት አጠገብ ያስቀምጡት።"</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"ይሄ ከዩኤስቢ መቃኛ የተገኙ ጣቢያዎችን አስወግዶ አዲስ ጣቢያዎችን እንደገና ይቃኛል።\n\nየዩኤስቢ መቃኛው መሰካቱን እና ከቴሌቪዥን ምልክት ምንጭ ጋር መገናኘቱን ያረጋግጡ።\n\nየአየር ላይ አንቴና የሚጠቀሙ ከሆነ አቀማመጡን ወይም አቅጣጫውን ያስተካክሉ። ለተሻሉ ውጤቶች ከፍ አድርገው ከመስኮት አጠገብ ያስቀምጡት።"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"ይሄ ከአውታረ መረብ መቃኛ የተገኙ ጣቢያዎችን አስወግዶ አዲስ ጣቢያዎችን እንደገና ይቃኛል።\n\nየአውታረ መረብ መቃኛው እና ከቴሌቪዥን ምልክት ምንጩ መገናኘቱን ያረጋግጡ።\n\nየአየር ላይ አንቴና የሚጠቀሙ ከሆነ አቀማመጡን ወይም አቅጣጫውን ያስተካክሉ። ለተሻሉ ውጤቶች ከፍ አድርገው ከመስኮት አጠገብ ያስቀምጡት።"</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"ቀጥል"</item>
<item msgid="235450158666155406">"ይቅር"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"የቴሌቪዥን መቃኛ ማዋቀር"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"የዩኤስቢ ጣቢያ መቃኛ ማዋቀር"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"የአውታረ መረብ ጣቢያ መቃኛ ማዋቀር"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"ይሄ በርካታ ደቂቃዎችን ሊወስድ ይችላል"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"መቃኛው ለጊዜው አይገኝም ወይም አስቀድሞ በቀረጻው ጥቅም ላይ ውሏል።"</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"ምንም ጣቢያዎች አልተገኙም"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"ቅኝቱ ምንም አዲስ ጣቢያዎችን አላገኘም። የእርስዎ ቴሌቪዥን ከቴሌቪዥን ሲግናል ምንጭ ጋር መገናኘቱን ያረጋግጡ።\n\nየአየር ላይ አንቴና ከሆነ የሚጠቀሙት አቀማመጡን ወይም አቅጣጫውን ያስተካክሉት። ለተሻሉ ውጤቶች ከፍ አድርገው ከመስኮት አጠገብ ያስቀምጡትና እንደገና ይቃኙ።"</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"ቅኝቱ ምንም ጣቢያዎችን አላገኘም። የዩኤስቢ መቃኛው መሰካቱን እና ከቴሌቪዥን ሲግናል ምንጩ ጋር መገናኘቱን ያረጋግጡ።\n\nየአየር ላይ አንቴና የሚጠቀሙ ከሆነ አቀማመጡን ወይም አቅጣጫውን ያስተካክሉ። ለተሻሉ ውጤቶች ከፍ አድርገው ከመስኮት አጠገብ ያስቀምጡት እና እንደገና ይቃኙ።"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"ቅኝቱ ምንም ጣቢያዎችን አላገኘም። የአውታረ መረብ መቃኛው እንደበራ እና ከቴሌቪዥን ሲግናል ምንጩ ጋር መገናኘቱን ያረጋግጡ።\n\nየአየር ላይ አንቴና የሚጠቀሙ ከሆነ አቀማመጡን ወይም አቅጣጫውን ያስተካክሉ። ለተሻሉ ውጤቶች ከፍ አድርገው ከመስኮት አጠገብ ያስቀምጡት እና እንደገና ይቃኙ።"</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"እንደገና ቃኝ"</item>
<item msgid="2092797862490235174">"ተከናውኗል"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"የቲቪ ጣቢያዎችን ቃኝ"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"የቴሌቪዥን መቃኛ ማዋቀር"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"የዩኤስቢ ቴሌቪዥን መቃኛ ማዋቀር"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"የUSB TV መቃኛ ግንኙነቱ ተቋርጧል።"</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"የቴሌቪዥን ጣቢያዎችን ቃኝ"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"የቴሌቪዥን መቃኛ ማዋቀር"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"የዩኤስቢ ቴሌቪዥን መቃኛ ማዋቀር"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"የአውታረ መረብ ቴሌቪዥን መቃኛ ማዋቀር"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"የዩኤስቢ ቴሌቪዥን መቃኛው ግንኙነት ተቋርጧል።"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"የአውታረ መረብ መቃኛ ግንኙነት ተቋርጧል።"</string>
</resources>
diff --git a/usbtuner-res/values-ar/strings.xml b/usbtuner-res/values-ar/strings.xml
index ecfde3e8..ae197d19 100644
--- a/usbtuner-res/values-ar/strings.xml
+++ b/usbtuner-res/values-ar/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"موالف التلفزيون"</string>
<string name="ut_app_name" msgid="8557698013780762454">"‏موالف التلفزيون عبر USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"تشغيل"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"إيقاف"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"موالف التلفزيون على الشبكة (تجريبي)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"الرجاء الانتظار لحين انتهاء المعالجة"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"تحديد مصدر القنوات"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"لا توجد إشارة"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"أخفق الضبط على <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"أخفق الضبط"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"تم تحديث برنامج الموالف مؤخرًا. الرجاء إعادة البحث عن القنوات."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"يمكنك تشغيل الصوت المحيطي في إعدادات صوت النظام لتفعيل الصوت"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"لا يمكن تشغيل الصوت. الرجاء تجربة تلفزيون آخر."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"إعداد موالف القنوات"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"إعداد موالف التلفزيون"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"‏إعداد موالف قنوات USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"إعداد موالف الشبكة"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"تحقق من توصيل التلفزيون بمصدر إشارة البث التلفزيوني.\n\nإذا كنت تستخدم هوائيًا للتحديث عبر الهواء، فقد تحتاج إلى ضبط موضعه أو اتجاهه لاستقبال معظم القنوات، وللحصول على أفضل النتائج، ضعه عاليًا بالقرب من النافذة."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"‏تحقق من توصيل الموالف عبر USB بمصدر إشارة البث التلفزيوني.\n\nإذا كنت تستخدم هوائيًا للتحديث عبر الهواء، فقد تحتاج إلى ضبط موضعه أو اتجاهه لاستقبال معظم القنوات، وللحصول على أفضل النتائج، ضعه عاليًا بالقرب من النافذة."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"تحقق من تشغيل موالف الشبكة وتوصيله بمصدر إشارة التلفزيون.\n\nفي حالة استخدام هوائي للتحديث عبر الهواء، قد تحتاج إلى ضبط موضعه أو تجاهه لاستقبال معظم القنوات. وللحصول على أفضل النتائج، يمكنك وضعه في مكان مرتفع أو بالقرب من النافذة."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"متابعة"</item>
<item msgid="727245208787621142">"ليس الآن"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"هل تريد إعادة تشغيل إعداد القنوات؟"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"سيؤدي هذا إلى إزالة القنوات التي تم العثور عليها من موالف التلفزيون والبحث مرة أخرى عن قنوات جديدة.\n\nتحقق من توصيل التلفزيون بمصدر إشارة البث التلفزيوني.\n\nإذا كنت تستخدم هوائيًا للتحديث عبر الهواء، فقد تحتاج إلى ضبط موضعه أو اتجاهه لاستقبال معظم القنوات، وللحصول على أفضل النتائج، ضعه عاليًا بالقرب من النافذة."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"‏سيؤدي هذا إلى إزالة القنوات التي تم العثور عليها من الموالف عبر USB والبحث مرة أخرى عن قنوات جديدة.\n\nتحقق من توصيل الموالف عبر USB بمصدر إشارة البث التلفزيوني.\n\nإذا كنت تستخدم هوائيًا للتحديث عبر الهواء، فقد تحتاج إلى ضبط موضعه أو اتجاهه لاستقبال معظم القنوات، وللحصول على أفضل النتائج، ضعه عاليًا بالقرب من النافذة."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"سيؤدي هذا إلى إزالة القنوات الموجودة من موالف الشبكة وإعادة المسح بحثًا عن القنوات الجديدة.\n\nتحقق من تشغيل موالف الشبكة وتوصيله بمصدر إشارة التلفزيون.\n\nفي حالة استخدام هوائي للتحديث عبر الهواء، قد تحتاج إلى ضبط موضعه أو تجاهه لاستقبال معظم القنوات. وللحصول على أفضل النتائج، يمكنك وضعه في مكان مرتفع أو بالقرب من النافذة."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"متابعة"</item>
<item msgid="235450158666155406">"إلغاء"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"إعداد موالف التلفزيون"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"‏إعداد موالف قنوات USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"إعداد موالف قناة الشبكة"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"قد يستغرق هذا عدة دقائق"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"لا يتوفر الموالف مؤقتًا أو سبق استخدامه بواسطة التسجيل."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -88,12 +88,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"لم يتم العثور على قنوات"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"لم يتم العثور على أي قنوات أثناء البحث، لذا عليك التحقق من توصيل التلفزيون بمصدر إشارة البث التلفزيوني.\n\nإذا كنت تستخدم هوائيًا للتحديث عبر الهواء، فاضبط موضعه أو اتجاهه، وللحصول على أفضل النتائج، ضعه عاليًا بالقرب من النافذة ثم أعد البحث."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"‏لم يتم العثور على أي قنوات أثناء البحث، تحقق من توصيل الموالف عبر USB بمصدر إشارة البث التلفزيوني.\n\nإذا كنت تستخدم هوائيًا للتحديث عبر الهواء، فاضبط موضعه أو اتجاهه، وللحصول على أفضل النتائج، ضعه عاليًا بالقرب من النافذة ثم أعد البحث."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"لم يتم العثور على أي قنوات خلال المسح. تحقق من تشغيل موالف الشبكة وتوصيله بمصدر إشارة التلفزيون.\n\nفي حالة استخدام هوائي للتحديث عبر الهواء، يجب ضبط موضعه أو تجاهه. وللحصول على أفضل النتائج، يمكنك وضعه في مكان مرتفع أو بالقرب من النافذة وإعادة المسح."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"بحث مرة أخرى"</item>
<item msgid="2092797862490235174">"تم"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"البحث عن قنوات تلفزيونية"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"إعداد موالف التلفزيون"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"‏إعداد موالف التلفزيون عبر USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"‏تم فصل موالف التلفزيون عبر USB."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"البحث عن قنوات تلفزيونية"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"إعداد موالف التلفزيون"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"‏إعداد موالف التلفزيون عبر USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"إعداد موالف التلفزيون على الشبكة"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"‏تم فصل موالف التلفزيون عبر USB."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"تم فصل موالف الشبكة."</string>
</resources>
diff --git a/usbtuner-res/values-az-rAZ/strings.xml b/usbtuner-res/values-az-rAZ/strings.xml
new file mode 100644
index 00000000..2022ad7b
--- /dev/null
+++ b/usbtuner-res/values-az-rAZ/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"TV Kökləyici"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB TV Kökləyici"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Network TV Tuner (BETA)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Lütfən, prosesi başa çatdırmaq üçün gözləyin"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Sazlayıcı proqram təminatı yenicə güncəllənib. Kanalları yenidən skan edin."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Audionu aktiv etmək üçün sistem səs ayarlarında əhatəli səsi aktiv edin"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Audio oxuna bilmir. Digər TV-dən istifadə edin"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanal kökləyici quraşdırması"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"TV Kökləyici quraşdırması"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB Kanal kökləyici quraşdırması"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Şəbəkə kökləyici quraşdırması"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"TV-nizin TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB kökləyicinin taxılı olduğunu və TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Şəbəkə kökləyicinin yanılı olduğunu və TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Davam edin"</item>
+ <item msgid="727245208787621142">"İndi yox"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Kanal quraşdırması yenidən işə salınsın?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Bu, TV kökləyici ilə tapılmış kanalları siləcək və yeni kanalları yenidən skan edəcək.\n\nTV-nizin TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"Bu USB kökləyici ilə tapılmış kanalları siləcək və yeni kanalları yenidən skan edəcək.\n\nUSB kökləyicinin taxılı olduğunu və TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Bu Şəbəkə kökləyici ilə tapılmış kanalları siləcək və yeni kanalları yenidən skan edəcək.\n\nŞəbəkə kökləyicinin yanılı olduğunu və TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Davam edin"</item>
+ <item msgid="235450158666155406">"Ləğv edin"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Bağlantı növünü seçin"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Əgər kökləyiciyə xarici antena qoşulubsa Antena seçimini edin. Əgər kanallar kabel xidməti provayderi ilə gəlirsə, onda Kabel seçimini edin. Əgər əmin deyilsinizsə, hər iki növ skan ediləcək, amma bu çox vaxt çəkəcək."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Antena"</item>
+ <item msgid="2670079958754180142">"Kabel"</item>
+ <item msgid="36774059871728525">"Əmin deyiləm"</item>
+ <item msgid="6881204453182153978">"Yalnız inkişaf"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"TV kökləyici quraşdırması"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB Kanal kökləyici quraşdırması"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Şəbəkə kanalı kökləyici quraşdırması"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Bu bir neçə dəqiqə çəkə bilər"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Kökləyici müvəqqəti əlçatan deyil və qeydə alma tərəfindən istifadə olunub."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d kanal tapıldı</item>
+ <item quantity="one">%1$d kanal tapıldı</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"KANAL SKANINI DAYANDIRIN"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d kanal tapıldı</item>
+ <item quantity="one">%1$d kanal tapıldı</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">Yaxşıdır! Kanal skanı zamanı %1$d kanal tapıldı. Əgər düzgün deyilsə, antenanın yerini dəyişin və yenidən skan edin.</item>
+ <item quantity="one">Yaxşıdır! Kanal skanı zamanı %1$d kanal tapıldı. Əgər düzgün deyilsə, antenanın yerini dəyişin və yenidən skan edin.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Hazırdır"</item>
+ <item msgid="2480490326672924828">"Yenidən skan edin"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Kanal tapılmadı"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Skan ilə heç bir kanal tapılmadı. TV-nizin TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Skan ilə heç bir kanal tapılmadı. USB kökləyicinin taxılı olduğunu və TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Skan ilə heç bir kanal tapılmadı. Şəbəkə kökləyicinin yanılı olduğunu və TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Yenidən skan edin"</item>
+ <item msgid="2092797862490235174">"Hazırdır"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"TV kanalları üçün skan"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV Kökləyici quraşdırması"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV Kökləyici quraşdırması"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Şəbəkə TV Kökləyici quraşdırması"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV kökləyicisinin bağlantısı kəsildi."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Şəbəkə kökləyicisinin bağlantısı kəsildi."</string>
+</resources>
diff --git a/usbtuner-res/values-az/strings.xml b/usbtuner-res/values-az/strings.xml
deleted file mode 100644
index f5305817..00000000
--- a/usbtuner-res/values-az/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"TV Kökləyici"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB TV Kökləyici"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Aktiv"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Deaktiv"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Lütfən, prosesi başa çatdırmaq üçün gözləyin"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Kanal mənbəyinizi seçin"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Siqnal Yoxdur"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> kanalına sazlamaq mümkün olmadı"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Sazlamaq uğursuz oldu"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Sazlayıcı proqram təminatı yenicə güncəllənib. Kanalları yenidən skan edin."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Audionu aktiv etmək üçün sistem səs ayarlarında əhatəli səsi aktiv edin"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanal kökləyici quraşdırması"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"TV Kökləyici quraşdırması"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB Kanal kökləyici quraşdırması"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"TV-nizin TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB kökləyicinin taxılı olduğunu və TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Davam edin"</item>
- <item msgid="727245208787621142">"İndi yox"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Kanal quraşdırması yenidən işə salınsın?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Bu, TV kökləyici ilə tapılmış kanalları siləcək və yeni kanalları yenidən skan edəcək.\n\nTV-nizin TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"Bu USB kökləyici ilə tapılmış kanalları siləcək və yeni kanalları yenidən skan edəcək.\n\nUSB kökləyicinin taxılı olduğunu və TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Davam edin"</item>
- <item msgid="235450158666155406">"Ləğv edin"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Bağlantı növünü seçin"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Əgər kökləyiciyə xarici antena qoşulubsa Antena seçimini edin. Əgər kanallar kabel xidməti provayderi ilə gəlirsə, onda Kabel seçimini edin. Əgər əmin deyilsinizsə, hər iki növ skan ediləcək, amma bu çox vaxt çəkəcək."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Antena"</item>
- <item msgid="2670079958754180142">"Kabel"</item>
- <item msgid="36774059871728525">"Əmin deyiləm"</item>
- <item msgid="6881204453182153978">"Yalnız inkişaf"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"TV kökləyici quraşdırması"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB Kanal kökləyici quraşdırması"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Bu bir neçə dəqiqə çəkə bilər"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Kökləyici müvəqqəti əlçatan deyil və qeydə alma tərəfindən istifadə olunub."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d kanal tapıldı</item>
- <item quantity="one">%1$d kanal tapıldı</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"KANAL SKANINI DAYANDIRIN"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d kanal tapıldı</item>
- <item quantity="one">%1$d kanal tapıldı</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">Yaxşıdır! Kanal skanı zamanı %1$d kanal tapıldı. Əgər düzgün deyilsə, antenanın yerini dəyişin və yenidən skan edin.</item>
- <item quantity="one">Yaxşıdır! Kanal skanı zamanı %1$d kanal tapıldı. Əgər düzgün deyilsə, antenanın yerini dəyişin və yenidən skan edin.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Hazırdır"</item>
- <item msgid="2480490326672924828">"Yenidən skan edin"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Kanal tapılmadı"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Skan ilə heç bir kanal tapılmadı. TV-nizin TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Skan ilə heç bir kanal tapılmadı. USB kökləyicinin taxılı olduğunu və TV siqnal mənbəyinə qoşulu olduğunu doğrulayın.\n\nHava antenası istifadə etdikdə, daha çox kanal üçün onun yerini və istiqamətini tənzimləməlisiniz. Daha yaxşı nəticələr üçün hündür yerə və pəncərəyə yaxın yerləşdirin."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Yenidən skan edin"</item>
- <item msgid="2092797862490235174">"Hazırdır"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"TV kanalları üçün skan"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV Kökləyici quraşdırması"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV Kökləyici quraşdırması"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV kökləyicisinin bağlantısı kəsildi."</string>
-</resources>
diff --git a/usbtuner-res/values-bg/strings.xml b/usbtuner-res/values-bg/strings.xml
index 0854c09e..996023ff 100644
--- a/usbtuner-res/values-bg/strings.xml
+++ b/usbtuner-res/values-bg/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Телевизионен тунер"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Телевизионен USB тунер"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Включване"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Изключване"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Network TV Tuner (БЕТА)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Моля, изчакайте обработването да завърши"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Изберете източник на канали"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Няма сигнал"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Превключването към „<xliff:g id="CHANNEL_NAME">%s</xliff:g>“ не бе успешно"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Превключването не бе успешно"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Софтуерът на тунера е актуализиран наскоро. Моля, сканирайте отново каналите."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Активирайте обемния звук от настройките за системния, за да включите аудиото"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Звукът не може да се възпроизведе. Моля, опитайте на друг телевизор"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Настройване на тунера за канали"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Настройване на телевизионния тунер"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Настройване на USB тунера за канали"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Настройване на мрежовия тунер"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Уверете се, че телевизорът ви е свързан с източник на телевизионен сигнал.\n\nАко използвате безжична антена, може да се наложи да коригирате разположението или посоката й, за да получите оптимален брой канали. За най-добри резултати я поставете високо и близо до прозорец."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Уверете се, че USB тунерът е включен и свързан с източник на телевизионен сигнал.\n\nАко използвате безжична антена, може да се наложи да коригирате разположението или посоката й, за да получите оптимален брой канали. За най-добри резултати я поставете високо и близо до прозорец."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Уверете се, че мрежовият тунер е включен и свързан с източник на телевизионен сигнал.\n\nАко използвате безжична антена, може да се наложи да коригирате разположението или посоката й, за да уловите най-много канали. За най-добри резултати я поставете високо и близо до прозорец."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Напред"</item>
<item msgid="727245208787621142">"Не сега"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Да се стартира ли отново настройването на каналите?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Така ще премахнете намерените от телевизионния тунер канали и ще сканирате за нови.\n\nУверете се, че телевизорът ви е свързан с източник на телевизионен сигнал.\n\nАко използвате безжична антена, може да се наложи да коригирате разположението или посоката й, за да получите оптимален брой канали. За най-добри резултати я поставете високо и близо до прозорец."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Така ще премахнете намерените от USB тунера канали и ще сканирате за нови.\n\nУверете се, че USB тунерът е включен и свързан с източник на телевизионен сигнал.\n\nАко използвате безжична антена, може да се наложи да коригирате разположението или посоката й, за да получите оптимален брой канали. За най-добри резултати я поставете високо и близо до прозорец."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Така ще премахнете намерените от мрежовия тунер канали и ще сканирате за нови.\n\nУверете се, че мрежовият тунер е включен и свързан с източник на телевизионен сигнал.\n\nАко използвате безжична антена, може да се наложи да коригирате разположението или посоката й, за да уловите най-много канали. За най-добри резултати я поставете високо и близо до прозорец."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Напред"</item>
<item msgid="235450158666155406">"Отказ"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Настройване на телевизионния тунер"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Настройване на USB тунера за канали"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Настройване на мрежовия тунер за канали"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Това може да отнеме няколко минути"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Временно няма достъп до тунера или той вече се използва за запис."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Няма намерени канали"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"При сканирането не бяха открити канали. Уверете се, че телевизорът ви е свързан с източник на телевизионен сигнал.\n\nАко използвате безжична антена, коригирайте разположението или посоката й. За най-добри резултати я поставете високо и близо до прозорец и сканирайте отново."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"При сканирането не бяха открити канали. Уверете се, че USB тунерът е включен и свързан с източник на телевизионен сигнал.\n\nАко използвате безжична антена, коригирайте разположението или посоката й. За най-добри резултати я поставете високо и близо до прозорец и сканирайте отново."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"При сканирането не бяха открити канали. Уверете се, че мрежовият тунер е включен и свързан с източник на телевизионен сигнал.\n\nАко използвате безжична антена, коригирайте разположението или посоката й. За най-добри резултати я поставете високо и близо до прозорец и сканирайте отново."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Повторно сканиране"</item>
<item msgid="2092797862490235174">"Готово"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Сканиране за телевизионни канали"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Настройване на телевизионния тунер"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Настройване на телевизионния USB тунер"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Връзката с телевизионния USB тунер е прекратена."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Сканиране за телевизионни канали"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Настройване на телевизионния тунер"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Настройване на телевизионния USB тунер"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Настройване на Network TV Tuner"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Връзката с телевизионния USB тунер е прекратена."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Връзката с мрежовия тунер е прекратена."</string>
</resources>
diff --git a/usbtuner-res/values-bn-rBD/strings.xml b/usbtuner-res/values-bn-rBD/strings.xml
new file mode 100644
index 00000000..8eb8a558
--- /dev/null
+++ b/usbtuner-res/values-bn-rBD/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"TV টিউনার"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB TV টিউনার"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"নেটওয়ার্ক TV টিউনার (বিটা)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"প্রক্রিয়াকরণ সম্পূর্ণ না হওয়া পর্যন্ত অনুগ্রহ করে অপেক্ষা করুন"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"টিউনার সফ্টওয়্যার সম্প্রতি আপডেট করা হয়েছে৷ অনুগ্রহ করে চ্যানেলগুলি আবার স্ক্যান করুন৷"</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"অডিও সক্ষম করতে সিস্টেম সাউন্ড সেটিংসে সারাউন্ড সাউন্ড সক্ষম করুন"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"অডিও প্লে করা যাবে না৷ অনুগ্রহ করে অন্য টিভি ব্যবহার করার চেষ্ট করুন"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"চ্যানেল টিউনার সেট আপ"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"TV টিউনার সেট আপ"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB চ্যানেল টিউনার সেটআপ"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"নেটওয়ার্ক টিউনার সেট আপ"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"আপনার TV একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে কিনা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে অধিকাংশ চ্যানেল পাওয়ার জন্য আপনাকে সেটির অবস্থান এবং দিক ঠিক করতে হতে পারে৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB টিউনার প্ল্যাগ ইন রয়েছে এবং একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে তা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে অধিকাংশ চ্যানেল পাওয়ার জন্য আপনাকে সেটির অবস্থান এবং দিক ঠিক করতে হতে পারে৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"নেটওয়ার্ক টিউনার চালু রয়েছে এবং কোনো TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে কিনা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে অধিকাংশ চ্যানেল পাওয়ার জন্য আপনাকে সেটির অবস্থান এবং দিক ঠিক করতে হতে পারে৷ আরো ভাল ফলাফলের জন্য, এটিকে উঁচুতে কোনো জানলার সামনে রেখে আবার স্ক্যান করুন৷"</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"চালিয়ে যান"</item>
+ <item msgid="727245208787621142">"এখনই নয়"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"আবার চ্যানেল সেট আপ করবেন?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"এটি TV টিউনার থেকে পাওয়া চ্যানেলগুলিকে মুছবে এবং নতুন চ্যানেলগুলির জন্য আবার স্ক্যান করবে৷\n\nআপনার TV একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে কিনা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে অধিকাংশ চ্যানেল পাওয়ার জন্য আপনাকে সেটির অবস্থান এবং দিক ঠিক করতে হতে পারে৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"এটি USB টিউনার থেকে পাওয়া চ্যানেলগুলিকে মুছবে এবং নতুন চ্যানেলগুলির জন্য আবার স্ক্যান করবে৷\n\nUSB টিউনার প্ল্যাগ ইন রয়েছে এবং একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে তা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে অধিকাংশ চ্যানেল পাওয়ার জন্য আপনাকে সেটির অবস্থান এবং দিক ঠিক করতে হতে পারে৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"এটি নেটওয়ার্ক টিউনার থেকে পাওয়া চ্যানেলগুলি মুছবে এবং নতুন চ্যানেলগুলিকে আবার স্ক্যান করবে৷\n\nনেটওয়ার্ক টিউনার চালু রয়েছে এবং কোনো TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে কিনা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে অধিকাংশ চ্যানেল পাওয়ার জন্য আপনাকে সেটির অবস্থান এবং দিক ঠিক করতে হতে পারে৷ আরো ভাল ফলাফলের জন্য, এটিকে উঁচুতে কোনো জানলার সামনে রেখে আবার স্ক্যান করুন৷"</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"চালিয়ে যান"</item>
+ <item msgid="235450158666155406">"বাতিল করুন"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"সংযোগের প্রকার নির্বাচন করুন"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"যদি আপনার টিউনারের সাথে কোনো বাহ্যিক অ্যান্টেনা সংযুক্ত থাকে তাহলে অ্যান্টেনা বাছুন৷ আপনার চ্যানেলগুলি যদি কোনো কেবল পরিষেবা প্রদানকারীর থেকে আসে তাহলে কেবল বাছুন৷ আপনি যদি নিশ্চিত না হন তাহলে উভয় প্রকারের স্ক্যান করা হবে, কিন্তু এটি অনেক সময় নিতে পারে৷"</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"অ্যান্টেনা"</item>
+ <item msgid="2670079958754180142">"কেবল"</item>
+ <item msgid="36774059871728525">"নিশ্চিত নই"</item>
+ <item msgid="6881204453182153978">"শুধুমাত্র বিকাশের উদ্দেশ্য"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"TV টিউনার সেট আপ"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB চ্যানেল টিউনার সেটআপ"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"নেটওয়ার্ক চ্যানেল টিউনার সেটআপ"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"এটি কয়েক মিনিট সময় নিতে পারে"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"টিউনার অস্থায়ীভাবে অনুপলব্ধ বা রেকডিংয়ে ইতিমধ্যেই ব্যবহৃত হয়েছে৷"</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="one">%1$dটি চ্যানেল পাওয়া গেছে</item>
+ <item quantity="other">%1$dটি চ্যানেল পাওয়া গেছে</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"চ্যানেল স্ক্যান করা থামান"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="one">%1$dটি চ্যানেল পাওয়া গেছে</item>
+ <item quantity="other">%1$dটি চ্যানেল পাওয়া গেছে</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="one">সুন্দর! চ্যানেল স্ক্যান করার সময়ে %1$dটি চ্যানেল পাওয়া গেছে। এটিকে যদি ঠিক বলে না মনে হয়, তাহলে অ্যান্টেনার অবস্থান ঠিক করার চেষ্টা করুন ও আবার স্ক্যান করুন।</item>
+ <item quantity="other">সুন্দর! চ্যানেল স্ক্যান করার সময়ে %1$dটি চ্যানেল পাওয়া গেছে। এটিকে যদি ঠিক বলে না মনে হয়, তাহলে অ্যান্টেনার অবস্থান ঠিক করার চেষ্টা করুন ও আবার স্ক্যান করুন।</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"সম্পন্ন"</item>
+ <item msgid="2480490326672924828">"আবার স্ক্যান করুন"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"কোনো চ্যানেল খুঁজে পাওয়া যায়নি"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"স্ক্যান করে কোনো চ্যানেল খুঁজে পাওয়া যায়নি৷ আপনার TV একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে কিনা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে সেটির অবস্থান এবং দিক ঠিক করুন৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"স্ক্যান করে কোনো চ্যানেল খুঁজে পাওয়া যায়নি৷ USB টিউনার প্ল্যাগ ইন রয়েছে এবং একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে তা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে সেটির অবস্থান এবং দিক ঠিক করুন৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"স্ক্যান করে কোনো চ্যানেল খুঁজে পাওয়া যায়নি৷ নেটওয়ার্ক টিউনার চালু এবং কোনো TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে কিনা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে সেটির অবস্থান এবং দিক ঠিক করুন৷ আরো ভাল ফলাফলের জন্য, এটিকে উঁচুতে কোনো জানলার সামনে রেখে আবার স্ক্যান করুন৷"</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"আবার স্ক্যান করুন"</item>
+ <item msgid="2092797862490235174">"সম্পন্ন"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"টিভি চ্যানেলগুলি স্ক্যান করুন"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV টিউনার সেট আপ"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB টিভি টিউনার সেট আপ"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"নেটওয়ার্ক TV টিউনার সেট আপ"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB টিভি টিউনারের সংযোগ বিচ্ছিন্ন হয়েছে।"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"নেটওয়ার্ক টিউনারের সংযোগ বিচ্ছিন্ন হয়েছে।"</string>
+</resources>
diff --git a/usbtuner-res/values-bn/strings.xml b/usbtuner-res/values-bn/strings.xml
deleted file mode 100644
index 236e2d96..00000000
--- a/usbtuner-res/values-bn/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"TV টিউনার"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB TV টিউনার"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"চালু আছে"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"বন্ধ করুন"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"প্রক্রিয়াকরণ সম্পূর্ণ না হওয়া পর্যন্ত অনুগ্রহ করে অপেক্ষা করুন"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"আপনার চ্যানেলের উৎস নির্বাচন করুন"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"কোনো সংকেত নেই"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> এ টিউন করতে ব্যর্থ হয়েছে"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"টিউন করতে ব্যর্থ হয়েছে"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"টিউনার সফ্টওয়্যার সম্প্রতি আপডেট করা হয়েছে৷ অনুগ্রহ করে চ্যানেলগুলি পুনরায় স্ক্যান করুন৷"</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"অডিও সক্ষম করতে সিস্টেম সাউন্ড সেটিংসে সারাউন্ড সাউন্ড সক্ষম করুন"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"চ্যানেল টিউনার সেট আপ"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"TV টিউনার সেট আপ"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB চ্যানেল টিউনার সেটআপ"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"আপনার TV একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে কিনা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে অধিকাংশ চ্যানেল পাওয়ার জন্য আপনাকে সেটির অবস্থান এবং দিক ঠিক করতে হতে পারে৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB টিউনার প্ল্যাগ ইন রয়েছে এবং একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে তা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে অধিকাংশ চ্যানেল পাওয়ার জন্য আপনাকে সেটির অবস্থান এবং দিক ঠিক করতে হতে পারে৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"চালিয়ে যান"</item>
- <item msgid="727245208787621142">"এখনই নয়"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"পুনরায় চ্যানেল সেট আপ করবেন?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"এটি TV টিউনার থেকে পাওয়া চ্যানেলগুলিকে মুছবে এবং নতুন চ্যানেলগুলির জন্য আবার স্ক্যান করবে৷\n\nআপনার TV একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে কিনা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে অধিকাংশ চ্যানেল পাওয়ার জন্য আপনাকে সেটির অবস্থান এবং দিক ঠিক করতে হতে পারে৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"এটি USB টিউনার থেকে পাওয়া চ্যানেলগুলিকে মুছবে এবং নতুন চ্যানেলগুলির জন্য আবার স্ক্যান করবে৷\n\nUSB টিউনার প্ল্যাগ ইন রয়েছে এবং একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে তা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে অধিকাংশ চ্যানেল পাওয়ার জন্য আপনাকে সেটির অবস্থান এবং দিক ঠিক করতে হতে পারে৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"চালিয়ে যান"</item>
- <item msgid="235450158666155406">"বাতিল করুন"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"সংযোগের প্রকার নির্বাচন করুন"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"যদি আপনার টিউনারের সাথে কোনো বাহ্যিক অ্যান্টেনা সংযুক্ত থাকে তাহলে অ্যান্টেনা বাছুন৷ আপনার চ্যানেলগুলি যদি কোনো কেবল পরিষেবা প্রদানকারীর থেকে আসে তাহলে কেবল বাছুন৷ আপনি যদি নিশ্চিত না হন তাহলে উভয় প্রকারের স্ক্যান করা হবে, কিন্তু এটি অনেক সময় নিতে পারে৷"</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"অ্যান্টেনা"</item>
- <item msgid="2670079958754180142">"কেবল"</item>
- <item msgid="36774059871728525">"নিশ্চিত নই"</item>
- <item msgid="6881204453182153978">"শুধুমাত্র বিকাশের উদ্দেশ্য"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"TV টিউনার সেট আপ"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB চ্যানেল টিউনার সেটআপ"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"এটি কয়েক মিনিট সময় নিতে পারে"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"টিউনার অস্থায়ীভাবে অনুপলব্ধ বা রেকডিংয়ে ইতিমধ্যেই ব্যবহৃত হয়েছে৷"</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="one">%1$dটি চ্যানেল পাওয়া গেছে</item>
- <item quantity="other">%1$dটি চ্যানেল পাওয়া গেছে</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"চ্যানেল স্ক্যান করা থামান"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="one">%1$dটি চ্যানেল পাওয়া গেছে</item>
- <item quantity="other">%1$dটি চ্যানেল পাওয়া গেছে</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="one">সুন্দর! চ্যানেল স্ক্যান করার সময়ে %1$dটি চ্যানেল পাওয়া গেছে। এটিকে যদি ঠিক বলে না মনে হয়, তাহলে অ্যান্টেনার অবস্থান ঠিক করার চেষ্টা করুন ও আবার স্ক্যান করুন।</item>
- <item quantity="other">সুন্দর! চ্যানেল স্ক্যান করার সময়ে %1$dটি চ্যানেল পাওয়া গেছে। এটিকে যদি ঠিক বলে না মনে হয়, তাহলে অ্যান্টেনার অবস্থান ঠিক করার চেষ্টা করুন ও আবার স্ক্যান করুন।</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"সম্পন্ন"</item>
- <item msgid="2480490326672924828">"আবার স্ক্যান করুন"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"কোনো চ্যানেল খুঁজে পাওয়া যায়নি"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"স্ক্যান করে কোনো চ্যানেল খুঁজে পাওয়া যায়নি৷ আপনার TV একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে কিনা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে সেটির অবস্থান এবং দিক ঠিক করুন৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"স্ক্যান করে কোনো চ্যানেল খুঁজে পাওয়া যায়নি৷ USB টিউনার প্ল্যাগ ইন রয়েছে এবং একটি TV সিগন্যাল উৎসের সাথে সংযুক্ত রয়েছে তা যাচাই করুন৷\n\nযদি কোনো ওভার-দ্য-এয়ার অ্যান্টেনা ব্যবহার করা হয় তাহলে সেটির অবস্থান এবং দিক ঠিক করুন৷ আরো ভাল ফলাফলের জন্য, এটিকে উচুঁতে কোনো জানলার সামনে রাখুন এবং আবার স্ক্যান করুন৷"</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"আবার স্ক্যান করুন"</item>
- <item msgid="2092797862490235174">"সম্পন্ন"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"টিভি চ্যানেলগুলি স্ক্যান করুন"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV টিউনার সেট আপ"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB টিভি টিউনার সেট আপ"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB টিভি টিউনারের সংযোগ বিচ্ছিন্ন হয়েছে।"</string>
-</resources>
diff --git a/usbtuner-res/values-ca/strings.xml b/usbtuner-res/values-ca/strings.xml
index af90c3d6..d005204e 100644
--- a/usbtuner-res/values-ca/strings.xml
+++ b/usbtuner-res/values-ca/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Sintonitzador de televisió"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Sintonitzador de televisió USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Activa"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Desactiva"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Sintonitzador de televisió en xarxa (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Espera per finalitzar el processament"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Selecciona la font del canal"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Sense senyal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"No s\'ha pogut sintonitzar <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"No s\'ha pogut sintonitzar"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"El programari del sintonitzador s\'ha actualitzat fa poc. Torna a cercar els canals."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Activa el so envoltant a la configuració de so del sistema per activar l\'àudio"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"No es pot reproduir l\'àudio. Prova-ho amb un altre televisor."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configuració del sintonitzador de canals"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Configuració del sintonitzador de televisió"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Configuració del sintonitzador de canals USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Configuració del sintonitzador en xarxa"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Verifica que el teu televisor estigui connectat a una font de senyal de televisió.\n\nSi fas servir una antena aèria, pot ser que calgui ajustar-ne la ubicació o la direcció per rebre el màxim de canals. Per obtenir els millors resultats, col·loca-la en un lloc elevat i a prop d\'una finestra."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Verifica que el sintonitzador USB estigui endollat i connectat a una font de senyal de televisió.\n\nSi fas servir una antena aèria, pot ser que calgui ajustar-ne la ubicació o la direcció per rebre el màxim de canals. Per obtenir els millors resultats, col·loca-la en un lloc elevat i a prop d\'una finestra."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Comprova que el sintonitzador en xarxa estigui engegat i connectat a una font de senyal de televisió.\n\nSi fas servir una antena aèria, pot ser que calgui ajustar-ne la ubicació o la direcció per rebre el màxim de canals. Per obtenir uns resultats millors, col·loca-la en un lloc elevat i a prop d\'una finestra."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continua"</item>
<item msgid="727245208787621142">"Ara no"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Vols tornar a executar la configuració de canals?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Això farà que se suprimeixin del sintonitzador de televisió els canals que s\'han trobat i que es tornin a cercar canals nous.\n\nVerifica que el teu televisor estigui connectat a una font de senyal de televisió.\n\nSi fas servir una antena aèria, pot ser que calgui ajustar-ne la ubicació o la direcció per rebre el màxim de canals. Per obtenir els millors resultats, col·loca-la en un lloc elevat i a prop d\'una finestra."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Això farà que se suprimeixin del sintonitzador USB els canals que s\'han trobat i que es tornin a cercar canals nous.\n\nVerifica que el sintonitzador USB estigui endollat i connectat a una font de senyal de televisió.\n\nSi fas servir una antena aèria, pot ser que calgui ajustar-ne la ubicació o la direcció per rebre el màxim de canals. Per obtenir els millors resultats, col·loca-la en un lloc elevat i a prop d\'una finestra."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Això farà que se suprimeixin del sintonitzador en xarxa els canals trobats i que se\'n tornin a cercar de nous.\n\nComprova que el sintonitzador en xarxa estigui engegat i connectat a una font de senyal de televisió.\n\nSi fas servir una antena aèria, pot ser que calgui ajustar-ne la ubicació o la direcció per rebre el màxim de canals. Per obtenir uns resultats millors, col·loca-la en un lloc elevat i a prop d\'una finestra."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continua"</item>
<item msgid="235450158666155406">"Cancel·la"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Configuració del sintonitzador de televisió"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Configuració del sintonitzador de canals USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Configuració del sintonitzador de canals en xarxa"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Aquesta acció pot tardar uns quants minuts"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"El sintonitzador no està disponible en aquest moment o bé ja s\'està utilitzant en un enregistrament."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"No s\'ha trobat cap canal"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"No s\'ha trobat cap canal. Verifica que el teu televisor estigui connectat a una font de senyal de televisió.\n\nSi fas servir una antena aèria, ajusta\'n la ubicació o la direcció. Per obtenir els millors resultats, col·loca-la en un lloc elevat i a prop d\'una finestra i torna a cercar canals."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"La cerca no ha trobat cap canal. Verifica que el sintonitzador USB estigui endollat i connectat a una font de senyal de televisió.\n\nSi fas servir una antena aèria, ajusta\'n la ubicació o la direcció. Per obtenir els millors resultats, col·loca-la en un lloc elevat i a prop d\'una finestra i torna a cercar."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"No s\'ha trobat cap canal. Comprova que el sintonitzador en xarxa estigui engegat i connectat a una font de senyal de televisió.\n\nSi fas servir una antena aèria, ajusta\'n la ubicació o la direcció. Per obtenir uns resultats millors, col·loca-la en un lloc elevat i a prop d\'una finestra i torna a cercar."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Torna a cercar"</item>
<item msgid="2092797862490235174">"Fet"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Cerca canals de televisió"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Configuració del sintonitzador de televisió"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Configuració del sintonitzador de televisió USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"El sintonitzador de televisió USB no està connectat."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Cerca canals de televisió"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Configuració del sintonitzador de televisió"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Configuració del sintonitzador de televisió USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Configuració del sintonitzador de televisió en xarxa"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"El sintonitzador de televisió USB no està connectat."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"El sintonitzador de la xarxa no està connectat."</string>
</resources>
diff --git a/usbtuner-res/values-cs/strings.xml b/usbtuner-res/values-cs/strings.xml
index 151083c6..69436042 100644
--- a/usbtuner-res/values-cs/strings.xml
+++ b/usbtuner-res/values-cs/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Televizní tuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Televizní tuner USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Zapnout"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Vypnout"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Síťový televizní tuner (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Vyčkejte prosím, než bude zpracování dokončeno"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Vyberte zdroj kanálu"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Žádný signál"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Kanál <xliff:g id="CHANNEL_NAME">%s</xliff:g> se nepodařilo naladit"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Nelze naladit"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Software tuneru byl nedávno aktualizován. Vyhledejte prosím kanály znovu."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Chcete-li zapnout zvuk, v nastavení systémového zvuku povolte prostorový zvuk"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Zvuk nelze přehrát. Zkuste použít jinou televizi."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Nastavení tuneru kanálů"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Nastavení televizního tuneru"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Nastavení tuneru kanálů USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Nastavení síťového tuneru"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Zkontrolujte, zda je televize připojena ke zdroji televizního signálu.\n\nPokud používáte bezdrátovou anténu, možná budete muset za účelem příjmu co největšího počtu kanálů upravit její umístění nebo nasměrování. Nejlepších výsledků dosáhnete, pokud ji umístíte vysoko a blízko okna."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Zkontrolujte, zda je tuner USB připojen k zařízení a ke zdroji televizního signálu.\n\nPokud používáte bezdrátovou anténu, možná budete muset za účelem příjmu co největšího počtu kanálů upravit její umístění nebo nasměrování. Nejlepších výsledků dosáhnete, pokud ji umístíte vysoko a blízko okna."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Zkontrolujte, zda je síťový tuner zapnut a připojen ke zdroji televizního signálu.\n\nPokud používáte bezdrátovou anténu, možná budete muset za účelem příjmu co největšího počtu kanálů upravit její umístění nebo nasměrování. Nejlepších výsledků dosáhnete, pokud ji umístíte vysoko a blízko okna."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Pokračovat"</item>
<item msgid="727245208787621142">"Teď ne"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Znovu spustit nastavení kanálů?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Tímto odstraníte kanály nalezené pomocí televizního tuneru a znovu vyhledáte nové kanály.\n\nZkontrolujte, zda je televize připojena ke zdroji televizního signálu.\n\nPokud používáte bezdrátovou anténu, možná budete muset za účelem příjmu co největšího počtu kanálů upravit její umístění nebo nasměrování. Nejlepších výsledků dosáhnete, pokud ji umístíte vysoko a blízko okna."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Tímto odstraníte kanály nalezené pomocí tuneru USB a znovu vyhledáte nové kanály.\n\nZkontrolujte, zda je tuner USB připojen k zařízení a ke zdroji televizního signálu.\n\nPokud používáte bezdrátovou anténu, možná budete muset za účelem příjmu co největšího počtu kanálů upravit její umístění nebo nasměrování. Nejlepších výsledků dosáhnete, pokud ji umístíte vysoko a blízko okna."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Tímto odstraníte kanály nalezené pomocí síťového tuneru a znovu vyhledáte nové kanály.\n\nZkontrolujte, zda je síťový tuner zapnut a připojen ke zdroji televizního signálu.\n\nPokud používáte bezdrátovou anténu, možná budete muset za účelem příjmu co největšího počtu kanálů upravit její umístění nebo nasměrování. Nejlepších výsledků dosáhnete, pokud ji umístíte vysoko a blízko okna."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Pokračovat"</item>
<item msgid="235450158666155406">"Zrušit"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Nastavení televizního tuneru"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Nastavení tuneru kanálů USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Nastavení kanálů síťového tuneru"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Tato akce může trvat několik minut."</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuner dočasně není k dispozici, případně je právě používán k nahrávání."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -82,12 +82,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Nebyly nalezeny žádné kanály"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Při vyhledávání nebyly nalezeny žádné kanály. Zkontrolujte, zda je televize připojena ke zdroji televizního signálu.\n\nPokud používáte bezdrátovou anténu, upravte její umístění nebo nasměrování. Nejlepších výsledků dosáhnete, pokud ji umístíte vysoko a blízko okna. Poté spusťte vyhledávání znovu."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Při vyhledávání nebyly nalezeny žádné kanály. Zkontrolujte, zda je tuner USB připojen k zařízení a ke zdroji televizního signálu.\n\nPokud používáte bezdrátovou anténu, upravte její umístění nebo nasměrování. Nejlepších výsledků dosáhnete, pokud ji umístíte vysoko a blízko okna. Poté spusťte vyhledávání znovu."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Při vyhledávání nebyly nalezeny žádné kanály. Zkontrolujte, zda je síťový tuner zapnut a připojen ke zdroji televizního signálu.\n\nPokud používáte bezdrátovou anténu, upravte její umístění nebo nasměrování. Nejlepších výsledků dosáhnete, pokud ji umístíte vysoko a blízko okna. Poté spusťte vyhledávání znovu."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Znovu vyhledat"</item>
<item msgid="2092797862490235174">"Hotovo"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Vyhledejte televizní kanály"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Nastavení televizního tuneru"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Nastavení televizního tuneru USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Televizní tuner USB byl odpojen."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Vyhledejte televizní kanály"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Nastavení televizního tuneru"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Nastavení televizního tuneru USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Nastavení síťového televizního tuneru"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Televizní tuner USB byl odpojen."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Síťový tuner byl odpojen."</string>
</resources>
diff --git a/usbtuner-res/values-da/strings.xml b/usbtuner-res/values-da/strings.xml
index cea5d3c3..96a902b8 100644
--- a/usbtuner-res/values-da/strings.xml
+++ b/usbtuner-res/values-da/strings.xml
@@ -19,27 +19,26 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV Tuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB-tuner til fjernsynet"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Til"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Fra"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Netværkstuner til tv (beta)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Vent, mens behandlingen afsluttes"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Vælg din kanalkilde"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Intet signal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> kunne ikke indlæses"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Indlæsningen lykkedes ikke"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Tunerens software er blevet opdateret for nylig. Scan efter kanalerne igen."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Aktivér surroundsound i systemets lydindstillinger for at aktivere lyd"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Der kan ikke afspilles lyd. Prøv på et andet fjernsyn"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Konfiguration af kanaltuneren"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Konfiguration med TV Tuner"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Konfiguration af USB-kanaltuneren"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Kontrollér, at dit fjernsyn er forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, kan det være nødvendigt at justere dens position eller retning for at modtage flest muligt kanaler. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"Kontrollér, at USB-tuneren er tilsluttet og forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, kan det være nødvendigt at justere dens position eller retning for at modtage flest muligt kanaler. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue."</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Konfiguration af netværkstuner"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Tjek, at dit fjernsyn er forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, kan det være nødvendigt at justere dens position eller retning for at modtage flest muligt kanaler. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"Tjek, at USB-tuneren er tilsluttet og forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, kan det være nødvendigt at justere dens position eller retning for at modtage flest muligt kanaler. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Tjek, at netværkstuneren er tændt og sluttet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, kan det være nødvendigt at justere dens position eller retning for at modtage flest muligt kanaler. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Fortsæt"</item>
<item msgid="727245208787621142">"Ikke nu"</item>
</string-array>
<string name="bt_setup_again_title" msgid="884713873101099572">"Vil du gentage kanalkonfigurationen?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Dette fjerner de kanaler, som blev fundet, fra fjernsynets tuner og scanner efter nye kanaler igen.\n\nKontrollér, at dit fjernsyn er forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, kan det være nødvendigt at justere dens position eller retning for at modtage flest muligt kanaler. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"Denne handling fjerner de kanaler, der blev fundet af USB-tuneren, og starter en ny scanning efter kanaler.\n\nKontrollér, at USB-tuneren er tilsluttet og forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, kan det være nødvendigt at justere dens position eller retning for at modtage flest muligt kanaler. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue."</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Dette fjerner de kanaler, som blev fundet, fra fjernsynets tuner og scanner efter nye kanaler igen.\n\nTjek, at dit fjernsyn er forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, kan det være nødvendigt at justere dens position eller retning for at modtage flest muligt kanaler. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"Denne handling fjerner de kanaler, der blev fundet af USB-tuneren, og starter en ny scanning efter kanaler.\n\nTjek, at USB-tuneren er tilsluttet og forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, kan det være nødvendigt at justere dens position eller retning for at modtage flest muligt kanaler. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Denne handling fjerner de kanaler, der blev fundet af netværkstuneren, og starter en ny kanalsøgning.\n\nTjek, at netværkstuneren er tændt og sluttet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, kan det være nødvendigt at justere dens position eller retning for at modtage flest muligt kanaler. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Fortsæt"</item>
<item msgid="235450158666155406">"Annuller"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Konfiguration med fjernsynets tuner"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Konfiguration af USB-kanaltuneren"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Konfiguration af netværkstuner til kanalsøgning"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Dette kan tage flere minutter"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuneren er midlertidigt utilgængelig eller benyttes allerede til en optagelse."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -74,14 +74,17 @@
<item msgid="2480490326672924828">"Scan igen"</item>
</string-array>
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Der blev ikke fundet nogen kanaler"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Der blev ikke fundet nogen kanaler under scanningen. Kontrollér, at dit fjernsyn er forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, skal du justere dens position eller retning. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue. Scan igen."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Der blev ikke fundet nogen kanaler under scanningen. Kontrollér, at USB-tuneren er tilsluttet og forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, skal du justere dens position eller retning. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue. Scan igen."</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Der blev ikke fundet nogen kanaler under scanningen. Tjek, at dit fjernsyn er forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, skal du justere dens position eller retning. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue. Scan igen."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Der blev ikke fundet nogen kanaler under scanningen. Tjek, at USB-tuneren er tilsluttet og forbundet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, skal du justere dens position eller retning. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue. Scan igen."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Der blev ikke fundet nogen kanaler under søgningen. Tjek, at netværkstuneren er tændt og sluttet til en tv-signalkilde.\n\nHvis du bruger en luftantenne, skal du justere dens position eller retning. Du opnår det bedste resultat ved at placere den højt oppe og i nærheden af et vindue. Søg igen."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Scan igen"</item>
<item msgid="2092797862490235174">"Udført"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Scan efter tv-kanaler"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Konfiguration med TV Tuner"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Konfiguration af USB-TV Tuner"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB-tuneren til fjernsynet af frakoblet."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Søg efter tv-kanaler"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Konfiguration af tuner til fjernsynet"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Konfiguration af USB-tuner til fjernsynet"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Konfiguration af netværkstuner til fjernsynet"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-tuneren til fjernsynet er ikke tilsluttet."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Netværkstuneren er ikke tilsluttet."</string>
</resources>
diff --git a/usbtuner-res/values-de/strings.xml b/usbtuner-res/values-de/strings.xml
index eab5fb1d..b0f17dfc 100644
--- a/usbtuner-res/values-de/strings.xml
+++ b/usbtuner-res/values-de/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV-Tuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB-TV-Tuner"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"An"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Aus"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Netzwerk-TV-Tuner (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Bitte warten Sie, bis die Verarbeitung abgeschlossen ist"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Kanalquelle auswählen"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Kein Signal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"\"<xliff:g id="CHANNEL_NAME">%s</xliff:g>\" konnte nicht eingestellt werden"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Fehler beim Einstellen"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Die Tunersoftware wurde kürzlich aktualisiert. Bitte führen Sie die Kanalsuche noch einmal durch."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Aktivieren Sie in den Systemeinstellungen Surround-Sound, um Audio einschalten zu können"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Audio kann nicht wiedergegeben werden. Bitte versuch es mit einem anderen Fernseher."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanaleinrichtung über den Tuner"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"TV-Tuner einrichten"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Kanaleinrichtung über den USB-Tuner"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Einrichtung des Netzwerk-Tuners"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Vergewissern Sie sich, dass Ihr Fernseher mit einer TV-Signalquelle verbunden ist.\n\nWenn Sie eine terrestrische Antenne verwenden, ändern Sie die Position oder Ausrichtung, um mehr Kanäle zu finden. Die besten Ergebnisse erhalten Sie, wenn Sie sie an eine erhöhte Position in Fensternähe stellen."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Vergewissern Sie sich, dass der USB-Tuner angeschlossen und mit einer TV-Signalquelle verbunden ist.\n\nWenn Sie eine terrestrische Antenne verwenden, ändern Sie die Position oder Ausrichtung, um mehr Kanäle zu finden. Die besten Ergebnisse erhalten Sie, wenn Sie sie an einer erhöhten Position in Fensternähe stellen."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Vergewissere dich, dass der Netzwerk-Tuner eingeschaltet und mit einer TV-Signalquelle verbunden ist.\n\nWenn du eine terrestrische Antenne verwendest, ändere die Position oder Ausrichtung, um mehr Kanäle zu empfangen. Die besten Ergebnisse erhältst du, wenn du die Antenne an eine erhöhte Position in Fensternähe stellst."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Weiter"</item>
<item msgid="727245208787621142">"Jetzt nicht"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Kanaleinrichtung erneut durchführen?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Dies entfernt die vom TV-Tuner gefundenen Kanäle und sucht noch einmal nach neuen Kanälen.\n\nVergewissern Sie sich, dass Ihr Fernseher mit einer TV-Signalquelle verbunden ist.\n\nWenn Sie eine terrestrische Antenne verwenden, ändern Sie die Position oder Ausrichtung, um mehr Kanäle zu finden. Die besten Ergebnisse erhalten Sie, wenn Sie sie an eine erhöhte Position in Fensternähe stellen."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Durch diese Aktion werden die gefundenen Kanäle vom USB-Tuner entfernt und die Kanalsuche wird erneut gestartet.\n\nVergewissern Sie sich, dass der USB-Tuner angeschlossen und mit einer TV-Signalquelle verbunden ist.\n\nWenn Sie eine terrestrische Antenne verwenden, ändern Sie die Position oder Ausrichtung, um mehr Kanäle zu finden. Die besten Ergebnisse erhalten Sie, wenn Sie sie an einer erhöhten Position in Fensternähe stellen."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Durch diese Aktion werden die vom Netzwerk-Tuner gefundenen Kanäle entfernt und die Kanalsuche wird neu gestartet.\n\nVergewissere dich, dass der Netzwerk-Tuner eingeschaltet und mit einer TV-Signalquelle verbunden ist.\n\nWenn du eine terrestrische Antenne verwendest, ändere die Position oder Ausrichtung, um mehr Kanäle zu empfangen. Die besten Ergebnisse erhältst du, wenn du die Antenne an eine erhöhte Position in Fensternähe stellst."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Weiter"</item>
<item msgid="235450158666155406">"Abbrechen"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"TV-Tuner einrichten"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Kanaleinrichtung über den USB-Tuner"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Kanaleinrichtung über den Netzwerk-Tuner"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Dies kann einige Minuten dauern"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Der Tuner ist vorübergehend nicht verfügbar oder wird schon für eine Aufnahme verwendet."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Keine Kanäle gefunden"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Bei der Suche wurden keine Kanäle gefunden. Vergewissern Sie sich, dass Ihr Fernseher mit einer TV-Signalquelle verbunden ist.\n\nWenn Sie eine terrestrische Antenne verwenden, ändern Sie die Position oder Ausrichtung. Um die besten Ergebnisse zu erhalten, stellen Sie sie an eine erhöhte Position in Fensternähe und führen Sie die Suche noch einmal durch."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Bei der Suche wurden keine Kanäle gefunden. Vergewissern Sie sich, dass der USB-Tuner angeschlossen und mit einer TV-Signalquelle verbunden ist.\n\nWenn Sie eine terrestrische Antenne verwenden, ändern Sie die Position oder Ausrichtung. Die besten Ergebnisse erhalten Sie, wenn Sie sie an einer erhöhten Position in Fensternähe stellen. Führen Sie dann die Suche erneut durch."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Bei der Suche wurden keine Kanäle gefunden. Vergewissere dich, dass der Netzwerk-Tuner eingeschaltet und mit einer TV-Signalquelle verbunden ist.\n\nWenn du eine terrestrische Antenne verwendest, ändere die Position oder Ausrichtung. Die besten Ergebnisse erhältst du, wenn du sie an eine erhöhte Position in Fensternähe stellst und die Suche noch einmal durchführst."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Noch einmal suchen"</item>
<item msgid="2092797862490235174">"Fertig"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Nach TV-Kanälen suchen"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV-Tuner einrichten"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB-TV-Tuner einrichten"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Verbindung zum USB-TV-Empfänger wurde aufgehoben."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Nach TV-Kanälen suchen"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Einrichtung des TV-Tuners"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Einrichtung des USB-TV-Tuners"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Einrichtung des Netzwerk-TV-Tuners"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Verbindung zum USB-TV-Tuner wurde aufgehoben."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Verbindung zum Netzwerk-Tuner wurde aufgehoben."</string>
</resources>
diff --git a/usbtuner-res/values-el/strings.xml b/usbtuner-res/values-el/strings.xml
index 6a033e3c..1ea637d4 100644
--- a/usbtuner-res/values-el/strings.xml
+++ b/usbtuner-res/values-el/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Δέκτης τηλεόρασης"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Δέκτης τηλεόρασης USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Ενεργό"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Ανενεργό"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Δέκτης τηλεόρασης δικτύου (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Περιμένετε να ολοκληρωθεί η επεξεργασία"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Επιλέξτε την πηγή του καναλιού σας"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Χωρίς σήμα"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Αποτυχία συντονισμού <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Αποτυχία συντονισμού"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Το λογισμικό δέκτη ενημερώθηκε πρόσφατα. Επαναλάβετε τη σάρωση των καναλιών."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Ενεργοποιήστε τον περιφερειακό ήχο στις ρυθμίσεις ήχου συστήματος για να ενεργοποιήσετε τον ήχο"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Δεν είναι δυνατή η αναπαραγωγή ήχου. Δοκιμάστε μια άλλη τηλεόραση."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Ρύθμιση δέκτη καναλιών"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Ρύθμιση δέκτη τηλεόρασης"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Ρύθμιση δέκτη καναλιών USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Ρύθμιση δέκτη δικτύου"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Βεβαιωθείτε ότι η τηλεόρασή σας είναι συνδεδεμένη σε μια πηγή τηλεοπτικού σήματος.\n\nΕάν χρησιμοποιείτε ασύρματη κεραία, ίσως χρειαστεί να προσαρμόσετε την τοποθέτηση ή την κατεύθυνσή της για να λάβετε περισσότερα κανάλια. Για καλύτερα αποτελέσματα, τοποθετήστε την ψηλά και κοντά σε ένα παράθυρο."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Βεβαιωθείτε ότι ο δέκτης USB είναι συνδεδεμένος στην πρίζα και σε μια πηγή τηλεοπτικού σήματος.\n\nΕάν χρησιμοποιείτε ασύρματη κεραία, ίσως χρειαστεί να προσαρμόσετε την τοποθέτηση ή την κατεύθυνσή της για να λάβετε περισσότερα κανάλια. Για καλύτερα αποτελέσματα, τοποθετήστε την ψηλά και κοντά σε ένα παράθυρο."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Βεβαιωθείτε ότι ο δέκτης του δικτύου είναι ενεργοποιημένος και συνδεδεμένος σε μια πηγή τηλεοπτικού σήματος.\n\nΕάν χρησιμοποιείτε ασύρματη κεραία, ίσως χρειαστεί να προσαρμόσετε την τοποθέτηση ή την κατεύθυνσή της για να λάβετε περισσότερα κανάλια. Για καλύτερα αποτελέσματα, τοποθετήστε την ψηλά και κοντά σε ένα παράθυρο."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Συνέχεια"</item>
<item msgid="727245208787621142">"Όχι τώρα"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Επανάληψη ρύθμισης καναλιών;"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Με αυτόν τον τρόπο θα καταργηθούν τα κανάλια που βρέθηκαν από τον δέκτη τηλεόρασης και θα γίνει ξανά σάρωση για νέα κανάλια.\n\nΒεβαιωθείτε ότι η τηλεόρασή σας είναι συνδεδεμένη σε μια πηγή τηλεοπτικού σήματος.\n\nΕάν χρησιμοποιείτε ασύρματη κεραία, ίσως χρειαστεί να προσαρμόσετε την τοποθέτηση ή την κατεύθυνσή της για να λάβετε περισσότερα κανάλια. Για καλύτερα αποτελέσματα, τοποθετήστε την ψηλά και κοντά σε ένα παράθυρο."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Με αυτόν τον τρόπο θα καταργηθούν τα κανάλια που βρέθηκαν από τον δέκτη USB και θα γίνει ξανά σάρωση για νέα κανάλια.\n\nΒεβαιωθείτε ότι ο δέκτης USB είναι συνδεδεμένος στην πρίζα και σε μια πηγή τηλεοπτικού σήματος.\n\nΕάν χρησιμοποιείτε ασύρματη κεραία, ίσως χρειαστεί να προσαρμόσετε την τοποθέτηση ή την κατεύθυνσή της για να λάβετε περισσότερα κανάλια. Για καλύτερα αποτελέσματα, τοποθετήστε την ψηλά και κοντά σε ένα παράθυρο."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Με αυτόν τον τρόπο, τα κανάλια που βρέθηκαν από τον δέκτη του δικτύου θα καταργηθούν και θα γίνει ξανά σάρωση για νέα κανάλια.\n\nΒεβαιωθείτε ότι ο δέκτης του δικτύου είναι ενεργοποιημένος και συνδεδεμένος σε μια πηγή τηλεοπτικού σήματος.\n\nΕάν χρησιμοποιείτε ασύρματη κεραία, ίσως χρειαστεί να προσαρμόσετε την τοποθέτηση ή την κατεύθυνσή της για να λάβετε περισσότερα κανάλια. Για καλύτερα αποτελέσματα, τοποθετήστε την ψηλά και κοντά σε ένα παράθυρο."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Συνέχεια"</item>
<item msgid="235450158666155406">"Ακύρωση"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Ρύθμιση δέκτη τηλεόρασης"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Ρύθμιση δέκτη καναλιών USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Ρύθμιση δέκτη καναλιών δικτύου"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Αυτό μπορεί να διαρκέσει αρκετά λεπτά"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Ο δέκτης δεν είναι διαθέσιμος προσωρινά ή χρησιμοποιείται ήδη από την εγγραφή."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Δεν βρέθηκαν κανάλια"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Δεν βρέθηκαν κανάλια κατά τη σάρωση. Βεβαιωθείτε ότι η τηλεόρασή σας είναι συνδεδεμένη σε μια πηγή τηλεοπτικού σήματος.\n\nΕάν χρησιμοποιείτε ασύρματη κεραία, προσαρμόστε την τοποθέτηση ή την κατεύθυνσή της. Για καλύτερα αποτελέσματα, τοποθετήστε την ψηλά και κοντά σε ένα παράθυρο και επαναλάβετε τη σάρωση."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Δεν βρέθηκαν κανάλια κατά τη σάρωση. Βεβαιωθείτε ότι ο δέκτης USB είναι συνδεδεμένος στην πρίζα και σε μια πηγή τηλεοπτικού σήματος.\n\nΕάν χρησιμοποιείτε ασύρματη κεραία, προσαρμόστε την τοποθέτηση ή την κατεύθυνσή της. Για καλύτερα αποτελέσματα, τοποθετήστε την ψηλά και κοντά σε ένα παράθυρο και επαναλάβετε τη σάρωση."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Δεν εντοπίστηκε κανένα κανάλι κατά τη σάρωση. Βεβαιωθείτε ότι ο δέκτης του δικτύου είναι ενεργοποιημένος και συνδεδεμένος σε μια πηγή τηλεοπτικού σήματος.\n\nΕάν χρησιμοποιείτε ασύρματη κεραία, προσαρμόστε την τοποθέτηση ή την κατεύθυνσή της. Για καλύτερα αποτελέσματα, τοποθετήστε την ψηλά και κοντά σε κάποιο παράθυρο και επαναλάβετε τη σάρωση."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Εκ νέου σάρωση"</item>
<item msgid="2092797862490235174">"Ολοκληρώθηκε"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Σάρωση για τηλεοπτικά κανάλια"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Ρύθμιση δέκτη τηλεόρασης"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Ρύθμιση δέκτη τηλεόρασης USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Ο δέκτης τηλεόρασης USB έχει αποσυνδεθεί."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Σάρωση για τηλεοπτικά κανάλια"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Ρύθμιση δέκτη τηλεόρασης"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Ρύθμιση δέκτη τηλεόρασης USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Ρύθμιση δέκτη τηλεόρασης δικτύου"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Ο δέκτης τηλεόρασης USB έχει αποσυνδεθεί."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Ο δέκτης δικτύου έχει αποσυνδεθεί."</string>
</resources>
diff --git a/usbtuner-res/values-en-rAU/strings.xml b/usbtuner-res/values-en-rAU/strings.xml
index 11e639fd..dccba99e 100644
--- a/usbtuner-res/values-en-rAU/strings.xml
+++ b/usbtuner-res/values-en-rAU/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV Tuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB TV Tuner"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"On"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Off"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Network TV Tuner (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Please wait to finish processing"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Select your channel source"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"No Signal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Failed to tune to <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Failed to tune"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Tuner software has been recently updated. Please re-scan the channels."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"To enable audio, enable surround sound in system sound settings"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Cannot play audio. Please try another TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Channel tuner setup"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"TV Tuner setup"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB channel tuner setup"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Network Tuner Setup"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Check that your TV is connected to a TV signal source.\n\nIf using an over-the-air aerial, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Check that the USB tuner is plugged in and connected to a TV signal source.\n\nIf using an over-the-air aerial, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Verify the network tuner is powered on and connected to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continue"</item>
<item msgid="727245208787621142">"Not now"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Re-run channel setup?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"This will remove the channels found from the TV tuner and scan for new channels again.\n\nCheck that your TV is connected to a TV signal source.\n\nIf using an over-the-air aerial, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"This will remove the channels found from the USB tuner and scan for new channels again.\n\nCheck that the USB tuner is plugged in and connected to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"This will remove the channels found from the network tuner and scan for new channels again.\n\nVerify the network tuner is powered on and connected to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continue"</item>
<item msgid="235450158666155406">"Cancel"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"TV tuner setup"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB channel tuner setup"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Network channel tuner setup"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"This may take several minutes"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuner is temporarily unavailable or already used by recording."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"No channels found"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"The scan did not find any channels. Check that your TV is connected to a TV signal source.\n\nIf using an over-the-air aerial, adjust its placement or direction. For best results, place it high and near a window and scan again."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"The scan did not find any channels. Check that the USB tuner is plugged in and connected to a TV signal source.\n\nIf using an over-the-air aerial, adjust its placement or direction. For best results, place it high and near a window and scan again."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"The scan did not find any channels. Verify the network tuner is powered on and connected to a TV signal source.\n\nIf using an over-the-air antenna, adjust its placement or direction. For best results, place it high and near a window and scan again."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Scan again"</item>
<item msgid="2092797862490235174">"Finished"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Scan for TV channels"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV Tuner setup"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV Tuner setup"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV tuner disconnected."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Scan for TV channels"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV Tuner setup"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV Tuner setup"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Network TV Tuner setup"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV tuner disconnected."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Network tuner disconnected."</string>
</resources>
diff --git a/usbtuner-res/values-en-rGB/strings.xml b/usbtuner-res/values-en-rGB/strings.xml
index 11e639fd..dccba99e 100644
--- a/usbtuner-res/values-en-rGB/strings.xml
+++ b/usbtuner-res/values-en-rGB/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV Tuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB TV Tuner"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"On"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Off"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Network TV Tuner (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Please wait to finish processing"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Select your channel source"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"No Signal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Failed to tune to <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Failed to tune"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Tuner software has been recently updated. Please re-scan the channels."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"To enable audio, enable surround sound in system sound settings"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Cannot play audio. Please try another TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Channel tuner setup"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"TV Tuner setup"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB channel tuner setup"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Network Tuner Setup"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Check that your TV is connected to a TV signal source.\n\nIf using an over-the-air aerial, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Check that the USB tuner is plugged in and connected to a TV signal source.\n\nIf using an over-the-air aerial, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Verify the network tuner is powered on and connected to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continue"</item>
<item msgid="727245208787621142">"Not now"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Re-run channel setup?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"This will remove the channels found from the TV tuner and scan for new channels again.\n\nCheck that your TV is connected to a TV signal source.\n\nIf using an over-the-air aerial, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"This will remove the channels found from the USB tuner and scan for new channels again.\n\nCheck that the USB tuner is plugged in and connected to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"This will remove the channels found from the network tuner and scan for new channels again.\n\nVerify the network tuner is powered on and connected to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continue"</item>
<item msgid="235450158666155406">"Cancel"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"TV tuner setup"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB channel tuner setup"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Network channel tuner setup"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"This may take several minutes"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuner is temporarily unavailable or already used by recording."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"No channels found"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"The scan did not find any channels. Check that your TV is connected to a TV signal source.\n\nIf using an over-the-air aerial, adjust its placement or direction. For best results, place it high and near a window and scan again."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"The scan did not find any channels. Check that the USB tuner is plugged in and connected to a TV signal source.\n\nIf using an over-the-air aerial, adjust its placement or direction. For best results, place it high and near a window and scan again."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"The scan did not find any channels. Verify the network tuner is powered on and connected to a TV signal source.\n\nIf using an over-the-air antenna, adjust its placement or direction. For best results, place it high and near a window and scan again."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Scan again"</item>
<item msgid="2092797862490235174">"Finished"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Scan for TV channels"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV Tuner setup"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV Tuner setup"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV tuner disconnected."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Scan for TV channels"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV Tuner setup"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV Tuner setup"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Network TV Tuner setup"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV tuner disconnected."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Network tuner disconnected."</string>
</resources>
diff --git a/usbtuner-res/values-en-rIN/strings.xml b/usbtuner-res/values-en-rIN/strings.xml
index 11e639fd..dccba99e 100644
--- a/usbtuner-res/values-en-rIN/strings.xml
+++ b/usbtuner-res/values-en-rIN/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV Tuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB TV Tuner"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"On"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Off"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Network TV Tuner (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Please wait to finish processing"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Select your channel source"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"No Signal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Failed to tune to <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Failed to tune"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Tuner software has been recently updated. Please re-scan the channels."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"To enable audio, enable surround sound in system sound settings"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Cannot play audio. Please try another TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Channel tuner setup"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"TV Tuner setup"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB channel tuner setup"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Network Tuner Setup"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Check that your TV is connected to a TV signal source.\n\nIf using an over-the-air aerial, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Check that the USB tuner is plugged in and connected to a TV signal source.\n\nIf using an over-the-air aerial, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Verify the network tuner is powered on and connected to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continue"</item>
<item msgid="727245208787621142">"Not now"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Re-run channel setup?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"This will remove the channels found from the TV tuner and scan for new channels again.\n\nCheck that your TV is connected to a TV signal source.\n\nIf using an over-the-air aerial, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"This will remove the channels found from the USB tuner and scan for new channels again.\n\nCheck that the USB tuner is plugged in and connected to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"This will remove the channels found from the network tuner and scan for new channels again.\n\nVerify the network tuner is powered on and connected to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its placement or direction to receive the most channels. For best results, place it high and near a window."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continue"</item>
<item msgid="235450158666155406">"Cancel"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"TV tuner setup"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB channel tuner setup"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Network channel tuner setup"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"This may take several minutes"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuner is temporarily unavailable or already used by recording."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"No channels found"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"The scan did not find any channels. Check that your TV is connected to a TV signal source.\n\nIf using an over-the-air aerial, adjust its placement or direction. For best results, place it high and near a window and scan again."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"The scan did not find any channels. Check that the USB tuner is plugged in and connected to a TV signal source.\n\nIf using an over-the-air aerial, adjust its placement or direction. For best results, place it high and near a window and scan again."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"The scan did not find any channels. Verify the network tuner is powered on and connected to a TV signal source.\n\nIf using an over-the-air antenna, adjust its placement or direction. For best results, place it high and near a window and scan again."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Scan again"</item>
<item msgid="2092797862490235174">"Finished"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Scan for TV channels"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV Tuner setup"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV Tuner setup"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV tuner disconnected."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Scan for TV channels"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV Tuner setup"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV Tuner setup"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Network TV Tuner setup"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV tuner disconnected."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Network tuner disconnected."</string>
</resources>
diff --git a/usbtuner-res/values-es-rUS/strings.xml b/usbtuner-res/values-es-rUS/strings.xml
index da7ec699..cca69f4e 100644
--- a/usbtuner-res/values-es-rUS/strings.xml
+++ b/usbtuner-res/values-es-rUS/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Sintonizador de TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Sintonizador de TV USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Activar"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Desactivar"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Sintonizador de TV de red (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Espera a que finalice el procesamiento"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Seleccionar la fuente del canal"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Sin señal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"No se pudo sintonizar el canal <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"No se pudo sintonizar el canal"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"El software del sintonizador se actualizó recientemente. Vuelve a buscar los canales."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Para habilitar el audio, deberás activar el sonido envolvente en la configuración del sistema de sonido"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"No se puede reproducir el audio. Intenta usar otra TV."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configuración del sintonizador de canales"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Configuración del sintonizador de TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Configuración del sintonizador de canales USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Configuración del sintonizador de red"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Verifica que tu TV esté conectada a una fuente de señal de TV.\n\nSi usas una antena inalámbrica, es posible que tengas que ajustar su posición o dirección para recibir la mayor cantidad de canales posible. Para obtener mejores resultados, ubica la antena en un lugar alto y cerca de una ventana."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Verifica que el sintonizador USB esté enchufado y conectado a una fuente de señal de TV.\n\nSi usas una antena inalámbrica, es posible que necesites ajustar su ubicación y dirección para recibir la mayor cantidad de canales. Para obtener mejores resultados, ubica la antena en un lugar alto y cerca de una ventana."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Comprueba que el sintonizador de red esté encendido y conectado a una fuente de señal de TV.\n\nSi estás usando una antena inalámbrica, es posible que debas ajustar su ubicación o dirección para recibir la mayoría de los canales. Si deseas obtener mejores resultados, colócala en un lugar alto y cerca de una ventana."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continuar"</item>
<item msgid="727245208787621142">"Ahora no"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"¿Quieres volver a configurar los canales?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Esta acción quitará los canales encontrados desde el sintonizador de TV y se volverán a buscar canales nuevos.\n\nVerifica que tu TV esté conectada a una fuente de señal de TV.\n\nSi usas una antena inalámbrica, es posible que tengas que ajustar su posición o dirección para recibir la mayor cantidad de canales posible. Para obtener mejores resultados, ubica la antena en un lugar alto y cerca de una ventana."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Esta acción quitará los canales encontrados desde el sintonizador de TV y se volverán a buscar canales nuevos.\n\nVerifica que el sintonizador USB esté enchufado y conectado a una fuente de señal de TV.\n\nSi usas una antena inalámbrica, es posible que necesites ajustar su ubicación y dirección para recibir la mayor cantidad de canales. Para obtener mejores resultados, ubica la antena en un lugar alto y cerca de una ventana."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"De esta manera, se quitarán los canales encontrados desde el sintonizador de red y se buscarán canales nuevos.\n\nComprueba que el sintonizador de red esté encendido y conectado a una fuente de señal de TV.\n\nSi estás usando una antena inalámbrica, es posible que debas ajustar su ubicación o dirección para recibir la mayor cantidad de canales. Para obtener mejores resultados, colócala en un lugar alto y cerca de una ventana."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continuar"</item>
<item msgid="235450158666155406">"Cancelar"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Configuración del sintonizador de TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Configuración del sintonizador de canales USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Configuración del sintonizador de canales de red"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Este proceso podría demorar varios minutos"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"El sintonizador no está disponible en este momento o está grabando."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"No se encontraron canales"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"No se encontró ningún canal. Verifica que tu TV esté conectada a una fuente de señal de TV.\n\nSi usas una antena inalámbrica, ajusta su posición o dirección. Para obtener mejores resultados, ubícala en un lugar alto y cerca de una ventana. Luego, vuelve a hacer la búsqueda."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"No se encontraron canales en la búsqueda. Verifica que el sintonizador USB esté enchufado y conectado a una fuente de señal de TV.\n\nSi usas una antena inalámbrica, ajusta su ubicación o dirección. Para obtener mejores resultados, ubícala en un lugar alto y cerca de una ventana. Luego, vuelve a hacer la búsqueda."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"No se encontró ningún canal durante la búsqueda. Comprueba que el sintonizador de red esté encendido y conectado a una fuente de señal de TV.\n\nSi estás usando una antena inalámbrica, ajusta su ubicación o dirección. Para obtener mejores resultados, colócala en un lugar alto y cerca de una ventana, y repite la búsqueda."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Volver a buscar"</item>
<item msgid="2092797862490235174">"Listo"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Busca canales de TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Configuración del sintonizador de TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Configuración del sintonizador de TV USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Se desconectó el sintonizador de TV USB."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Busca canales de TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Configuración del sintonizador de TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Configuración del sintonizador de TV USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Configuración del sintonizador de TV de red"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Se desconectó el sintonizador de TV USB."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Se desconectó el sintonizador de red."</string>
</resources>
diff --git a/usbtuner-res/values-es/strings.xml b/usbtuner-res/values-es/strings.xml
index e8e34cb2..26742e65 100644
--- a/usbtuner-res/values-es/strings.xml
+++ b/usbtuner-res/values-es/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Sintonizador de canales"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Sintonizador de canales USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Activar"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Desactivar"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Sintonizador de TV en red (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Espera hasta que finalice el procesamiento"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Selecciona la fuente de canales"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Sin señal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"No se ha podido sintonizar <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"No se podido sintonizar"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"El software del sintonizador se ha actualizado recientemente. Vuelve a buscar los canales."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Habilita el sonido envolvente en los ajustes del sistema de sonido para activar el audio"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"No se puede reproducir el audio. Prueba con otra TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configuración del sintonizador de canales"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Configuración del sintonizador de canales"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Configuración del sintonizador de canales USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Configuración del sintonizador en red"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Comprueba que la TV esté conectada a una fuente de señal de TV.\n\n Si utilizas una antena inalámbrica, puede que tengas que cambiar su posición o dirección para recibir la mayor cantidad posible de canales. Para conseguir los mejores resultados, colócala en alto y cerca de una ventana."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"Comprueba que el sintonizador USB esté enchufado y conectado a una fuente de señal de TV.\n\nSi utilizas una antena inalámbrica, puede que tengas que cambiar su ubicación o dirección para recibir la mayor cantidad posible de canales. Para conseguir los mejores resultados, colócala en alto y cerca de una ventana."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"Comprueba que el sintonizador USB esté enchufado y conectado a una fuente de señal de TV.\n\nSi utilizas una antena inalámbrica, puede que tengas que cambiar su emplazamiento o dirección para recibir la mayor cantidad posible de canales. Para conseguir los mejores resultados, colócala en alto y cerca de una ventana."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Comprueba que el sintonizador en red esté encendido y conectado a una fuente de señal de TV.\n\nSi utilizas una antena inalámbrica, es posible que tengas que cambiar su emplazamiento o su orientación para ver la mayoría de los canales. Para obtener los mejores resultados, colócala en un lugar alto cerca de una ventana."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continuar"</item>
<item msgid="727245208787621142">"Ahora no"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"¿Quieres volver a ejecutar la configuración de canales?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Se quitarán los canales encontrados del sintonizador de canales y se volverán a buscar nuevos canales.\n\nComprueba que la TV esté conectada a una fuente de señal de TV.\n\nSi utilizas una antena inalámbrica, puede que tengas que cambiar su posición o dirección para recibir la mayor cantidad posible de canales. Para conseguir los mejores resultados, colócala en alto y cerca de una ventana."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Se quitarán los canales encontrados con el sintonizador USB y se volverán a buscar nuevos canales.\n\nComprueba que el sintonizador USB esté enchufado y conectado a una fuente de señal de TV.\n\nSi utilizas una antena inalámbrica, puede que tengas que cambiar su ubicación o dirección para recibir la mayor cantidad posible de canales. Para conseguir los mejores resultados, colócala en alto y cerca de una ventana."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Se quitarán los canales encontrados del sintonizador en red y se repetirá la búsqueda de canales.\n\nComprueba que el sintonizador en red esté encendido y conectado a una fuente de señal de TV.\n\nSi utilizas una antena inalámbrica, es posible que tengas que cambiar su emplazamiento o su orientación para ver la mayoría de los canales. Para obtener los mejores resultados, colócala en un lugar alto cerca de una ventana."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continuar"</item>
<item msgid="235450158666155406">"Cancelar"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Configuración del sintonizador de canales"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Configuración del sintonizador de canales USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Configuración del sintonizador de canales en red"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Este proceso puede tardar varios minutos"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"El sintonizador no está disponible temporalmente o se está utilizando en otra grabación."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -75,13 +75,16 @@
</string-array>
<string name="ut_result_not_found_title" msgid="4649533929056795595">"No se han encontrado canales"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"No se ha encontrado ningún canal. Comprueba que la TV esté conectada a una fuente de señal de TV.\n\nSi utilizas una antena inalámbrica, cambia su posición o dirección. Para conseguir los mejores resultados, colócala en alto y cerca de una ventana. A continuación, vuelve a realizar la búsqueda."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"No se ha encontrado ningún canal. Comprueba que el sintonizador USB esté enchufado y conectado a una fuente de señal de TV.\n\nSi utilizas una antena inalámbrica, cambia su ubicación o dirección. Para conseguir los mejores resultados, colócala en alto y cerca de una ventana. A continuación, vuelve a realizar la búsqueda."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"No se ha encontrado ningún canal. Comprueba que el sintonizador USB esté enchufado y conectado a una fuente de señal de TV.\n\nSi utilizas una antena inalámbrica, cambia su emplazamiento o dirección. Para conseguir los mejores resultados, colócala en alto y cerca de una ventana. A continuación, vuelve a realizar la búsqueda."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"El análisis no ha encontrado ningún canal. Comprueba que el sintonizador en red esté encendido y conectado a una fuente de señal de TV.\n\nSi utilizas una antena inalámbrica, cambia su emplazamiento u orientación. Para obtener los mejores resultados, colócala en un lugar alto cerca de una ventana y repite el análisis."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Volver a buscar"</item>
<item msgid="2092797862490235174">"Listo"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Busca canales de TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Configuración del sintonizador de canales"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Configuración de sintonizador de canales USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Sintonizador de canales USB desconectado."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Buscar canales de TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Configuración del sintonizador de TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Configuración de sintonizador de TV USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Configuración del sintonizador de TV en red"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"El sintonizador de canales USB está desconectado."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"El sintonizador en red está desconectado."</string>
</resources>
diff --git a/usbtuner-res/values-et-rEE/strings.xml b/usbtuner-res/values-et-rEE/strings.xml
new file mode 100644
index 00000000..3d97a31a
--- /dev/null
+++ b/usbtuner-res/values-et-rEE/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"Telerituuner"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB-telerituuner"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Teleri võrgutuuner (BEETA)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Oodake, kuni töötlemine on lõppenud"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Tuuneri tarkvara värskendati hiljuti. Otsige kanaleid uuesti."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Heli lubamiseks lubage ruumiline heli süsteemi heliseadetes"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Heli ei saa esitada. Proovige teist telerit"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanalituuneri seadistus"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"Telerituuneri seadistus"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB-kanalituuneri seadistus"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Võrgutuuneri seadistus"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Veenduge, et teler oleks ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, peate võimalikult paljude kanalite nägemiseks võib-olla kohandama selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"Veenduge, et USB-tuuner oleks pistikus ja ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, peate enamiku kanalite nägemiseks võib-olla kohandama selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Veenduge, et võrgutuuner oleks sisse lülitatud ja teleri signaaliallikaga ühendatud.\n\nKui kasutate õhuantenni, peate võib-olla muutma selle asendit või suunda, et rohkem kanaleid leida. Parimate tulemuste saavutamiseks asetage see kõrgesse kohta akna lähedale."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Jätka"</item>
+ <item msgid="727245208787621142">"Mitte praegu"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Kas käitada kanali seadistust uuesti?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"See eemaldab telerituuneri leitud kanalid ja otsib uuesti uusi kanaleid.\n\nVeenduge, et teler oleks ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, peate võimalikult paljude kanalite nägemiseks võib-olla kohandama selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"See eemaldab USB-tuuneri leitud kanalid ja otsib uuesti uusi kanaleid.\n\nVeenduge, et USB-tuuner oleks pistikus ja ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, peate enamiku kanalite nägemiseks võib-olla kohandama selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"See eemaldab võrgutuunerist leitud kanalid ja skannib uuesti uusi kanaleid.\n\nVeenduge, et võrgutuuner oleks sisse lülitatud ja teleri signaaliallikaga ühendatud.\n\nKui kasutate õhuantenni, peate võib-olla muutma selle asendit või suunda, et rohkem kanaleid leida. Parimate tulemuste saavutamiseks asetage see kõrgesse kohta akna lähedale."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Jätka"</item>
+ <item msgid="235450158666155406">"Tühista"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Valige ühenduse tüüp"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Kui tuuneriga on ühendatud väline antenn, tehke valik Antenn. Kui kanaleid pakub kaabelteenuse pakkuja, tehke valik Kaabel. Kui te pole kindel, otsitakse mõlemat tüüpi, kuid see võib kauem aega võtta."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Antenn"</item>
+ <item msgid="2670079958754180142">"Kaabel"</item>
+ <item msgid="36774059871728525">"Ei ole kindel"</item>
+ <item msgid="6881204453182153978">"Ainult arenduseks"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"Telerituuneri seadistus"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB-kanalituuneri seadistus"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Võrgutuuneri kanalite seadistus"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"See võib võtta mitu minutit"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuuner pole ajutiselt saadaval või seda kasutatakse juba salvestamiseks."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">Leiti %1$d kanalit</item>
+ <item quantity="one">Leiti %1$d kanal</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"PEATA KANALITE OTSIMINE"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">Leiti %1$d kanalit</item>
+ <item quantity="one">Leiti %1$d kanal</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">Hästi! Kanalite otsimisel leiti %1$d kanalit. Kui see ei tundu õige, kohandage antenni asendit ja otsige uuesti.</item>
+ <item quantity="one">Hästi! Kanalite otsimisel leiti %1$d kanal. Kui see ei tundu õige, kohandage antenni asendit ja otsige uuesti.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Valmis"</item>
+ <item msgid="2480490326672924828">"Otsi uuesti"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Ühtegi kanalit ei leitud"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Otsimisel ei leitud ühtegi kanalit. Veenduge, et teler oleks ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, kohandage selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale ning otsige uuesti."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Otsimisel ei leitud ühtegi kanalit. Veenduge, et USB-tuuner oleks pistikus ja ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, kohandage selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale ning otsige uuesti."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Skannimisel ei leitud ühtegi kanalit. Veenduge, et võrgutuuner oleks sisse lülitatud ja teleri signaaliallikaga ühendatud.\n\nKui kasutate õhuantenni, muutke selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgesse kohta akna lähedale ja skannige uuesti."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Otsi uuesti"</item>
+ <item msgid="2092797862490235174">"Valmis"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Telekanalite otsimine"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Telerituuneri seadistus"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB-telerituuneri seadistus"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Teleri võrgutuuneri seadistus"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-telerituuner eemaldati."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Võrgutuuner eemaldati."</string>
+</resources>
diff --git a/usbtuner-res/values-et/strings.xml b/usbtuner-res/values-et/strings.xml
deleted file mode 100644
index 70cb238a..00000000
--- a/usbtuner-res/values-et/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"Telerituuner"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB-telerituuner"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Sees"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Väljas"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Oodake, kuni töötlemine on lõppenud"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Valige kanali allikas"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Pole signaali"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Kanalile <xliff:g id="CHANNEL_NAME">%s</xliff:g> häälestamine ebaõnnestus"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Häälestamine ebaõnnestus"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Tuuneri tarkvara värskendati hiljuti. Otsige kanaleid uuesti."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Heli lubamiseks lubage ruumiline heli süsteemi heliseadetes"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanalituuneri seadistus"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"Telerituuneri seadistus"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB-kanalituuneri seadistus"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Veenduge, et teler oleks ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, peate võimalikult paljude kanalite nägemiseks võib-olla kohandama selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"Veenduge, et USB-tuuner oleks pistikus ja ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, peate enamiku kanalite nägemiseks võib-olla kohandama selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Jätka"</item>
- <item msgid="727245208787621142">"Mitte praegu"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Kas käitada kanali seadistust uuesti?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"See eemaldab telerituuneri leitud kanalid ja otsib uuesti uusi kanaleid.\n\nVeenduge, et teler oleks ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, peate võimalikult paljude kanalite nägemiseks võib-olla kohandama selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"See eemaldab USB-tuuneri leitud kanalid ja otsib uuesti uusi kanaleid.\n\nVeenduge, et USB-tuuner oleks pistikus ja ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, peate enamiku kanalite nägemiseks võib-olla kohandama selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Jätka"</item>
- <item msgid="235450158666155406">"Tühista"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Valige ühenduse tüüp"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Kui tuuneriga on ühendatud väline antenn, tehke valik Antenn. Kui kanaleid pakub kaabelteenuse pakkuja, tehke valik Kaabel. Kui te pole kindel, otsitakse mõlemat tüüpi, kuid see võib kauem aega võtta."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Antenn"</item>
- <item msgid="2670079958754180142">"Kaabel"</item>
- <item msgid="36774059871728525">"Ei ole kindel"</item>
- <item msgid="6881204453182153978">"Ainult arenduseks"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"Telerituuneri seadistus"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB-kanalituuneri seadistus"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"See võib võtta mitu minutit"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuuner pole ajutiselt saadaval või seda kasutatakse juba salvestamiseks."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">Leiti %1$d kanalit</item>
- <item quantity="one">Leiti %1$d kanal</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"PEATA KANALITE OTSIMINE"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">Leiti %1$d kanalit</item>
- <item quantity="one">Leiti %1$d kanal</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">Hästi! Kanalite otsimisel leiti %1$d kanalit. Kui see ei tundu õige, kohandage antenni asendit ja otsige uuesti.</item>
- <item quantity="one">Hästi! Kanalite otsimisel leiti %1$d kanal. Kui see ei tundu õige, kohandage antenni asendit ja otsige uuesti.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Valmis"</item>
- <item msgid="2480490326672924828">"Otsi uuesti"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Ühtegi kanalit ei leitud"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Otsimisel ei leitud ühtegi kanalit. Veenduge, et teler oleks ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, kohandage selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale ning otsige uuesti."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Otsimisel ei leitud ühtegi kanalit. Veenduge, et USB-tuuner oleks pistikus ja ühendatud teleri signaaliallikaga.\n\nKui kasutate õhuantenni, kohandage selle asendit või suunda. Parimate tulemuste saavutamiseks asetage see kõrgele ja akna lähedale ning otsige uuesti."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Otsi uuesti"</item>
- <item msgid="2092797862490235174">"Valmis"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Otsige telekanaleid"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Telerituuneri seadistus"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB-telerituuneri seadistus"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB-telerituuner eemaldati."</string>
-</resources>
diff --git a/usbtuner-res/values-eu-rES/strings.xml b/usbtuner-res/values-eu-rES/strings.xml
new file mode 100644
index 00000000..0f7ac943
--- /dev/null
+++ b/usbtuner-res/values-eu-rES/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"Sintonizadorea"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB bidezko sintonizadorea"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Sareko sintonizadorea (BETA)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Itxaron prozesatzen amaitu arte"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Sintonizadorearen softwarea berriki eguneratu da. Bilatu kanalak berriro."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Audioa gaitzeko, joan sistemaren soinuaren ezarpenetara eta gaitu soinu inguratzailea"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Ezin da erreproduzitu audioa. Saiatu beste telebista batean."</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanal-sintonizadorearen konfigurazioa"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"Sintonizadorearen konfigurazioa"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB kanal-sintonizadorearen konfigurazioa"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Sareko sintonizadorearen konfigurazioa"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Egiaztatu telebista-seinalearen iturburu batera konektatuta dagoela telebista.\n\nAntena analogiko bat badarabilzu, agian bere kokapena edo norabidea doitu beharko dituzu kanal gehienak eskuratzeko. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"Egiaztatu USB sintonizadorea entxufatuta eta telebistako seinale-iturburu batera konektatuta dagoela.\n\nHari gabeko antena badarabilzu, doitu bere kokapena edo norabidea. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan eta gauzatu bilaketa berriro."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Egiaztatu sintonizadorea piztuta dagoela eta telebista-seinalea igortzen duen iturburu batera konektatu duzula.\n\nHari-gabeko antena bat erabiltzen ari bazara, doi ezazu haren kokapena edo norabidea ahal bezain beste kanal aurkitzeko. Emaitzarik onenak lortzeko, ezar ezazu ahal bezain altu eta leiho batetik gertu."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Jarraitu"</item>
+ <item msgid="727245208787621142">"Orain ez"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Berriro konfiguratu nahi dituzu kanalak?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Sintonizadoreak aurkitutako kanalak kenduko dira eta berriro bilatuko dira kanalak.\n\nEgiaztatu telebista-seinalearen iturburu batera konektatuta dagoela telebista.\n\nAntena analogiko bat badarabilzu, agian bere kokapena edo norabidea doitu beharko dituzu kanal gehienak eskuratzeko. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"USB sintonizadoreak aurkitutako kanalak kenduko dira eta berriro bilatuko dira kanalak.\n\nEgiaztatu USB sintonizadorea entxufatuta eta telebistako seinale-iturburu batera konektatuta dagoela.\n\nAntena analogiko bat badarabilzu, agian bere kokapena edo norabidea doitu beharko dituzu kanal gehienak eskuratzeko. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Hori eginez gero, kendu egingo dira sareko sintonizadoreak aurkitutako kanalak eta zerotik hasiko da berriro kanalak bilatzen.\n\n Egiaztatu sintonizadorea piztuta dagoela eta telebista-seinalea igortzen duen iturburu batera konektatu duzula.\n\nHari-gabeko antena bat erabiltzen ari bazara, doi ezazu haren kokapena edo norabidea ahal bezain beste kanal aurkitzeko. Emaitzarik onenak lortzeko, ezar ezazu ahal bezain altu eta leiho batetik gertu."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Jarraitu"</item>
+ <item msgid="235450158666155406">"Utzi"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Hautatu konexio mota"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Kanpoko antena badago sintonizadorera konektatuta, aukeratu Antena. Kableko zerbitzu-hornitzaile batek eskaintzen badizkizu kanalak, aukeratu Kablea. Ziur ez bazaude, mota bietakoak bilatuko dira, baina zertxobait luzatuko da."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Antena"</item>
+ <item msgid="2670079958754180142">"Kablea"</item>
+ <item msgid="36774059871728525">"Ez dakit ziur"</item>
+ <item msgid="6881204453182153978">"Garapenerako soilik"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"Sintonizadorearen konfigurazioa"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB kanal-sintonizadorearen konfigurazioa"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Sareko kanalen sintonizadorearen konfigurazioa"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Zenbait minutu beharko dira"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Sintonizadorea ez dago erabilgarri edo beste zerbait ari da grabatzen."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d kanal aurkitu dira</item>
+ <item quantity="one">%1$d kanal aurkitu da</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"UTZI KANALAK BILATZEARI"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d kanal aurkitu dira</item>
+ <item quantity="one">%1$d kanal aurkitu da</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">Primeran! %1$d kanal aurkitu da kanalak bilatzean. Oker gaudela uste baduzu, doitu antenaren posizioa eta saiatu berriro.</item>
+ <item quantity="one">Primeran! %1$d kanal aurkitu da kanalak bilatzean. Oker gaudela uste baduzu, doitu antenaren posizioa eta saiatu berriro.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Eginda"</item>
+ <item msgid="2480490326672924828">"Bilatu berriro"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Ez da aurkitu kanalik"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Bilaketak ez du aurkitu kanalik. Egiaztatu telebista-seinalearen iturburu batera konektatuta dagoela telebista.\n\nAntena analogiko bat badarabilzu, doitu bere kokapena edo norabidea. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan eta gauzatu bilaketa berriro."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Bilaketak ez du aurkitu kanalik. Egiaztatu USB sintonizadorea entxufatuta eta telebistako seinale-iturburu batera konektatuta dagoela.\n\nAntena analogiko bat badarabilzu, doitu bere kokapena edo norabidea. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan eta gauzatu bilaketa berriro."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Ez da aurkitu kanalik. Egiaztatu sintonizadorea piztuta dagoela eta telebista-seinalea igortzen duen iturburu batera konektatu duzula.\n\nHari-gabeko antena bat erabiltzen ari bazara, doi ezazu haren kokapena edo norabidea. Emaitzarik onenak lortzeko, ezar ezazu ahal bezain altu eta leiho batetik gertu. Ondoren, bila itzazu kanalak berriro."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Bilatu berriro"</item>
+ <item msgid="2092797862490235174">"Eginda"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Bilatu telebista-kateak"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Sintonizadorearen konfigurazioa"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB bidezko sintonizadorearen konfigurazioa"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Sareko sintonizadorearen konfigurazioa"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Deskonektatu da USB bidezko sintonizadorea."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Deskonektatu da sareko sintonizadorea."</string>
+</resources>
diff --git a/usbtuner-res/values-eu/strings.xml b/usbtuner-res/values-eu/strings.xml
deleted file mode 100644
index a0d456eb..00000000
--- a/usbtuner-res/values-eu/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"Sintonizadorea"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB bidezko sintonizadorea"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Aktibatuta"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Desaktibatuta"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Itxaron prozesatzen amaitu arte"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Hautatu kanalaren iturburua"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Ez dago seinalerik"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Ezin izan da sintonizatu <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Ezin izan da sintonizatu"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Sintonizadorearen softwarea berriki eguneratu da. Bilatu kanalak berriro."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Audioa gaitzeko, joan sistemaren soinuaren ezarpenetara eta gaitu soinu inguratzailea"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanal-sintonizadorearen konfigurazioa"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"Sintonizadorearen konfigurazioa"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB kanal-sintonizadorearen konfigurazioa"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Egiaztatu telebista-seinalearen iturburu batera konektatuta dagoela telebista.\n\nAntena analogiko bat badarabilzu, agian bere kokapena edo norabidea doitu beharko dituzu kanal gehienak eskuratzeko. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"Egiaztatu USB sintonizadorea entxufatuta eta telebistako seinale-iturburu batera konektatuta dagoela.\n\nHari gabeko antena badarabilzu, doitu bere kokapena edo norabidea. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan eta gauzatu bilaketa berriro."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Jarraitu"</item>
- <item msgid="727245208787621142">"Orain ez"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Berriro konfiguratu nahi dituzu kanalak?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Sintonizadoreak aurkitutako kanalak kenduko dira eta berriro bilatuko dira kanalak.\n\nEgiaztatu telebista-seinalearen iturburu batera konektatuta dagoela telebista.\n\nAntena analogiko bat badarabilzu, agian bere kokapena edo norabidea doitu beharko dituzu kanal gehienak eskuratzeko. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"USB sintonizadoreak aurkitutako kanalak kenduko dira eta berriro bilatuko dira kanalak.\n\nEgiaztatu USB sintonizadorea entxufatuta eta telebistako seinale-iturburu batera konektatuta dagoela.\n\nAntena analogiko bat badarabilzu, agian bere kokapena edo norabidea doitu beharko dituzu kanal gehienak eskuratzeko. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Jarraitu"</item>
- <item msgid="235450158666155406">"Utzi"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Hautatu konexio mota"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Kanpoko antena badago sintonizadorera konektatuta, aukeratu Antena. Kableko zerbitzu-hornitzaile batek eskaintzen badizkizu kanalak, aukeratu Kablea. Ziur ez bazaude, mota bietakoak bilatuko dira, baina zertxobait luzatuko da."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Antena"</item>
- <item msgid="2670079958754180142">"Kablea"</item>
- <item msgid="36774059871728525">"Ez dakit ziur"</item>
- <item msgid="6881204453182153978">"Garapenerako soilik"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"Sintonizadorearen konfigurazioa"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB kanal-sintonizadorearen konfigurazioa"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Zenbait minutu beharko dira"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Sintonizadorea ez dago erabilgarri edo beste zerbait ari da grabatzen."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d kanal aurkitu dira</item>
- <item quantity="one">%1$d kanal aurkitu da</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"UTZI KANALAK BILATZEARI"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d kanal aurkitu dira</item>
- <item quantity="one">%1$d kanal aurkitu da</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">Primeran! %1$d kanal aurkitu da kanalak bilatzean. Oker gaudela uste baduzu, doitu antenaren posizioa eta saiatu berriro.</item>
- <item quantity="one">Primeran! %1$d kanal aurkitu da kanalak bilatzean. Oker gaudela uste baduzu, doitu antenaren posizioa eta saiatu berriro.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Eginda"</item>
- <item msgid="2480490326672924828">"Bilatu berriro"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Ez da aurkitu kanalik"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Bilaketak ez du aurkitu kanalik. Egiaztatu telebista-seinalearen iturburu batera konektatuta dagoela telebista.\n\nAntena analogiko bat badarabilzu, doitu bere kokapena edo norabidea. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan eta gauzatu bilaketa berriro."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Bilaketak ez du aurkitu kanalik. Egiaztatu USB sintonizadorea entxufatuta eta telebistako seinale-iturburu batera konektatuta dagoela.\n\nAntena analogiko bat badarabilzu, doitu bere kokapena edo norabidea. Emaitzarik onenak lortzeko, ezarri toki altu batean edo leiho baten ondoan eta gauzatu bilaketa berriro."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Bilatu berriro"</item>
- <item msgid="2092797862490235174">"Eginda"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Bilatu telebista-kanalak"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Sintonizadorearen konfigurazioa"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB bidezko sintonizadorearen konfigurazioa"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB bidezko sintonizadorea deskonektatu da."</string>
-</resources>
diff --git a/usbtuner-res/values-fa/strings.xml b/usbtuner-res/values-fa/strings.xml
index 8a51a4fc..586fc926 100644
--- a/usbtuner-res/values-fa/strings.xml
+++ b/usbtuner-res/values-fa/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"تنظیم‌کننده تلویزیون"</string>
<string name="ut_app_name" msgid="8557698013780762454">"‏تنظیم‌کننده تلویزیون USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"روشن"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"خاموش"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"تنظیم‌کننده تلویزیون شبکه (بتا)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"لطفاً تا پایان پردازش صبر کنید"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"منبع کانال را انتخاب کنید"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"بدون سیگنال"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"تنظیم به <xliff:g id="CHANNEL_NAME">%s</xliff:g> انجام نشد"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"تنظیم ناموفق بود"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"نرم‌افزار تنظیم‌کننده اخیراً به‌روزرسانی شده است. لطفاً کانال‌ها را دوباره اسکن کنید."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"برای فعال کردن صدا، صدای فراگیر را در تنظیمات صدای سیستم فعال کنید"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"صوت پخش نمی‌شود. لطفاً تلویزیون دیگری را امتحان کنید."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"راه‌اندازی تنظیم‌کننده کانال"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"راه‌اندازی تنظیم‌کننده تلویزیون"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"‏راه‌اندازی تنظیم‌کننده کانال USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"راه‌اندازی تنظیم‌کننده شبکه‌ای"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"مطمئن شوید تلویزیونتان به منبع سیگنال تلویزیونی متصل است.\n\nدر صورت استفاده از آنتن بی‌سیم شاید لازم باشد برای دریافت کانال‌های بیشتر، موقعیت یا جهت آن را تنظیم کنید. برای بهترین نتایج، آن را در جای بلند و نزدیک پنجره قرار دهید."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"‏مطمئن شوید تنظیم‌کننده USB به منبع نیرو و منبع سیگنال تلویزیونی متصل است.\n\nدر صورت استفاده از آنتن بی‌سیم، موقعیت یا جهت آن را تنظیم کنید. برای بهترین نتایج، آن را در جای بلند و نزدیک پنجره قرار دهید."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"مطمئن شوید تنظیم‌کننده شبکه‌ای به برق و منبع سیگنال تلویزیونی وصل است.\n\nاگر از آنتن هوایی استفاده می‌کنید، ممکن است لازم باشد برای دریافت بیشترین تعداد کانال مکان و موقعیت آن را تنظیم کنید. برای بهترین نتایج، آن را در جای بلند و نزدیک پنجره قرار دهید."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"ادامه"</item>
<item msgid="727245208787621142">"فعلاً نه"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"تنظیم کانال دوباره اجرا شود؟"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"با این کار کانال‌های پیداشده از تنظیم‌کننده تلویزیون حذف می‌شوند و دوباره برای کانال‌های جدید اسکن می‌کند.\n\nمطمئن شوید تلویزیونتان به منبع سیگنال تلویزیونی متصل است.\n\nدر صورت استفاده از آنتن بی‌سیم، شاید لازم باشد برای دریافت کانال‌های بیشتر، موقعیت یا جهت آن را تنظیم کنید. برای بهترین نتایج، آن را در جای بلند و نزدیک پنجره قرار دهید."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"‏این کار کانال‌های پیداشده از تنظیم‌کننده USB را حذف می‌کند و دوباره کانال‌های جدید را اسکن می‌کند.\n\nمطمئن شوید تنظیم‌کننده USB به منبع نیرو و منبع سیگنال تلویزیونی متصل است.\n\nدر صورت استفاده از آنتن بی‌سیم، برای دریافت کانال‌های بیشتر، موقعیت یا جهت آن را تنظیم کنید. برای بهترین نتایج، آن را در جای بلند و نزدیک پنجره قرار دهید و دوباره اسکن کنید."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"این کار کانال‌های پیداشده را از تنظیم‌کننده شبکه‌ای حذف می‌کند و دوباره کانال‌های جدید را اسکن می‌کند.\n\nمطمئن شوید تنظیم‌کننده شبکه‌ای به برق و منبع سیگنال تلویزیونی وصل است.\n\nاگر از آنتن هوایی استفاده می‌کنید، ممکن است لازم باشد برای دریافت بیشترین تعداد کانال مکان و موقعیت آن را تنظیم کنید. برای بهترین نتایج، آن را در جای بلند و نزدیک پنجره قرار دهید."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"ادامه"</item>
<item msgid="235450158666155406">"لغو"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"راه‌اندازی تنظیم‌کننده تلویزیون"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"‏راه‌اندازی تنظیم‌کننده کانال USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"راه‌اندازی تنظیم‌کننده کانال شبکه‌ای"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"ممکن است چند دقیقه طول بکشد"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"تنظیم‌کننده موقتاً دردسترس نیست یا در این لحظه در ضبط شدن استفاده می‌شود."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"کانالی پیدا نشد"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"اسکن هیچ کانالی پیدا نکرد. مطمئن شوید تلویزیونتان به یک منبع سیگنال تلویزیونی متصل است. \n\nدر صورت استفاده از آنتن بی‌سیم، موقعیت یا جهت آن را تنظیم کنید. برای بهترین نتایج، آن را در جای بلند و نزدیک پنجره قرار دهید و دوباره اسکن کنید."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"‏اسکن هیچ کانالی پیدا نکرد. مطمئن شوید تنظیم‌کننده USB به منبع نیرو و منبع سیگنال تلویزیونی متصل است.\n\nدر صورت استفاده از آنتن بی‌سیم، موقعیت یا جهت آن را تنظیم کنید. برای بهترین نتایج، آن را در جای بلند و نزدیک پنجره قرار دهید و دوباره اسکن کنید."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"اسکن، کانالی پیدا نکرد. مطمئن شوید تنظیم‌کننده شبکه‌ای به برق و منبع سیگنال تلویزیونی وصل است.\n\nاگر از آنتن هوایی استفاده می‌کنید، موقعیت یا جهت آن را تنظیم کنید. برای بهترین نتایج، آن را در جای بلند و نزدیک پنجره قرار دهید و دوباره اسکن کنید."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"اسکن دوباره"</item>
<item msgid="2092797862490235174">"تمام"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"اسکن کانال‌های تلویزیون"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"راه‌اندازی تنظیم‌کننده تلویزیون"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"‏راه‌اندازی تنظیم‌کننده تلویزیون USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"‏تیونر تلویزیون USB قطع شد."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"اسکن کانال‌های تلویزیون"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"راه‌اندازی تنظیم‌کننده تلویزیون"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"‏راه‌اندازی تنظیم‌کننده تلویزیون USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"راه‌اندازی تنظیم‌کننده تلویزیون شبکه‌ای"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"‏ارتباط تیونر USB تلویزیون قطع شد."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"ارتباط تیونر شبکه قطع شد."</string>
</resources>
diff --git a/usbtuner-res/values-fi/strings.xml b/usbtuner-res/values-fi/strings.xml
index 79d0c7f5..4dabc97c 100644
--- a/usbtuner-res/values-fi/strings.xml
+++ b/usbtuner-res/values-fi/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV-viritin"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB-TV-viritin"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Ota käyttöön"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Poista käytöstä"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Antenni-TV-viritin (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Odota, että käsittely on valmis."</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Valitse kanavalähde."</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Ei signaalia"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Kanavan <xliff:g id="CHANNEL_NAME">%s</xliff:g> virittäminen epäonnistui."</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Virittäminen epäonnistui."</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Viritinohjelmisto on päivitetty äskettäin. Hae kanavat uudelleen."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Ota ääni käyttöön kytkemällä tilaääni päälle järjestelmän ääniasetuksissa."</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Äänen toistaminen ei onnistu. Yritä käyttää toista TV:tä."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanavavirittimen määritys"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"TV-virittimen määritys"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB-kanavavirittimen määritys"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Antennivirittimen määritys"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Tarkista, että TV on liitetty TV-signaalilähteeseen.\n\nJos käytät antennia, useampien kanavien löytäminen saattaa edellyttää sen paikan tai suuntauksen säätämistä. Saat parhaan tuloksen asettamalla antennin korkealle ja lähelle ikkunaa."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Tarkista, että USB-viritin on kytketty oikein ja liitetty TV-signaalilähteeseen.\n\nJos käytät antennia, useampien kanavien löytäminen saattaa edellyttää sen paikan ja suuntauksen säätämistä. Saat parhaan tuloksen asettamalla antennin korkealle ja lähelle ikkunaa."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Tarkista, että viritin on päällä ja liitetty TV-signaalilähteeseen.\n\nJos käytät antennia, säädä sen paikkaa tai suuntausta. Aseta antenni korkealle ja lähelle ikkunaa, jotta saat parhaat tulokset, ja tee uusi haku."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Jatka"</item>
<item msgid="727245208787621142">"Ei nyt"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Haetaanko kanavia uudelleen?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Tämä poistaa TV-virittimen löytämät kanavat ja tekee kanavahaun uudelleen.\n\nTarkista, että TV on liitetty TV-signaalilähteeseen.\n\nJos käytät antennia, useampien kanavien löytäminen saattaa edellyttää sen paikan tai suuntauksen säätämistä. Saat parhaan tuloksen asettamalla antennin korkealle ja lähelle ikkunaa."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Tämä poistaa USB-virittimen löytämät kanavat ja tekee kanavahaun uudelleen.\n\nTarkista, että USB-viritin on kytketty oikein ja liitetty TV-signaalilähteeseen.\n\nJos käytät antennia, useampien kanavien löytäminen saattaa edellyttää sen paikan tai suuntauksen säätämistä. Saat parhaan tuloksen asettamalla antennin korkealle ja lähelle ikkunaa."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Tämä poistaa virittimen löytämät kanavat ja etsii kanavia uudestaan.\n\nTarkista, että viritin on päällä ja liitetty TV-signaalilähteeseen.\n\nJos käytät antennia, säädä sen paikkaa tai suuntausta. Aseta antenni korkealle ja lähelle ikkunaa, jotta saat parhaat tulokset, ja tee uusi haku."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Jatka"</item>
<item msgid="235450158666155406">"Peruuta"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"TV-virittimen määritys"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB-kanavavirittimen määritys"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Antennikanavavirittimen määritys"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Tämä voi kestää useita minuutteja."</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Viritin ei ole toistaiseksi käytettävissä tai se on nauhoitteen käytössä."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Kanavia ei löytynyt"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Haku ei löytänyt yhtään kanavaa. Tarkista, että TV on liitetty TV-signaalilähteeseen.\n\nJos käytät antennia, säädä sen paikkaa tai suuntausta. Saat parhaan tuloksen asettamalla antennin korkealle ja lähelle ikkunaa. Tee haku sitten uudelleen."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Haku ei löytänyt yhtään kanavaa. Tarkista, että USB-viritin on kytketty oikein ja liitetty TV-signaalilähteeseen.\n\nJos käytät antennia, säädä sen paikkaa tai suuntausta. Saat parhaan tuloksen asettamalla antennin korkealle ja lähelle ikkunaa. Tee haku sitten uudelleen."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Haussa ei löytynyt kanavia. Tarkista, että viritin on päällä ja liitetty TV-signaalilähteeseen.\n\nJos käytät antennia, säädä sen paikkaa tai suuntausta. Aseta antenni korkealle ja lähelle ikkunaa, jotta saat parhaat tulokset, ja tee uusi haku."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Hae uudelleen"</item>
<item msgid="2092797862490235174">"Valmis"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Hae TV-kanavia"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV-virittimen määritys"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB-TV-virittimen määritys"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB-TV-viritin ei ole kytketty"</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Hae TV-kanavia"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV-virittimen määritys"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB-TV-virittimen määritys"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Antenni-TV-virittimen määritys"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-TV-viritin ei ole kytketty."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Verkkoviritin ei ole kytketty."</string>
</resources>
diff --git a/usbtuner-res/values-fr-rCA/strings.xml b/usbtuner-res/values-fr-rCA/strings.xml
index 54e8759e..754649ae 100644
--- a/usbtuner-res/values-fr-rCA/strings.xml
+++ b/usbtuner-res/values-fr-rCA/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Syntoniseur télé"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Syntoniseur télé USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Activer"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Désactivé"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Syntoniseur télé réseau (BÊTA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Veuillez patienter jusqu\'à la fin du traitement"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Sélectionnez votre source de chaînes"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Aucun signal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Impossible de syntoniser <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Échec de syntonisation"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Le logiciel du syntoniseur a été mis à jour récemment. Veuillez rechercher les chaînes à nouveau."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Pour activer l\'audio, vous devez activer le son ambiophonique dans les paramètres sonores du système"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Impossible de lire l\'audio. Veuillez essayer sur un autre téléviseur."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configuration du syntoniseur de chaînes"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Configuration du syntoniseur télé"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Configurer les chaînes du syntoniseur USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Configuration du syntoniseur réseau"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Vérifiez que le téléviseur est connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne, vous devrez peut-être ajuster sa position ou son orientation pour recevoir le plus de chaînes possible. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Vérifiez que le syntoniseur USB est branché et connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne, ajustez sa position ou son orientation. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre, puis relancez la recherche."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Assurez-vous que le syntoniseur réseau est allumé et connecté à une source de signal télé.\n\nSi vous utilisez une antenne, il se peut que vous deviez ajuster sa position ou sa direction pour capter un maximum de chaînes. Pour obtenir des résultats optimaux, placez-la en hauteur et près d\'une fenêtre."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continuer"</item>
<item msgid="727245208787621142">"Pas maintenant"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Relancer la configuration de la chaîne?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Cette opération permet de supprimer les chaînes détectées du syntoniseur télé et d\'en rechercher de nouvelles.\n\nVérifiez que le téléviseur est connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne, vous devrez peut-être ajuster sa position ou son orientation pour recevoir le plus de chaînes possible. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Cette opération permet de supprimer les chaînes détectées du syntoniseur USB et d\'en rechercher de nouvelles.\n\nVérifiez que le syntoniseur USB est branché et connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne, vous devrez peut-être ajuster sa position ou son orientation pour recevoir le plus de chaînes possible. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Cela supprimera les chaînes trouvées du syntoniseur réseau et lancera une nouvelle recherche.\n\nAssurez-vous que le syntoniseur réseau est allumé et connecté à une source de signal télé.\n\nSi vous utilisez une antenne, il se peut que vous deviez ajuster sa position ou sa direction pour capter un maximum de chaînes. Pour obtenir des résultats optimaux, placez-la en hauteur et près d\'une fenêtre."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continuer"</item>
<item msgid="235450158666155406">"Annuler"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Configuration du syntoniseur télé"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Configurer les chaînes du syntoniseur USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Configuration du syntoniseur de chaînes réseau"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Cela peut prendre plusieurs minutes"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Le syntoniseur n\'est pas accessible ou bien il est en cours d\'utilisation par l\'enregistreur."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Aucune chaîne"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"La recherche n\'a détecté aucune chaîne. Vérifiez que le téléviseur est connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne, ajustez sa position ou son orientation. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre, puis relancez la recherche."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"La recherche n\'a détecté aucune chaîne. Vérifiez que le syntoniseur USB est branché et connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne, ajustez sa position ou son orientation. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre, puis relancez la recherche."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"La recherche n\'a détecté aucune chaîne. Assurez-vous que le syntoniseur réseau est allumé et connecté à une source de signal télé.\n\nSi vous utilisez une antenne, ajustez sa position ou sa direction. Pour obtenir des résultats optimaux, placez-la en hauteur et près d\'une fenêtre, puis relancez la recherche."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Rechercher à nouveau"</item>
<item msgid="2092797862490235174">"Terminé"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Rechercher les chaînes de télévision"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Configuration du syntoniseur télé"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Configurer le syntoniseur télé USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Le syntoniseur télé USB est débranché."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Rechercher les chaînes de télévision"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Configuration du syntoniseur télé"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Configurer le syntoniseur télé USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Configuration du syntoniseur télé réseau"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Le syntoniseur télé USB est déconnecté."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Le syntoniseur réseau est déconnecté."</string>
</resources>
diff --git a/usbtuner-res/values-fr/strings.xml b/usbtuner-res/values-fr/strings.xml
index 4cb551f7..3b4a6589 100644
--- a/usbtuner-res/values-fr/strings.xml
+++ b/usbtuner-res/values-fr/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Tuner TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Tuner TV USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Activé"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Désactivé"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Tuner TV réseau (VERSION BÊTA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Veuillez patienter jusqu\'à la fin du traitement."</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Sélectionnez la source de la chaîne."</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Aucun signal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Échec de sélection de la chaîne <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Échec de la sélection de la chaîne"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Le logiciel du tuner a été mis à jour récemment. Veuillez lancer une nouvelle recherche des chaînes."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Activer le son surround dans les paramètres sonores du système pour activer l\'audio"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Impossible de lire le fichier audio. Veuillez utiliser un autre téléviseur"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configuration du tuner de chaînes"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Configuration du tuner TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Configuration du tuner de chaînes USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Configuration du tuner réseau"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Vérifiez que le téléviseur est connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne Over The Air, vous devrez peut-être ajuster sa position ou son orientation pour recevoir le plus de chaînes possible. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Vérifiez que le tuner USB est branché et connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne Over The Air, ajustez sa position ou son orientation. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre, puis relancez la recherche."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Vérifiez que le tuner réseau est allumé et connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne Over The Air, vous devrez peut-être ajuster sa position ou son orientation pour recevoir le plus de chaînes possible. Pour de meilleurs résultats, placez-la en hauteur et près d\'une fenêtre."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continuer"</item>
<item msgid="727245208787621142">"Pas maintenant"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Relancer la configuration de la chaîne ?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Cette opération permet de supprimer les chaînes détectées du tuner TV et d\'en rechercher de nouvelles.\n\nVérifiez que le téléviseur est connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne Over The Air, vous devrez peut-être ajuster sa position ou son orientation pour recevoir le plus de chaînes possible. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Cette opération permet de supprimer les chaînes détectées du tuner USB et d\'en rechercher de nouvelles.\n\nVérifiez que le tuner USB est branché et connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne Over The Air, vous devrez peut-être ajuster sa position ou son orientation pour recevoir le plus de chaînes possible. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Cette opération permet de supprimer les chaînes détectées du tuner réseau et d\'en rechercher de nouvelles.\n\nVérifiez que le tuner réseau est allumé et connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne Over The Air, vous devrez peut-être ajuster sa position ou son orientation pour recevoir le plus de chaînes possible. Pour de meilleurs résultats, placez-la en hauteur et près d\'une fenêtre."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continuer"</item>
<item msgid="235450158666155406">"Annuler"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Configuration du tuner TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Configuration du tuner de chaînes USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Configuration du tuner de chaînes réseau"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Cette opération peut prendre plusieurs minutes."</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Le tuner est temporairement indisponible ou est déjà utilisé pour l\'enregistrement."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Aucune chaîne n\'a été détectée"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"La recherche n\'a détecté aucune chaîne. Vérifiez que le téléviseur est connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne Over The Air, ajustez sa position ou son orientation. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre, puis relancez la recherche."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"La recherche n\'a détecté aucune chaîne. Vérifiez que le tuner USB est branché et connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne Over The Air, ajustez sa position ou son orientation. Pour obtenir les meilleurs résultats, placez-la dans une position élevée et près d\'une fenêtre, puis relancez la recherche."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"La recherche n\'a détecté aucune chaîne. Vérifiez que le tuner réseau est allumé et connecté à la source d\'un signal de télévision.\n\nSi vous utilisez une antenne Over The Air, ajustez sa position ou son orientation. Pour de meilleurs résultats, placez-la en hauteur et près d\'une fenêtre, puis relancez la recherche."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Rechercher à nouveau"</item>
<item msgid="2092797862490235174">"OK"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Rechercher les chaînes de télévision"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Configuration du tuner TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Configuration du tuner TV USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Le tuner TV USB est déconnecté."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Rechercher les chaînes de télévision"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Configuration du tuner TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Configuration du tuner TV USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Configuration du tuner TV réseau"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Le tuner TV USB est déconnecté."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Tuner réseau déconnecté."</string>
</resources>
diff --git a/usbtuner-res/values-gl-rES/strings.xml b/usbtuner-res/values-gl-rES/strings.xml
new file mode 100644
index 00000000..4c75fc65
--- /dev/null
+++ b/usbtuner-res/values-gl-rES/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"Sintonizador de televisión"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"Sintonizador USB de televisión"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Sintonizador de televisión de rede (beta)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Espera a que finalice o procesamento"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"O software do sintonizador actualizouse recentemente. Volve buscar canles."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Activa o son envolvente na configuración de son do sistema para activar o audio"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Non se pode reproducir o audio. Proba con outra televisión"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configuración do sintonizador de canles"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"Configuración do sintonizador de televisión"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"Configuración do sintonizador de canles USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Configuración do sintonizador de rede"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Comproba que a televisión está conectada a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, é posible que teñas que axustar a súa posición ou dirección para recibir a maioría das canles. Para conseguir os mellores resultados, colócaa nun lugar alto e preto dunha ventá."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"Comproba que o sintonizador USB está enchufado e conectado a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, é posible que teñas que axustar a súa posición ou dirección para recibir a maioría das canles. Para conseguir os mellores resultados, colócaa nun lugar alto e preto dunha ventá."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Verifica que o sintonizador de rede estea acendido e conectado a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, é posible que teñas que axustar a súa posición ou dirección para recibir a maioría das canles. Para conseguir os mellores resultados, colócaa nun lugar alto e preto dunha ventá."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Continuar"</item>
+ <item msgid="727245208787621142">"Agora non"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Queres volver executar a configuración da canle?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Esta acción eliminará as canles que atopaches co sintonizador de televisión e buscará outras novas.\n\nComproba que a televisión está conectada a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, é posible que teñas que axustar a súa posición ou dirección para recibir a maioría das canles. Para conseguir os mellores resultados, colócaa nun lugar alto e preto dunha ventá."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"Esta acción eliminará as canles que atopaches co sintonizador USB e buscará outras novas.\n\nComproba que o sintonizador USB está enchufado e conectado a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, é posible que teñas que axustar a súa posición ou dirección para recibir a maioría das canles. Para conseguir os mellores resultados, colócaa nun lugar alto e preto dunha ventá."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Con esta acción quitaranse as canles atopadas do teu sintonizador de rede e buscaranse novas canles outra vez.\n\nVerifica que o sintonizador de rede estea acendido e conectado a unha fonte de sinal de televisión.\n\n}Se usas unha antena sen fíos, é posible que teñas que axustar a súa posición ou dirección para recibir a maioría das canles. Para conseguir os mellores resultados, colócaa nun lugar alto e preto dunha ventá."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Continuar"</item>
+ <item msgid="235450158666155406">"Cancelar"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Seleccionar tipo de conexión"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Selecciona Antena se hai unha antena externa conectada ao sintonizador. Selecciona Cable se as túas canles proceden dun fornecedor de servizo de cable. Se non o sabes con seguridade, realizarase a busca usando os dous tipos de conexión, pero este proceso pode tardar máis tempo."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Antena"</item>
+ <item msgid="2670079958754180142">"Cable"</item>
+ <item msgid="36774059871728525">"Non estou seguro"</item>
+ <item msgid="6881204453182153978">"Só desenvolvemento"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"Configuración do sintonizador de televisión"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"Configuración do sintonizador de canles USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Configuración do sintonizador de canles de rede"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Esta acción pode tardar varios minutos"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"O sintonizador non está dispoñible temporalmente ou xa se utiliza para unha gravación."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">Atopáronse %1$d canles</item>
+ <item quantity="one">Atopouse %1$d canle</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"DETER BUSCA DE CANLES"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">Atopáronse %1$d canles</item>
+ <item quantity="one">Atopouse %1$d canle</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">Estupendo! Atopáronse %1$d canles durante a busca de canles. Se non che parece correcto, tenta axustar a posición da antena e realiza a busca de novo.</item>
+ <item quantity="one">Estupendo! Atopouse %1$d canle durante a busca de canles. Se non che parece correcto, tenta axustar a posición da antena e realiza a busca de novo.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Feito"</item>
+ <item msgid="2480490326672924828">"Buscar de novo"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Non se atopou ningunha canle"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Durante a busca non se atopou ningunha canle. Comproba que a televisión está conectada a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, axusta a súa posición ou dirección. Para conseguir os mellores resultados, colócaa nun lugar alto, preto dunha ventá e realiza a fai a busca de novo."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"A busca non atopou ningunha canle. Comproba que o sintonizador USB está enchufado e conectado a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, axusta a súa posición ou dirección. Para conseguir os mellores resultados, colócaa nun lugar alto, preto dunha ventá e realiza a busca de novo."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"A busca de canles non obtivo resultados. Verifica que o sintonizador de rede estea acendido e conectado a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, axusta a súa posición ou dirección. Para conseguir os mellores resultados, colócaa nun lugar alto, preto dunha ventá, e realiza a busca de novo."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Buscar de novo"</item>
+ <item msgid="2092797862490235174">"Feito"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Buscar canles de televisión"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Configuración do sintonizador de televisión"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Configuración do sintonizador USB de televisión"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Configuración do sintonizador de televisión de rede"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Desconectouse o sintonizador de televisión USB."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Desconectouse o sintonizador de rede."</string>
+</resources>
diff --git a/usbtuner-res/values-gl/strings.xml b/usbtuner-res/values-gl/strings.xml
deleted file mode 100644
index 58c14605..00000000
--- a/usbtuner-res/values-gl/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"Sintonizador de televisión"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"Sintonizador USB de televisión"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Activar"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Desactivar"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Espera a que finalice o procesamento"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Selecciona a fonte da túa canle"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Sen sinal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Produciuse un erro ao sintonizar <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Produciuse un erro ao sintonizar"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"O software do sintonizador actualizouse recentemente. Volve buscar canles."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Activa o son envolvente na configuración de son do sistema para activar o audio"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configuración do sintonizador de canles"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"Configuración do sintonizador de televisión"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"Configuración do sintonizador de canles USB"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Comproba que a televisión está conectada a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, é posible que teñas que axustar a súa posición ou dirección para recibir a maioría das canles. Para conseguir os mellores resultados, colócaa nun lugar alto e preto dunha ventá."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"Comproba que o sintonizador USB está enchufado e conectado a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, é posible que teñas que axustar a súa posición ou dirección para recibir a maioría das canles. Para conseguir os mellores resultados, colócaa nun lugar alto e preto dunha ventá."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Continuar"</item>
- <item msgid="727245208787621142">"Agora non"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Queres volver executar a configuración da canle?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Esta acción eliminará as canles que atopaches co sintonizador de televisión e buscará outras novas.\n\nComproba que a televisión está conectada a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, é posible que teñas que axustar a súa posición ou dirección para recibir a maioría das canles. Para conseguir os mellores resultados, colócaa nun lugar alto e preto dunha ventá."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"Esta acción eliminará as canles que atopaches co sintonizador USB e buscará outras novas.\n\nComproba que o sintonizador USB está enchufado e conectado a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, é posible que teñas que axustar a súa posición ou dirección para recibir a maioría das canles. Para conseguir os mellores resultados, colócaa nun lugar alto e preto dunha ventá."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Continuar"</item>
- <item msgid="235450158666155406">"Cancelar"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Seleccionar tipo de conexión"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Selecciona Antena se hai unha antena externa conectada ao sintonizador. Selecciona Cable se as túas canles proceden dun fornecedor de servizo de cable. Se non o sabes con seguridade, realizarase a busca usando os dous tipos de conexión, pero este proceso pode tardar máis tempo."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Antena"</item>
- <item msgid="2670079958754180142">"Cable"</item>
- <item msgid="36774059871728525">"Non estou seguro"</item>
- <item msgid="6881204453182153978">"Só desenvolvemento"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"Configuración do sintonizador de televisión"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"Configuración do sintonizador de canles USB"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Esta acción pode tardar varios minutos"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"O sintonizador non está dispoñible temporalmente ou xa se utiliza para unha gravación."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">Atopáronse %1$d canles</item>
- <item quantity="one">Atopouse %1$d canle</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"DETER BUSCA DE CANLES"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">Atopáronse %1$d canles</item>
- <item quantity="one">Atopouse %1$d canle</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">Estupendo! Atopáronse %1$d canles durante a busca de canles. Se non che parece correcto, tenta axustar a posición da antena e realiza a busca de novo.</item>
- <item quantity="one">Estupendo! Atopouse %1$d canle durante a busca de canles. Se non che parece correcto, tenta axustar a posición da antena e realiza a busca de novo.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Feito"</item>
- <item msgid="2480490326672924828">"Buscar de novo"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Non se atopou ningunha canle"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Durante a busca non se atopou ningunha canle. Comproba que a televisión está conectada a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, axusta a súa posición ou dirección. Para conseguir os mellores resultados, colócaa nun lugar alto, preto dunha ventá e realiza a fai a busca de novo."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"A busca non atopou ningunha canle. Comproba que o sintonizador USB está enchufado e conectado a unha fonte de sinal de televisión.\n\nSe usas unha antena sen fíos, axusta a súa posición ou dirección. Para conseguir os mellores resultados, colócaa nun lugar alto, preto dunha ventá e realiza a busca de novo."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Buscar de novo"</item>
- <item msgid="2092797862490235174">"Feito"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Busca canles de televisión"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Configuración do sintonizador de televisión"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Configuración do sintonizador USB de televisión"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Desconectouse o sintonizador de televisión USB."</string>
-</resources>
diff --git a/usbtuner-res/values-hi/strings.xml b/usbtuner-res/values-hi/strings.xml
index ea0d51c1..265670e7 100644
--- a/usbtuner-res/values-hi/strings.xml
+++ b/usbtuner-res/values-hi/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"टीवी ट्यूनर"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB टीवी ट्यूनर"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"चालू करें"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"बंद करें"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"नेटवर्क टीवी ट्यूनर (बीटा)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"कृपया प्रक्रिया पूरी होने का इंतज़ार करें"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"अपना चैनल स्रोत चुनें"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"कोई सिग्नल नहीं"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> को ट्यून करने में विफल रहा"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ट्यून करने में विफल रहा"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"ट्यूनर सॉफ़्टवेयर को हाल ही में अपडेट किया गया है. कृपया चैनलों के लिए दोबारा स्कैन करें."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ऑडियो सक्षम करने के लिए सिस्टम साउंड सेटिंग में सराउंड साउंड सक्षम करें"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"ऑडियो नहीं चल पा रहा है. कृपया कोई दूसरा टीवी आज़माएं"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"चैनल ट्यूनर सेटअप"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"टीवी ट्यूनर सेटअप"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB चैनल ट्यूनर सेटअप"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"नेटवर्क ट्यूनर सेटअप"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"पुष्टि करें कि आपका टीवी किसी टीवी सिग्नल स्रोत से कनेक्ट किया हुआ है.\n\nयदि ओवर द एयर एंटेना का उपयोग कर रहे हैं, तो अधिकांश चैनल पाने के लिए आपको उसकी स्थिति या दिशा समायोजित करने की आवश्यकता हो सकती है. सबसे अच्छे परिणामों के लिए, उसे ऊंचाई पर और किसी खिड़की के पास लगाएं."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"पुष्टि करें कि USB ट्यूनर प्लग इन है और टीवी सिग्नल स्रोत से कनेक्ट किया हुआ है.\n\nयदि आप ओवर द एयर एंटेना का उपयोग कर रहे हैं, तो अधिकांश चैनल पाने के लिए आपको उसकी स्थिति या दिशा समायोजित करने की आवश्यकता हो सकती है. अच्छे परिणामों के लिए, उसे ऊंचाई पर और किसी खिड़की के पास लगाएं."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"सत्यापित करें कि नेटवर्क ट्यूनर चालू है और किसी टीवी सिग्नल स्रोत से कनेक्ट है.\n\nयदि किसी ओवर-द-एयर एंटेना का उपयोग कर रहे हैं, तो अधिकांश चैनल प्राप्त करने के लिए आपको एंटेना का स्थान या दिशा समायोजित करनी पड़ सकती है. सर्वश्रेष्ठ परिणामों के लिए, उसे ऊंचाई पर और किसी खिड़की के पास रखें."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"जारी रखें"</item>
<item msgid="727245208787621142">"अभी नहीं"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"चैनल सेटअप फिर से चलाएं?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"इससे टीवी ट्यूनर से मिले चैनल निकल जाएंगे और नए चैनल दोबारा स्कैन किए जाएंगे.\n\nपुष्टि करें कि आपका टीवी किसी टीवी सिग्नल स्रोत से कनेक्ट किया हुआ है.\n\nयदि ओवर द एयर एंटेना का उपयोग कर रहे हैं, तो अधिकांश चैनल पाने के लिए आपको उसकी स्थिति या दिशा समायोजित करने की आवश्यकता हो सकती है. सबसे अच्छे परिणामों के लिए, उसे ऊंचाई पर और किसी खिड़की के पास लगाएं."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"इससे USB ट्यूनर से मिले चैनल निकल जाएंगे और नए चैनलों के लिए फिर से स्कैन किया जाएगा.\n\nपुष्टि करें कि USB ट्यूनर प्लग इन है और टीवी सिग्नल स्रोत से कनेक्ट किया हुआ है.\n\nयदि आप ओवर द एयर एंटेना का उपयोग कर रहे हैं, तो अधिकांश चैनल पाने के लिए आपको उसकी स्थिति या दिशा समायोजित करने की आवश्यकता हो सकती है. अच्छे परिणामों के लिए, उसे ऊंचाई पर और किसी खिड़की के पास लगाएं."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"ऐसा करने से नेटवर्क ट्यूनर से मिले चैनल निकाल दिए जाएंगे और नए चैनल के लिए फिर से स्कैन किया जाएगा.\n\nसत्यापित करें कि नेटवर्क ट्यूनर चालू है और किसी टीवी सिग्नल स्रोत से कनेक्ट है.\n\nयदि किसी ओवर-द-एयर एंटेना का उपयोग कर रहे हैं, तो अधिकांश चैनल प्राप्त करने के लिए आपको एंटेना का स्थान या दिशा समायोजित करनी पड़ सकती है. सर्वश्रेष्ठ परिणामों के लिए, उसे ऊंचाई पर और किसी खिड़की के पास रखें."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"जारी रखें"</item>
<item msgid="235450158666155406">"रद्द करें"</item>
@@ -54,8 +53,9 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"टीवी ट्यूनर सेटअप"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB चैनल ट्यूनर सेटअप"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"नेटवर्क चैनल ट्यूनर सेटअप"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"इसमें कुछ मिनट लग सकते हैं"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ट्यूनर अस्थायी रूप से उपलब्ध नहीं है या रिकॉर्डिंग में उसका उपयोग पहले ही कर लिया गया है."</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ट्यूनर अस्थायी रूप से उपलब्ध नहीं है या रिकॉर्डिंग में उसका उपयोग पहले ही हो रहा है."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
<item quantity="one">%1$d चैनल मिले</item>
<item quantity="other">%1$d चैनल मिले</item>
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"कोई चैनल नहीं मिला"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"स्कैन करने से कोई भी चैनल नहीं मिला. पुष्टि करें कि आपका टीवी किसी टीवी सिग्नल स्रोत से कनेक्ट किया हुआ है.\n\nयदि ओवर द एयर एंटेना का उपयोग कर रहे हैं, तो उसकी स्थिति या दिशा समायोजित करें. सबसे अच्छे परिणामों के लिए, उसे ऊंचाई पर और किसी खिड़की के पास लगाएं और दोबारा स्कैन करें."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"स्कैन करने से कोई चैनल नहीं मिला. पुष्टि करें कि USB ट्यूनर प्लग इन है और टीवी सिग्नल स्रोत से कनेक्ट किया हुआ है.\n\nयदि आप ओवर द एयर एंटेना का उपयोग कर रहे हैं, तो उसकी स्थिति या दिशा समायोजित करें. अच्छे परिणामों के लिए, उसे ऊंचाई पर और किसी खिड़की के पास लगाएं और दोबारा स्कैन करें."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"स्कैन में कोई चैनल नहीं मिला. सत्यापित करें कि नेटवर्क ट्यूनर चालू है और किसी टीवी संकेत स्रोत से कनेक्ट है.\n\nयदि किसी ओवर-द-एयर एंटेना का उपयोग कर रहे हैं, तो उसका स्थान या दिशा समायोजित करें. सर्वश्रेष्ठ परिणामों के लिए, उसे ऊंचाई पर और किसी खिड़की के पास रखें और फिर से स्कैन करें."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"दोबारा स्‍कैन करें"</item>
<item msgid="2092797862490235174">"हो गया"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"टीवी चैनलों के लिए स्‍कैन करें"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"टीवी ट्यूनर सेटअप"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB टीवी ट्यूनर सेटअप"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB टीवी ट्यूनर डिस्कनेक्ट किया गया."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"टीवी चैनलों के लिए स्‍कैन करें"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"टीवी ट्यूनर सेटअप"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB टीवी ट्यूनर सेटअप"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"नेटवर्क टीवी ट्यूनर सेटअप"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB टीवी ट्यूनर डिसकनेक्ट किया गया."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"नेटवर्क ट्यूनर डिसकनेक्ट किया गया."</string>
</resources>
diff --git a/usbtuner-res/values-hr/strings.xml b/usbtuner-res/values-hr/strings.xml
index 4a00deaf..42f5c3aa 100644
--- a/usbtuner-res/values-hr/strings.xml
+++ b/usbtuner-res/values-hr/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV prijemnik"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB TV prijemnik"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Uključeno"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Isključeno"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Mrežni TV prijemnik (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Pričekajte da obrada završi"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Odaberite izvor kanala"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Nema signala"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Namještanje na kanal <xliff:g id="CHANNEL_NAME">%s</xliff:g> nije uspjelo"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Namještanje nije uspjelo"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Softver prijemnika nedavno je ažuriran. Ponovite traženje kanala."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Omogućite okružujući zvuk u postavkama zvuka na razini sustava da biste omogućili audio"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Zvuk se ne može reproducirati. Pokušajte s drugim televizorom"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Postavljanje prijemnika kanala"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Postavljanje TV prijemnika"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Postavljanje USB prijemnika za kanale"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Postavljanje mrežnog prijemnika"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Provjerite je li televizor povezan s izvorom televizijskog signala.\n\nAko upotrebljavate antenu zemaljske televizije, možda ćete joj morati promijeniti položaj ili smjer da biste pronašli najviše kanala. Za najbolje rezultate postavite je visoko i u blizini prozora."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Provjerite je li USB prijemnik priključen i povezan s izvorom TV signala.\n\nAko upotrebljavate antenu zemaljske televizije, možda trebate prilagoditi njezin položaj ili smjer da biste primali najviše kanala. Za najbolje rezultate postavite je visoko i u blizini prozora."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Provjerite je li mrežni prijemnik uključen i povezan s izvorom TV signala.\n\nAko upotrebljavate bežičnu antenu, možda ćete trebati prilagoditi položaj ili smjer da biste pronašli najviše kanala. Za najbolje rezultate postavite je visoko i blizu prozora."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Nastavi"</item>
<item msgid="727245208787621142">"Ne sada"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Želite li ponovo pokrenuti postavljanje kanala?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Time će se ukloniti kanali pronađeni pomoću TV prijemnika i ponovo pokrenuti pretraživanje kanala.\n\nProvjerite je li televizor povezan s izvorom televizijskog signala.\n\nAko upotrebljavate antenu zemaljske televizije, možda ćete joj morati promijeniti položaj ili smjer da biste pronašli najviše kanala. Za najbolje rezultate postavite je visoko i u blizini prozora."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Time će se ukloniti kanali pronađeni putem USB prijemnika i ponoviti pretraživanje kanala.\n\nProvjerite je li USB prijemnik priključen i povezan s izvorom televizijskog signala.\n\nAko upotrebljavate antenu zemaljske televizije, možda trebate prilagoditi njezin položaj ili smjer da biste primali najviše kanala. Za najbolje rezultate postavite je visoko i u blizini prozora."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Time će se ukloniti kanali pronađeni mrežnim prijemnikom i pokrenuti pretraživanje novih kanala.\n\nProvjerite je li mrežni prijemnik uključen i povezan s izvorom TV signala.\n\nAko upotrebljavate bežičnu antenu, možda ćete trebati prilagoditi položaj ili smjer da biste pronašli najviše kanala. Za najbolje rezultate postavite je visoko i blizu prozora."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Nastavi"</item>
<item msgid="235450158666155406">"Odustani"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Postavljanje TV prijemnika"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Postavljanje USB prijemnika za kanale"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Postavljanje prijemnika za mrežne kanale"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"To može potrajati nekoliko minuta"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Prijemnik trenutačno nije dostupan ili se već upotrebljava za snimanje."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -79,12 +79,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Nije pronađen nijedan kanal"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Tijekom pretraživanja nije pronađen nijedan kanal. Provjerite je li televizor povezan s izvorom televizijskog signala.\n\nAko upotrebljavate antenu zemaljske televizije, promijenite joj položaj ili smjer. Za najbolje rezultate postavite je visoko i u blizini prozora, a zatim pretražite ponovo."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Pretraživanjem nije pronađen nijedan kanal. Provjerite je li USB prijemnik priključen i povezan s izvorom televizijskog signala.\n\nAko upotrebljavate antenu zemaljske televizije, prilagodite joj položaj ili smjer. Za najbolje rezultate postavite je visoko i u blizini prozora i pretražite ponovo."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Nije pronađen nijedan kanal. Provjerite je li mrežni prijemnik uključen i povezan s izvorom TV signala.\n\nAko upotrebljavate bežičnu antenu, prilagodite položaj ili smjer. Za najbolje rezultate postavite je visoko i blizu prozora i pretražite ponovo."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Pretraži ponovo"</item>
<item msgid="2092797862490235174">"Gotovo"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Pretražite TV kanale"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Postavljanje TV prijemnika"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Postavljanje USB TV prijemnika"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV prijemnik isključen."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Pretražite TV kanale"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Postavljanje TV prijemnika"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Postavljanje USB TV prijemnika"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Postavljanje mrežnog TV prijemnika"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV prijemnik isključen."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Mrežni prijemnik isključen."</string>
</resources>
diff --git a/usbtuner-res/values-hu/strings.xml b/usbtuner-res/values-hu/strings.xml
index e2bca51c..0d83fe31 100644
--- a/usbtuner-res/values-hu/strings.xml
+++ b/usbtuner-res/values-hu/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Tévétuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB-s tévétuner"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Be"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Ki"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Hálózati tévétuner (BÉTA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Kérjük, várja meg a folyamat befejezését"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Válassza ki a csatornaforrást"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Nincs jel"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Nem sikerült behangolni a(z) <xliff:g id="CHANNEL_NAME">%s</xliff:g> csatornát"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Nem sikerült a hangolás"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"A tuner szoftverét nemrég frissítették. Kérjük, ismételje meg a csatornakeresést."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"A hang aktiválásához engedélyezze a térhatású hangot a rendszerszintű hangbeállításokban"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"A hangot nem lehet lejátszani. Kérjük, próbálkozzon másik tévén"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Csatornatuner beállítása"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Tévétuner beállítása"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB-s csatornatuner beállítása"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Hálózati tuner beállítása"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Ellenőrizze, hogy tévéje csatlakoztatva van-e a televíziós jelforráshoz.\n\nAntenna használata esetén szükség lehet az elhelyezés, illetve az irány módosítására a lehető legtöbb csatorna befogásához. A legjobb eredmény érdekében helyezze magasra és ablak közelébe."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Győződjön meg arról, hogy az USB-tuner be van dugva, és csatlakoztatva van a televíziós jelforráshoz.\n\nAntenna használata esetén szükség lehet az elhelyezés, illetve irány módosítására a lehető legtöbb csatorna befogásához. A legjobb eredmény érdekében helyezze magasra és ablak közelébe."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Ellenőrizze, hogy a hálózati tuner be van-e kapcsolva, és csatlakozik-e televíziós jelforráshoz.\n\nHa antennát használ, módosítsa az elhelyezkedését, illetve irányát, hogy minél több csatornát fogjon. A legjobb eredmény érdekében helyezze magasra és ablak közelébe."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Folytatás"</item>
<item msgid="727245208787621142">"Most nem"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Újra végrehajtja a csatornabeállítást?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Ezzel eltávolítja a tévétuner segítségével megtalált csatornákat, és új csatornakeresést indít.\n\nEllenőrizze, hogy tévéje csatlakoztatva van-e a televíziós jelforráshoz.\n\nAntenna használata esetén szükség lehet az elhelyezés, illetve az irány módosítására a lehető legtöbb csatorna befogásához. A legjobb eredmény érdekében helyezze magasra és ablak közelébe."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Ezzel eltávolítja a már megtalált csatornákat az USB-tunerről, és újból elvégzi a csatornakeresést.\n\nGyőződjön meg arról, hogy az USB-tuner be van dugva, és csatlakoztatva van a televíziós jelforráshoz.\n\nAntenna használata esetén szükség lehet az elhelyezés, illetve irány módosítására a lehető legtöbb csatorna befogásához. A legjobb eredmény érdekében helyezze magasra és ablak közelébe."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Ezzel eltávolítja a hálózati tuner által talált csatornákat, és újabb csatornakeresést indít el.\n\nEllenőrizze, hogy a hálózati tuner be van-e kapcsolva, és csatlakozik-e televíziós jelforráshoz.\n\nHa antennát használ, módosítsa az elhelyezkedését, illetve irányát, hogy minél több csatornát fogjon. A legjobb eredmény érdekében helyezze magasra és ablak közelébe."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Folytatás"</item>
<item msgid="235450158666155406">"Mégse"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Tévétuner beállítása"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB-s csatornatuner beállítása"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Hálózati csatornatuner beállítása"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Ez néhány percet is igénybe vehet"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"A tuner átmenetileg nem áll rendelkezésre, vagy már fel lett használva a felvétel során."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Nem található csatorna"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"A keresés nem talált csatornát. Ellenőrizze, hogy tévéje csatlakoztatva van-e a televíziós jelforráshoz.\n\nAntenna használata esetén módosítsa annak elhelyezését, illetve irányát. A legjobb eredmény érdekében helyezze magasra és ablak közelébe, majd ismételje meg a keresést."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"A keresés nem talált csatornát. Győződjön meg arról, hogy az USB-tuner be van dugva, és csatlakoztatva van a televíziós jelforráshoz.\n\nHa antennát használ, állítson annak helyzetén, illetve irányán. A legjobb eredmény érdekében helyezze magasra és ablak közelébe, majd ismételje meg a keresést."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"A rendszer nem talált egyetlen csatornát sem. Ellenőrizze, hogy a hálózati tuner be van-e kapcsolva, és csatlakozik-e televíziós jelforráshoz.\n\nHa antennát használ, módosítsa az elhelyezkedését, illetve irányát. A legjobb eredmény érdekében helyezze magasra és ablak közelébe, majd ismételje meg a keresést."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Keresés újra"</item>
<item msgid="2092797862490235174">"Kész"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Tévécsatornák keresése"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Tévétuner beállítása"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB-s tévétuner beállítása"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Megszakadt a kapcsolat az USB-s tévétunerrel."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Tévécsatornák keresése"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Tévétuner beállítása"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB-s tévétuner beállítása"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Hálózati tévétuner beállítása"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Megszakadt a kapcsolat az USB-s tévétunerrel."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Megszakadt a kapcsolat a hálózati tunerrel."</string>
</resources>
diff --git a/usbtuner-res/values-hy-rAM/strings.xml b/usbtuner-res/values-hy-rAM/strings.xml
new file mode 100644
index 00000000..2d3080c1
--- /dev/null
+++ b/usbtuner-res/values-hy-rAM/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"Հեռուստակարգավորիչ"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB հեռուստակարգավորիչ"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Ցանցային հեռուստաընդունիչ (ԲԵՏԱ)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Սպասեք՝ մինչ որոնումը ավարտվի"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Ընդունիչի ծրագրակազմը վերջերս թարմացվել է: Նորից որոնեք ալիքները:"</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Ձայնը միացնելու համար համակարգի ձայնի կարգավորումներում ակտիվացրեք ծավալային ձայնը"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Հնարավոր չէ վերարտադրել ձայնը: Փորձեք մեկ այլ հեռուստացույց:"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Ալիքների կարգավորիչի տեղադրում"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"Հեռուստակարգավորիչի տեղադրում"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"Ալիքների USB կարգավորիչի տեղադրում"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Ցանցային ընդունիչի կարգավորում"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Համոզվեք, որ հեռուստացույցը միացված է հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս հնարավոր է՝ անհրաժեշտ լինի կարգավորել դրա դիրքն ու ուղղությունը՝ ավելի շատ ալիքներ գտնելու համար: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ:"</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"Համոզվեք, որ USB կարգավորիչը միացված է ցանցին և հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս հնարավոր է՝ անհրաժեշտ լինի կարգավորել դրա դիրքն ու ուղղությունը՝ ավելի շատ ալիքներ գտնելու համար: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ:"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Համոզվեք, որ ցանցային ընդունիրչը միացված է և կապակցված հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս հնարավոր է՝ անհրաժեշտ լինի կարգավորել դրա դիրքն ու ուղղությունը՝ ավելի շատ ալիքներ գտնելու համար: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ:"</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Շարունակել"</item>
+ <item msgid="727245208787621142">"Ոչ հիմա"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Կրկի՞ն կարգավորել ալիքները:"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Այս գործողության արդյունքում կհեռացվեն հեռուստակարգավորիչից ստացված ալիքները և կկատարվի ալիքների նոր որոնում:\n\nՀամոզվեք, որ հեռուստացույցը միացված է հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս հնարավոր է՝ անհրաժեշտ լինի կարգավորել դրա դիրքն ու ուղղությունը՝ ավելի շատ ալիքներ գտնելու համար: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ:"</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"Այս գործողության արդյունքում կհեռացվեն USB կարգավորիչից ստացված ալիքները և կկատարվի ալիքների նոր որոնում:\n\nՀամոզվեք, որ USB կարգավորիչը միացված է ցանցին և հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս հնարավոր է՝ անհրաժեշտ լինի կարգավորել դրա դիրքն ու ուղղությունը՝ ավելի շատ ալիքներ գտնելու համար: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ:"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Այս գործողության արդյունքում կհեռացվեն ցանցային ընդունիչից ստացված ալիքները և կկատարվի ալիքների նոր որոնում:\n\nՀամոզվեք, որ ցանցային ընդունիչը միացված է և կապակցված հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս հնարավոր է՝ անհրաժեշտ լինի կարգավորել դրա դիրքն ու ուղղությունը՝ ավելի շատ ալիքներ գտնելու համար: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ:"</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Շարունակել"</item>
+ <item msgid="235450158666155406">"Չեղարկել"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Ընտրեք միացման տեսակը"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Եթե ընդունիչին միացված է արտաքին ալեհավաք, ապա ընտրեք Ալեհավաքը: Եթե ալիքների ազդանշանը ստանում եք մալուխային հեռուստաընկերությունից, ապա ընտրեք Մալուխը: Եթե համոզված չեք, ապա կարող եք որոնել երկու տեսակն էլ, սակայն դա ավելի երկար կտևի:"</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Ալեհավաք"</item>
+ <item msgid="2670079958754180142">"Մալուխ"</item>
+ <item msgid="36774059871728525">"Չգիտեմ"</item>
+ <item msgid="6881204453182153978">"Միայն մշակման"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"Հեռուստակարգավորիչի տեղադրում"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"Ալիքների USB կարգավորիչի տեղադրում"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Ցանցային ալիքների ընդունիչի տեղադրում"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Դա կարող է տևել մի քանի րոպե"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Ընդունիչը ժամանակավորապես անհասանելի է կամ արդեն օգտագործվում է տեսագրելու համար:"</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="one">%1$d channels found</item>
+ <item quantity="other">Գտնվել է %1$d ալիք</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"ԴԱԴԱՐԵՑՆԵԼ ԱԼԻՔՆԵՐԻ ՈՐՈՆՈՒՄԸ"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="one">%1$d channels found</item>
+ <item quantity="other">Գտնվել է %1$d ալիք</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="one">Nice! %1$d channels were found during the channel scan. If this doesn’t seem right, try adjusting the antenna position and scan again.</item>
+ <item quantity="other">Գերազանց է: Ալիքների որոնման արդյունքում գտնվել է %1$d ալիք: Եթե դա բավարար չէ, փորձեք փոխել ալեհավաքի դիրքը և որոնել նորից:</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Պատրաստ է"</item>
+ <item msgid="2480490326672924828">"Կրկին որոնել"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Ալիքներ չեն գտնվել"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Որոնման արդյունքում ալիքներ չեն գտնվել: Համոզվեք, որ հեռուստացույցը միացված է հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս կարգավորեք դրա դիրքն ու ուղղությունը: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ, ապա որոնեք նորից:"</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Որոնման արդյունքում ալիքներ չեն գտնվել: Համոզվեք, որ USB կարգավորիչը միացված է ցանցին և հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս կարգավորեք դրա դիրքն ու ուղղությունը: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ, ապա որոնեք նորից:"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Որոնման արդյունքում ալիքներ չեն գտնվել: Համոզվեք, որ ցանցային ընդունիչը միացված է և կապակցված հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս կարգավորեք դրա դիրքն ու ուղղությունը: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ, ապա որոնեք նորից:"</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Կրկին որոնել"</item>
+ <item msgid="2092797862490235174">"Պատրաստ է"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"TV ալիքների որոնում"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV ընդունիչի տեղադրում"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV ընդունիչի տեղադրում"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Ցանցային TV ընդունիչի տեղադրում"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB հեռուստաընդունիչն անջատված է:"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Ցանցային ընդունիչն անջատված է։"</string>
+</resources>
diff --git a/usbtuner-res/values-hy/strings.xml b/usbtuner-res/values-hy/strings.xml
deleted file mode 100644
index a8e33eac..00000000
--- a/usbtuner-res/values-hy/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"Հեռուստակարգավորիչ"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB հեռուստակարգավորիչ"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Միացնել"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Անջատել"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Սպասեք՝ մինչ որոնումը ավարտվի"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Ընտրեք ալիքի աղբյուրը"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Ազդանշան չկա"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Չհաջողվեց անցնել <xliff:g id="CHANNEL_NAME">%s</xliff:g> ալիքին"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Չհաջողվեց անցնել ալիքին"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Ընդունիչի ծրագրակազմը վերջերս թարմացվել է: Նորից որոնեք ալիքները:"</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Ձայնը միացնելու համար համակարգի ձայնի կարգավորումներում ակտիվացրեք ծավալային ձայնը"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Ալիքների կարգավորիչի տեղադրում"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"Հեռուստակարգավորիչի տեղադրում"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"Ալիքների USB կարգավորիչի տեղադրում"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Համոզվեք, որ հեռուստացույցը միացված է հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս հնարավոր է՝ անհրաժեշտ լինի կարգավորել դրա դիրքն ու ուղղությունը՝ ավելի շատ ալիքներ գտնելու համար: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ:"</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"Համոզվեք, որ USB կարգավորիչը միացված է ցանցին և հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս հնարավոր է՝ անհրաժեշտ լինի կարգավորել դրա դիրքն ու ուղղությունը՝ ավելի շատ ալիքներ գտնելու համար: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ:"</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Շարունակել"</item>
- <item msgid="727245208787621142">"Ոչ հիմա"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Կրկի՞ն կարգավորել ալիքները:"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Այս գործողության արդյունքում կհեռացվեն հեռուստակարգավորիչից ստացված ալիքները և կկատարվի ալիքների նոր որոնում:\n\nՀամոզվեք, որ հեռուստացույցը միացված է հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս հնարավոր է՝ անհրաժեշտ լինի կարգավորել դրա դիրքն ու ուղղությունը՝ ավելի շատ ալիքներ գտնելու համար: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ:"</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"Այս գործողության արդյունքում կհեռացվեն USB կարգավորիչից ստացված ալիքները և կկատարվի ալիքների նոր որոնում:\n\nՀամոզվեք, որ USB կարգավորիչը միացված է ցանցին և հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս հնարավոր է՝ անհրաժեշտ լինի կարգավորել դրա դիրքն ու ուղղությունը՝ ավելի շատ ալիքներ գտնելու համար: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ:"</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Շարունակել"</item>
- <item msgid="235450158666155406">"Չեղարկել"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Ընտրեք միացման տեսակը"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Եթե ընդունիչին միացված է արտաքին ալեհավաք, ապա ընտրեք Ալեհավաքը: Եթե ալիքների ազդանշանը ստանում եք մալուխային հեռուստաընկերությունից, ապա ընտրեք Մալուխը: Եթե համոզված չեք, ապա կարող եք որոնել երկու տեսակն էլ, սակայն դա ավելի երկար կտևի:"</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Ալեհավաք"</item>
- <item msgid="2670079958754180142">"Մալուխ"</item>
- <item msgid="36774059871728525">"Չգիտեմ"</item>
- <item msgid="6881204453182153978">"Միայն մշակման"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"Հեռուստակարգավորիչի տեղադրում"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"Ալիքների USB կարգավորիչի տեղադրում"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Դա կարող է տևել մի քանի րոպե"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Ընդունիչը ժամանակավորապես անհասանելի է կամ արդեն օգտագործվում է տեսագրելու համար:"</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="one">%1$d channels found</item>
- <item quantity="other">Գտնվել է %1$d ալիք</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"ԴԱԴԱՐԵՑՆԵԼ ԱԼԻՔՆԵՐԻ ՈՐՈՆՈՒՄԸ"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="one">%1$d channels found</item>
- <item quantity="other">Գտնվել է %1$d ալիք</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="one">Nice! %1$d channels were found during the channel scan. If this doesn’t seem right, try adjusting the antenna position and scan again.</item>
- <item quantity="other">Գերազանց է: Ալիքների որոնման արդյունքում գտնվել է %1$d ալիք: Եթե դա բավարար չէ, փորձեք փոխել ալեհավաքի դիրքը և որոնել նորից:</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Պատրաստ է"</item>
- <item msgid="2480490326672924828">"Կրկին որոնել"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Ալիքներ չեն գտնվել"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Որոնման արդյունքում ալիքներ չեն գտնվել: Համոզվեք, որ հեռուստացույցը միացված է հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս կարգավորեք դրա դիրքն ու ուղղությունը: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ, ապա որոնեք նորից:"</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Որոնման արդյունքում ալիքներ չեն գտնվել: Համոզվեք, որ USB կարգավորիչը միացված է ցանցին և հեռուստատեսային ազդանշանի աղբյուրին:\n\nԵթերային ալեհավաք օգտագործելիս կարգավորեք դրա դիրքն ու ուղղությունը: Լավագույն արդյունքներն ապահովելու համար այն դրեք բարձր տեղում՝ պատուհանի մոտ, ապա որոնեք նորից:"</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Կրկին որոնել"</item>
- <item msgid="2092797862490235174">"Պատրաստ է"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Հեռուստաալիքների որոնում"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Հեռուստակարգավորիչի տեղադրում"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB հեռուստակարգավորիչի տեղադրում"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB հեռուստակարգավորիչն անջատված է:"</string>
-</resources>
diff --git a/usbtuner-res/values-in/strings.xml b/usbtuner-res/values-in/strings.xml
index e534c9c6..8f3aa4d1 100644
--- a/usbtuner-res/values-in/strings.xml
+++ b/usbtuner-res/values-in/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Tuner TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Tuner TV USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Aktif"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Nonaktif"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Tuner TV Jaringan (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Harap tunggu sampai pemrosesan selesai"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Pilih sumber saluran Anda"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Tidak Ada Sinyal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Gagal menyetel ke <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Gagal menyetel"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Perangkat lunak tuner ini baru saja diperbarui. Pindai ulang saluran Anda."</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Software tuner ini baru saja diperbarui. Pindai ulang saluran Anda."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Aktifkan suara surround di setelan suara sistem untuk mengaktifkan audio"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Tidak dapat memutar audio. Coba TV lainnya"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Penyiapan penyetel saluran"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Penyiapan Tuner TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Penyiapan tuner saluran USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Penyiapan tuner jaringan"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Pastikan TV terhubung ke sumber sinyal TV.\n\nJika menggunakan antena udara, Anda mungkin perlu menyesuaikan tempat atau arahnya untuk menerima sebagian besar saluran. Untuk hasil terbaik, tempatkan di lokasi yang tinggi dan dekat dengan jendela."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Pastikan tuner USB dicolokkan dan tersambung ke sumber sinyal TV.\n\nJika menggunakan antena udara, Anda mungkin perlu menyesuaikan tempat atau arahnya untuk menerima jumlah saluran paling banyak. Untuk hasil terbaik, letakkan di tempat yang tinggi dan dekat jendela."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Pastikan tuner jaringan aktif dan terhubung ke sumber sinyal TV.\n\nJika menggunakan antena udara, Anda mungkin perlu menyesuaikan tempat dan arahnya agar dapat menerima sebagian besar saluran. Untuk hasil terbaik, tempatkan antena di lokasi yang tinggi dan dekat jendela."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Lanjutkan"</item>
<item msgid="727245208787621142">"Jangan sekarang"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Jalankan lagi penyiapan saluran?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Tindakan ini akan menghapus saluran yang ditemukan dari tuner TV dan memindai saluran baru lagi.\n\nPastikan TV terhubung ke sumber sinyal TV.\n\nJika menggunakan antena udara, mungkin Anda perlu menyesuaikan tempat atau arahnya untuk menerima sebagian besar saluran. Untuk hasil terbaik, tempatkan di lokasi yang tinggi dan dekat dengan jendela."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Tindakan ini akan menghapus saluran yang ditemukan dari tuner USB dan memindai saluran baru lagi.\n\nPastikan tuner USB dicolokkan dan tersambung ke sumber sinyal TV.\n\nJika menggunakan antena udara, Anda mungkin perlu menyesuaikan tempat atau arahnya untuk menerima jumlah saluran paling banyak. Untuk hasil terbaik, letakkan di tempat yang tinggi dan dekat jendela."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Hal ini akan menghapus saluran yang ditemukan dari tuner jaringan dan memindai saluran baru lagi.\n\nPastikan tuner jaringan aktif dan terhubung ke sumber sinyal TV.\n\nJika menggunakan antena udara, Anda mungkin perlu menyesuaikan penempatan atau arahnya agar dapat menerima sebagian besar saluran. Untuk hasil terbaik, tempatkan antena di lokasi yang tinggi dan dekat dengan jendela."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Lanjutkan"</item>
<item msgid="235450158666155406">"Batal"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Penyiapan tuner TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Penyiapan tuner saluran USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Penyiapan tuner saluran jaringan"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Proses ini dapat memakan waktu beberapa menit"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuner sementara tidak tersedia atau sudah digunakan oleh rekaman."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Tidak ditemukan Saluran"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Pemindaian tidak menemukan saluran apa pun. Pastikan TV terhubung ke sumber sinyal TV.\n\nJika menggunakan antena udara, sesuaikan tempat atau arahnya. Untuk hasil terbaik, tempatkan di lokasi yang tinggi dan dekat dengan jendela kemudian pindai lagi."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Pemindaian tidak menemukan saluran apa pun. Pastikan tuner USB dicolokkan dan tersambung ke sumber sinyal TV.\n\nJika menggunakan antena udara, sesuaikan tempat atau arahnya. Untuk hasil terbaik, letakkan di tempat yang tinggi dan dekat jendela lalu pindai lagi."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Tidak menemukan saluran apa pun saat memindai. Pastikan tuner jaringan aktif dan terhubung ke sumber sinyal TV.\n\nJika Anda menggunakan antena udara, sesuaikan penempatan atau arahnya. Untuk hasil terbaik, tempatkan di lokasi yang tinggi dan dekat jendela, lalu pindai lagi."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Pindai lagi"</item>
<item msgid="2092797862490235174">"Selesai"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Pindai saluran TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Penyiapan Tuner TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Penyiapan Tuner TV USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Koneksi tuner TV USB terputus."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Pindai saluran TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Penyiapan Tuner TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Penyiapan Tuner TV USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Penyiapan Tuner TV Jaringan"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Koneksi tuner TV USB terputus."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Koneksi tuner jaringan terputus."</string>
</resources>
diff --git a/usbtuner-res/values-is-rIS/strings.xml b/usbtuner-res/values-is-rIS/strings.xml
new file mode 100644
index 00000000..fa1e85c7
--- /dev/null
+++ b/usbtuner-res/values-is-rIS/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"Sjónvarpsmóttakari"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB-sjónvarpsmóttakari"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Netsjónvarpsmóttakari (TILRAUNAÚTGÁFA)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Bíddu þar til vinnslu lýkur"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Hugbúnaður sjónvarpsmóttakarans var uppfærður nýlega. Leitaðu aftur að rásum."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Kveikja á víðómastillingu í hljóðstillingum kerfisins til að kveikja á hljóði"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Ekki er hægt að spila hljóð. Prófaðu annað sjónvarp"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Uppsetning sjónvarpskorts"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"Uppsetning sjónvarpsmóttakara"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"Uppsetning USB-sjónvarpsrásakorts"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Uppsetning netsjónvarpsmóttakara"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Gakktu úr skugga um að sjónvarpið sé tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"Gakktu úr skugga um að USB-sjónvarpskortið sé í sambandi og tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt til að ná fleiri rásum. Best er að hafa það hátt uppi og nálægt glugga."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Gakktu úr skugga um að kveikt sé á netsjónvarpsmóttakaranum og að hann sé tengdur við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Halda áfram"</item>
+ <item msgid="727245208787621142">"Ekki núna"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Viltu keyra rásauppsetningu aftur?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Þetta fjarlægir stöðvar sem sjónvarpsmóttakarinn fann og leitar aftur að nýjum stöðvum.\n\nGakktu úr skugga um að sjónvarpið sé tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"Þetta fjarlægir rásir sem skráðar eru á USB-sjónvarpskortinu og leitar að nýjum stöðvum.\n\nGakktu úr skugga um að USB-sjónvarpskortið sé í sambandi og tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt til að ná fleiri rásum. Best er að hafa það hátt uppi og nálægt glugga."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Þetta fjarlægir rásirnar sem sjónvarpsmóttakarinn þinn fann og leitar aftur að nýjum rásum.\n\nGakktu úr skugga um að kveikt sé á netsjónvarpsmóttakaranum og að hann sé tengdur við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Halda áfram"</item>
+ <item msgid="235450158666155406">"Hætta við"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Veldu tengigerðina"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Veldu „Loftnet“ ef utanáliggjandi loftnet er tengt við sjónvarpskortið. Veldu „Kapall“ ef rásirnar berast þér í gegnum kapal. Ef þú ert ekki viss verður leitað að báðum gerðum og það kann að taka lengri tíma."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Loftnet"</item>
+ <item msgid="2670079958754180142">"Kapall"</item>
+ <item msgid="36774059871728525">"Ekki viss"</item>
+ <item msgid="6881204453182153978">"Aðeins þróunaraðilar"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"Uppsetning sjónvarpsmóttakara"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"Uppsetning USB-sjónvarpsrásakorts"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Uppsetning netsjónvarpsmóttakara"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Þetta getur tekið nokkrar mínútur"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Móttakari er tímabundið ekki í boði eða er þegar að taka upp."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="one">%1$d rás fannst</item>
+ <item quantity="other">%1$d rásir fundust</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"STÖÐVA RÁSALEIT"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="one">%1$d rás fannst</item>
+ <item quantity="other">%1$d rásir fundust</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="one">Glæsilegt! %1$d rás fannst við leitina. Ef þetta er ekki eins og það á að vera skaltu prófa að stilla loftnetið og leita aftur.</item>
+ <item quantity="other">Glæsilegt! %1$d rásir fundust við leitina. Ef þetta er ekki eins og það á að vera skaltu prófa að stilla loftnetið og leita aftur.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Lokið"</item>
+ <item msgid="2480490326672924828">"Leita aftur"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Engar rásir fundust"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Engar rásir fundust. Gakktu úr skugga um að sjónvarpið sé tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Engar rásir fundust. Gakktu úr skugga um að USB-sjónvarpskortið sé í sambandi og tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Leitin fann engar stöðvar. Gakktu úr skugga um að kveikt sé á netsjónvarpsmóttakaranum og hann sé tengdur við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Leita aftur"</item>
+ <item msgid="2092797862490235174">"Lokið"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Skanna eftir sjónvarpsstöðvum"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Uppsetning sjónvarpsmóttakara"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Uppsetning USB-sjónvarpsmóttakara"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Uppsetning netsjónvarpsmóttakara"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-sjónvarpsmóttakari tekinn úr sambandi."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Netmóttakari tekinn úr sambandi."</string>
+</resources>
diff --git a/usbtuner-res/values-is/strings.xml b/usbtuner-res/values-is/strings.xml
deleted file mode 100644
index f63d9810..00000000
--- a/usbtuner-res/values-is/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"Sjónvarpsmóttakari"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB-sjónvarpsmóttakari"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Kveikja"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Slökkva"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Bíddu þar til vinnslu lýkur"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Veldu inntak rása"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Ekkert merki"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Mistókst að stilla á <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Mistókst að stilla"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Hugbúnaður sjónvarpsmóttakarans var uppfærður nýlega. Leitaðu aftur að rásum."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Kveikja á víðómastillingu í hljóðstillingum kerfisins til að kveikja á hljóði"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Uppsetning sjónvarpskorts"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"Uppsetning sjónvarpsmóttakara"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"Uppsetning USB-sjónvarpsrásakorts"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Gakktu úr skugga um að sjónvarpið sé tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"Gakktu úr skugga um að USB-sjónvarpskortið sé í sambandi og tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt til að ná fleiri rásum. Best er að hafa það hátt uppi og nálægt glugga."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Halda áfram"</item>
- <item msgid="727245208787621142">"Ekki núna"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Viltu keyra rásauppsetningu aftur?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Þetta fjarlægir stöðvar sem sjónvarpsmóttakarinn fann og leitar aftur að nýjum stöðvum.\n\nGakktu úr skugga um að sjónvarpið sé tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"Þetta fjarlægir rásir sem skráðar eru á USB-sjónvarpskortinu og leitar að nýjum stöðvum.\n\nGakktu úr skugga um að USB-sjónvarpskortið sé í sambandi og tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt til að ná fleiri rásum. Best er að hafa það hátt uppi og nálægt glugga."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Halda áfram"</item>
- <item msgid="235450158666155406">"Hætta við"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Veldu tengigerðina"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Veldu „Loftnet“ ef utanáliggjandi loftnet er tengt við sjónvarpskortið. Veldu „Kapall“ ef rásirnar berast þér í gegnum kapal. Ef þú ert ekki viss verður leitað að báðum gerðum og það kann að taka lengri tíma."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Loftnet"</item>
- <item msgid="2670079958754180142">"Kapall"</item>
- <item msgid="36774059871728525">"Ekki viss"</item>
- <item msgid="6881204453182153978">"Aðeins þróunaraðilar"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"Uppsetning sjónvarpsmóttakara"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"Uppsetning USB-sjónvarpsrásakorts"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Þetta getur tekið nokkrar mínútur"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Móttakari er tímabundið ekki í boði eða er þegar að taka upp."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="one">%1$d rás fannst</item>
- <item quantity="other">%1$d rásir fundust</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"STÖÐVA RÁSALEIT"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="one">%1$d rás fannst</item>
- <item quantity="other">%1$d rásir fundust</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="one">Glæsilegt! %1$d rás fannst við leitina. Ef þetta er ekki eins og það á að vera skaltu prófa að stilla loftnetið og leita aftur.</item>
- <item quantity="other">Glæsilegt! %1$d rásir fundust við leitina. Ef þetta er ekki eins og það á að vera skaltu prófa að stilla loftnetið og leita aftur.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Lokið"</item>
- <item msgid="2480490326672924828">"Leita aftur"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Engar rásir fundust"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Engar rásir fundust. Gakktu úr skugga um að sjónvarpið sé tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Engar rásir fundust. Gakktu úr skugga um að USB-sjónvarpskortið sé í sambandi og tengt við sjónvarpstengi.\n\nEf þú ert að nota loftnet skaltu færa það á annan stað eða snúa því í aðra átt. Best er að hafa það hátt uppi og nálægt glugga þegar leitað er."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Leita aftur"</item>
- <item msgid="2092797862490235174">"Lokið"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Skanna eftir sjónvarpsstöðvum"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Uppsetning sjónvarpsmóttakara"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Uppsetning USB-sjónvarpsmóttakara"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB-sjónvarpsmóttakari tekinn úr sambandi."</string>
-</resources>
diff --git a/usbtuner-res/values-it/strings.xml b/usbtuner-res/values-it/strings.xml
index 7787d019..3e15fb24 100644
--- a/usbtuner-res/values-it/strings.xml
+++ b/usbtuner-res/values-it/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Sintonizzatore TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Sintonizzatore TV USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Attiva"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Disattiva"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Network TV Tuner (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Attendi il completamento dell\'elaborazione"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Seleziona la tua fonte canale"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Nessun segnale"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Sintonizzazione su <xliff:g id="CHANNEL_NAME">%s</xliff:g> non riuscita"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Sintonizzazione non riuscita"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Il software del sintonizzatore è stato aggiornato di recente. Esegui nuovamente la scansione dei canali."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Per attivare l\'audio, attiva l\'audio surround nelle impostazioni del sistema"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Impossibile riprodurre l\'audio. Prova con un\'altra TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configurazione del sintonizzatore di canali"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Configurazione del sintonizzatore TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Configurazione del sintonizzatore di canali USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Configurazione del sintonizzatore di rete"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Verifica che la TV sia connessa a un\'origine del segnale TV.\n\nSe utilizzi un\'antenna OTA, regolane la posizione o la direzione per ricevere la maggior parte dei canali. Per ottenere risultati ottimali, posizionala in alto e vicino a una finestra."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Verifica che il sintonizzatore USB sia collegato e connesso a un\'origine del segnale TV.\n\nSe utilizzi un\'antenna OTA, potresti dover regolare la sua posizione o direzione per ricevere la maggior parte dei canali. Per risultati ottimali, posizionala in alto e vicino a una finestra."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Verifica che il sintonizzatore di rete sia acceso e connesso a un\'origine del segnale TV.\n\nSe utilizzi un\'antenna OTA (over-the-air), potresti doverne regolare la posizione o la direzione per ricevere il maggior numero di canali. Per ottenere risultati ottimali, posizionala in alto, vicino a una finestra."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continua"</item>
<item msgid="727245208787621142">"Non ora"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Eseguire nuovamente la configurazione dei canali?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Questa operazione rimuoverà i canali trovati dal sintonizzatore TV ed eseguirà la ricerca di nuovi canali.\n\nVerifica che la TV sia connessa a un\'origine del segnale TV.\n\nSe utilizzi un\'antenna OTA, regolane la posizione o la direzione per ricevere la maggior parte dei canali. Per ottenere risultati ottimali, posizionala in alto e vicino a una finestra."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Questa operazione rimuoverà i canali trovati dal sintonizzatore USB ed eseguirà la ricerca di nuovi canali.\n\nVerifica che il sintonizzatore USB sia collegato e connesso a un\'origine del segnale TV.\n\nSe utilizzi un\'antenna OTA, potresti dover regolare la sua posizione o direzione per ricevere il maggior numero di canali. Per ottenere risultati ottimali, posizionala in alto e vicino a una finestra."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"I canali trovati dal sintonizzatore di rete verranno rimossi e verrà eseguita nuovamente la ricerca di nuovi canali.\n\nVerifica che il sintonizzatore di rete sia acceso e connesso a un\'origine del segnale TV.\n\nSe utilizzi un\'antenna OTA (over-the-air), potresti doverne regolare la posizione o la direzione per ricevere il maggior numero di canali. Per ottenere risultati ottimali, posizionala in alto, vicino a una finestra."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continua"</item>
<item msgid="235450158666155406">"Annulla"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Configurazione del sintonizzatore TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Configurazione del sintonizzatore di canali USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Configurazione del sintonizzatore di canali della rete"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"L\'operazione potrebbe richiedere alcuni minuti"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Il sintonizzatore è temporaneamente non disponibile o già utilizzato dal registratore."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Nessun canale trovato"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Nessun canale trovato durante la ricerca. Verifica che la TV sia connessa a un\'origine del segnale TV.\n\nSe utilizzi un\'antenna OTA, regolane la posizione o la direzione. Per ottenere risultati ottimali, posizionala in alto, vicino a una finestra ed esegui nuovamente la ricerca."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Nessun canale trovato durante la ricerca. Verifica che il sintonizzatore USB sia collegato e connesso a un\'origine del segnale TV.\n\nSe utilizzi un\'antenna OTA (over-the-air), regolane la posizione o la direzione. Per ottenere risultati ottimali, posizionala in alto, vicino a una finestra ed esegui nuovamente la ricerca."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Nessun canale trovato durante la ricerca. Verifica che il sintonizzatore di rete sia acceso e connesso a un\'origine del segnale TV.\n\nSe utilizzi un\'antenna OTA (over-the-air), regolane la posizione o la direzione. Per ottenere risultati ottimali, posizionala in alto, vicino a una finestra ed esegui nuovamente la ricerca."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Cerca di nuovo"</item>
<item msgid="2092797862490235174">"Fine"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Cerca canali TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Configurazione del sintonizzatore TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Configurazione del sintonizzatore TV USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Sintonizzatore TV USB disconnesso."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Cerca canali TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Configurazione del sintonizzatore TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Configurazione del sintonizzatore TV USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Configurazione del sintonizzatore TV di rete"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Sintonizzatore TV USB disconnesso."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Sintonizzatore di rete disconnesso."</string>
</resources>
diff --git a/usbtuner-res/values-iw/strings.xml b/usbtuner-res/values-iw/strings.xml
index 5dab5f15..d30fdac5 100644
--- a/usbtuner-res/values-iw/strings.xml
+++ b/usbtuner-res/values-iw/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"טיונר טלוויזיה"</string>
<string name="ut_app_name" msgid="8557698013780762454">"‏טיונר ה-USB בטלוויזיה"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"מופעל"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"כבוי"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"טיונר טלוויזיה לרשת (ביטא)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"המתן לסיום העיבוד"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"בחר את מקור הערוצים"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"אין אות"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"לא ניתן היה לכוון לערוץ <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"הכוונון נכשל"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"תוכנת הטיונר עודכנה לאחרונה. סרוק מחדש את הערוצים."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"הפעל סראונד בהגדרות צלילי מערכת כדי להפעיל אודיו"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"אין אפשרות להשמיע אודיו. נסה ערוץ טלוויזיה אחר."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"הגדרת טיונר ערוצים"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"הגדרת טיונר טלוויזיה"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"‏הגדרת טיונר ערוצים בחיבור USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"הגדרת מקלט הרשת"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"ודא שהטלוויזיה מחוברת למקור אות טלוויזיה.\n\nאם אתה משתמש באנטנה אלחוטית, ייתכן שיהיה עליך לשנות את המיקום או את הכיוון שלה כדי לקלוט כמה שיותר ערוצים. לקבלת התוצאות הטובות ביותר, הצב אותה במקום גבוה ליד חלון."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"‏ודא שטיונר USB מחובר למקור אות בטלוויזיה. \n\n אם אתה משתמש באנטנה אלחוטית, ייתכן שיהיה עליך לכוון את מיקומה או את כיוונה כדי לקלוט כמה שיותר ערוצים. לתוצאות מיטביות, הצב אותה במקום גבוה ליד חלון וסרוק שוב."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"ודא שמקלט הרשת מופעל ומחובר למקור אות של טלוויזיה.\n\nאם אתה משתמש באנטנה לקליטת שידורים אלחוטיים, ייתכן שיהיה עליך לשנות את המיקום או את הכיוון שלה כדי לקלוט כמה שיותר ערוצים. לקבלת התוצאות הטובות ביותר, הצב אותה במקום גבוה ליד חלון."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"המשך"</item>
<item msgid="727245208787621142">"לא עכשיו"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"האם להפעיל מחדש את הגדרת הערוצים?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"פעולה זו תסיר את הערוצים שנמצאו בטיונר הטלוויזיה ותסרוק שוב ערוצים חדשים.\n\nודא שהטלוויזיה מחוברת למקור אות טלוויזיה.\n\nאם אתה משתמש באנטנה אלחוטית, ייתכן שיהיה עליך לשנות את המיקום או את הכיוון שלה כדי לקלוט כמה שיותר ערוצים. לקבלת התוצאות הטובות ביותר, הצב אותה במקום גבוה ליד חלון."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"‏פעולה זו תסיר את הערוצים שנמצאו מטיונר ה-USB ותתבצע סריקה נוספת לערוצים חדשים.\n\nודא שטיונר USB מחובר למקור אות בטלוויזיה.\n\nאם אתה משתמש באנטנה אלחוטית, ייתכן שיהיה עליך לשנות את מיקומה או את כיוונה כדי לקלוט כמה שיותר ערוצים. לתוצאות מיטביות, הצב אותה במקום גבוה ליד חלון וסרוק שוב."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"הפעולה תסיר את הערוצים שנמצאו ממקלט הרשת ותתבצע שוב סריקה לאיתור ערוצים חדשים.\n\nודא שמקלט הרשת מופעל ומחובר למקור אות של טלוויזיה.\n\nאם אתה משתמש באנטנה לקליטת שידורים אלחוטיים, ייתכן שיהיה עליך לשנות את המיקום או את הכיוון שלה כדי לקלוט כמה שיותר ערוצים. לקבלת התוצאות הטובות ביותר, הצב אותה במקום גבוה ליד חלון."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"המשך"</item>
<item msgid="235450158666155406">"ביטול"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"הגדרת טיונר טלוויזיה"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"‏הגדרת טיונר ערוצים בחיבור USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"הגדרת מקלט ערוצים לרשת"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"פעולה זו עשויה להימשך מספר דקות"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"הטיונר אינו זמין באופן זמני או שהוא כבר נמצא בשימוש של הקלטה."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -82,12 +82,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"לא נמצאו ערוצים"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"בסריקה לא נמצאו ערוצים. ודא שהטלוויזיה מחוברת למקור אות טלוויזיה.\n\nאם אתה משתמש באנטנה אלחוטית, שנה את המיקום או את הכיוון שלה. לקבלת התוצאות הטובות ביותר, הצב אותה במקום גבוה ליד חלון וסרוק שוב."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"‏לא נמצאו ערוצים בסריקה. ודא שטיונר USB מחובר למקור אות בטלוויזיה. \n\n אם אתה משתמש באנטנה אלחוטית, שנה את מיקומה או את כיוונה. לתוצאות מיטביות, הצב אותה במקום גבוה ליד חלון וסרוק שוב."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"בסריקה לא נמצאו ערוצים. ודא שמקלט הרשת מופעל ומחובר למקור אות של טלוויזיה.\n\nאם אתה משתמש באנטנה לקליטת שידורים אלחוטיים, שנה את המיקום או את הכיוון שלה. לקבלת התוצאות הטובות ביותר, הצב אותה במקום גבוה ליד חלון וסרוק שוב."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"סרוק שוב"</item>
<item msgid="2092797862490235174">"סיום"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"סריקה לאיתור ערוצי טלוויזיה"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"הגדרת טיונר טלוויזיה"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"‏הגדרת טיונר ה-USB בטלוויזיה"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"‏טיונר ה-USB שבטלוויזיה מנותק."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"סריקה לאיתור ערוצי טלוויזיה"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"הגדרה של טיונר טלוויזיה"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"‏הגדרה של טיונר USB בטלוויזיה"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"הגדרה של טיונר טלוויזיה לרשת"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"‏טיונר ה-USB שבטלוויזיה מנותק."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"טיונר הרשת מנותק."</string>
</resources>
diff --git a/usbtuner-res/values-ja/strings.xml b/usbtuner-res/values-ja/strings.xml
index 88af255a..53223b41 100644
--- a/usbtuner-res/values-ja/strings.xml
+++ b/usbtuner-res/values-ja/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"テレビ チューナー"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB テレビ チューナー"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"ON"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"OFF"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"ネットワーク テレビ チューナー(ベータ版)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"処理が完了するまでこのままお待ちください"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"チャンネル ソースを選択してください"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"信号がありません"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"「<xliff:g id="CHANNEL_NAME">%s</xliff:g>」に合わせることができませんでした"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"合わせることができませんでした"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"最近チューナー ソフトウェアが更新されています。チャンネルをもう一度スキャンしてください。"</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"音声を有効にするには、システムのサウンド設定でサラウンド サウンドをオンにしてください"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"音声を再生できません。別のテレビをお試しください"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"チャンネル チューナーのセットアップ"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"テレビ チューナーのセットアップ"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB チャンネル チューナーのセットアップ"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"ネットワーク チューナーのセットアップ"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"テレビがテレビの信号源に接続されていることを確認してください。\n\n無線アンテナを使用している場合は、チャンネルの多くを受信するためにアンテナの場所や方向の調節が必要になる場合があります。最良の結果を得るには、アンテナを窓際の高い位置に設置します。"</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"USB チューナーが電源に接続され、テレビの信号源に接続されていることを確認してください。\n\n無線アンテナを使用している場合は、チャンネルの多くを受信するためにアンテナの場所や方向の調節が必要になる場合があります。最良の結果を得るには、アンテナを窓際の高い位置に設置します。"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"ネットワーク チューナーの電源がオンになっていて、テレビの信号源に接続されていることを確認してください。\n\n無線アンテナを使用している場合は、チャンネルの多くを受信するためにアンテナの場所や方向の調節が必要になる場合があります。最良の結果を得るには、アンテナを窓際の高い位置に設置します。"</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"次へ"</item>
<item msgid="727245208787621142">"後で"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"もう一度チャンネルを設定しますか?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"テレビ チューナーで見つかったチャンネルを削除して新しいチャンネルをもう一度スキャンします。\n\nテレビがテレビの信号源に接続されていることを確認してください。\n\n無線アンテナを使用している場合は、チャンネルの多くを受信するためにアンテナの場所や方向の調節が必要になる場合があります。最良の結果を得るには、アンテナを窓際の高い位置に設置します。"</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"USB チューナーで見つかったチャンネルを削除して新しいチャンネルをもう一度スキャンします。\n\nUSB チューナーが電源に接続され、テレビの信号源に接続されていることを確認してください。\n\n無線アンテナを使用している場合は、チャンネルの多くを受信するためにアンテナの場所や方向の調節が必要になる場合があります。最良の結果を得るには、アンテナを窓際の高い位置に設置します。"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"ネットワーク チューナーで見つかったチャンネルを削除して新しいチャンネルをもう一度スキャンします。\n\nネットワーク チューナーの電源がオンになっていて、テレビの信号源に接続されていることを確認してください。\n\n無線アンテナを使用している場合は、チャンネルの多くを受信するためにアンテナの場所や方向の調節が必要になる場合があります。最良の結果を得るには、アンテナを窓際の高い位置に設置します。"</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"次へ"</item>
<item msgid="235450158666155406">"キャンセル"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"テレビ チューナーのセットアップ"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB チャンネル チューナーのセットアップ"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"ネットワーク チャンネル チューナーのセットアップ"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"この処理には数分かかることがあります"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"チューナーを一時的に使用できないか、すでに録画に使用しています。"</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"チャンネルが見つかりませんでした"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"スキャンの結果、チャンネルは見つかりませんでした。テレビがテレビの信号源に接続されていることを確認してください。\n\n無線アンテナを使用している場合は、アンテナの場所や方向を調節してください。最良の結果を得るには、アンテナを窓際の高い位置に設置してから、もう一度スキャンします。"</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"スキャンの結果、チャンネルは見つかりませんでした。USB チューナーが電源に接続され、テレビの信号源に接続されていることを確認してください。\n\n無線アンテナを使用している場合は、アンテナの場所や方向を調節してください。最良の結果を得るには、アンテナを窓際の高い位置に設置してから、もう一度スキャンします。"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"スキャンの結果、チャンネルは見つかりませんでした。ネットワーク チューナーの電源がオンになっていて、テレビの信号源に接続されていることを確認してください。\n\n無線アンテナを使用している場合は、アンテナの場所や方向を調節してください。最良の結果を得るには、アンテナを窓際の高い位置に設置してから、もう一度スキャンします。"</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"再スキャン"</item>
<item msgid="2092797862490235174">"完了"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"テレビのチャンネルをスキャン"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"テレビ チューナーのセットアップ"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB テレビ チューナーのセットアップ"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV チューナーの接続が解除されています。"</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"テレビのチャンネルをスキャン"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"テレビ チューナーのセットアップ"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB テレビ チューナーのセットアップ"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"ネットワーク テレビ チューナーのセットアップ"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB テレビ チューナーの接続が解除されています。"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"ネットワーク チューナーの接続が解除されています。"</string>
</resources>
diff --git a/usbtuner-res/values-ka-rGE/strings.xml b/usbtuner-res/values-ka-rGE/strings.xml
new file mode 100644
index 00000000..055c4a99
--- /dev/null
+++ b/usbtuner-res/values-ka-rGE/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"TV-ტუნერი"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB TV-ტუნერი"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"ქსელის TV-ტუნერი (Beta)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"გთხოვთ, მოითმინოთ დამუშავების დასრულებამდე"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"ტუნერის პროგრამული უზრუნველყოფა ახლახან განახლდა. გთხოვთ, ხელახლა დაასკანიროთ არხები."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"აუდიოს ჩასართავად, სისტემის ხმის პარამეტრებში ჩართეთ მოცულობითი ხმა"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"აუდიოს დაკვრა ვერ ხერხდება. გთხოვთ, ცადოთ სხვა არხი"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"არხების ტუნერის დაყენება"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"TV-ტუნერის დაყენება"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"არხების USB ტუნერის დაყენება"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"ქსელის ტუნერის დაყენება"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"დარწმუნდით, რომ თქვენი ტელევიზორი მიერთებულია სატელევიზიო სიგნალის წყაროსთან..\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, არხების უმეტესობის მისაღებად, მისი განლაგების ან მიმართულების დარეგულება მოგიწევთ. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"დარწმუნდით, რომ USB ტუნერი ბუდეშია და მიერთებულია სატელევიზიო სიგნალის წყაროსთან.\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, არხების უმეტესობის მისაღებად, მისი განლაგების ან მიმართულების დარეგულება მოგიწევთ. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"დარწმუნდით, რომ ქსელის ტუნერი ჩართულია და მიერთებულია სატელევიზიო სიგნალის წყაროსთან.\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, არხების უმეტესობის მისაღებად, მისი განლაგების ან მიმართულების დარეგულირება მოგიწევთ. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"გაგრძელება"</item>
+ <item msgid="727245208787621142">"ახლა არა"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"გსურთ არხების ხელახლა დაყენება?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"ეს მოქმედება ამოშლის TV ტუნერით ნაპოვნ არხებს და ახალი არხების სკანირება ხელახლა მოხდება.\n\nდარწმუნდით, რომ თქვენი ტელევიზორი მიერთებულია სატელევიზიო სიგნალის წყაროსთან.\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, არხების უმეტესობის მისაღებად, მისი განლაგების ან მიმართულების დარეგულება მოგიწევთ. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"ეს მოქმედება ამოშლის USB ტუნერით ნაპოვნ არხებს და ხელახლა მოხდება ახალი არხების სკანირება.\n\nდარწმუნდით, რომ USB ტუნერი ბუდეშია და მიერთებულია სატელევიზიო სიგნალის წყაროსთან.\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, არხების უმეტესობის მისაღებად, მისი განლაგების ან მიმართულების დარეგულება მოგიწევთ. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"ეს მოქმედება ამოშლის ქსელის ტუნერით ნაპოვნ არხებს და ახალი არხების სკანირება ხელახლა მოხდება.\n\nდარწმუნდით, რომ ქსელის ტუნერი ჩართულია და მიერთებულია სატელევიზიო სიგნალის წყაროსთან.\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, არხების უმეტესობის მისაღებად, მისი განლაგების ან მიმართულების დარეგულირება მოგიწევთ. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"გაგრძელება"</item>
+ <item msgid="235450158666155406">"გაუქმება"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"აირჩიეთ კავშირის ტიპი"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"აირჩიეთ ანტენა, თუ ტუნერთან მიერთებულია გარე ანტენა. აირჩიეთ კაბელი, თუ არხებს საკაბელო სერვისის პროვაიდერისგან იღებთ. თუ დარწმუნებული არ ხართ, დასკანირდება ორივე ტიპი, მაგრამ ამას შეიძლება მეტი დრო დასჭირდეს."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"ანტენა"</item>
+ <item msgid="2670079958754180142">"კაბელი"</item>
+ <item msgid="36774059871728525">"არ ვიცი"</item>
+ <item msgid="6881204453182153978">"მხოლოდ დეველოპერებისთვის"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"TV-ტუნერის დაყენება"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"არხების USB ტუნერის დაყენება"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"არხების ქსელის ტუნერის დაყენება"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"ამას შეიძლება რამდენიმე წუთი დასჭირდეს"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ტუნერი დროებით მიუწვდომელია, ან უკვე გამოიყენება ჩასაწერად."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">მოიძებნა %1$d არხი</item>
+ <item quantity="one">მოიძებნა %1$d არხი</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"არხების სკანირების შეწყვეტა"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">მოიძებნა %1$d არხი</item>
+ <item quantity="one">მოიძებნა %1$d არხი</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">მშვენიერია! არხების სკანირებისას მოიძებნა %1$d არხი. თუ სათანადო შედეგს ვერ მიიღებთ, ცადეთ ანტენის პოზიციის დარეგულირება და ხელახლა დაასკანირეთ.</item>
+ <item quantity="one">მშვენიერია! არხების სკანირებისას მოიძებნა %1$d არხი. თუ სათანადო შედეგს ვერ მიიღებთ, ცადეთ ანტენის პოზიციის დარეგულირება და ხელახლა დაასკანირეთ.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"მზადაა"</item>
+ <item msgid="2480490326672924828">"ხელახლა სკანირება"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"არხები ვერ მოიძებნა"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"სკანირებისას არხები ვერ მოიძებნა. დარწმუნდით, რომ თქვენი ტელევიზორი მიერთებულია სატელევიზიო სიგნალის წყაროსთან.\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, დაარეგულირეთ მისი განლაგება ან მიმართულება. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს და ხელახლა დაასკანირეთ."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"სკანირებისას არხები ვერ მოიძებნა. დარწმუნდით, რომ USB ტუნერი ბუდეშია და მიერთებულია სატელევიზიო სიგნალის წყაროსთან. \n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, დაარეგულირეთ მისი განლაგება ან მიმართულება. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს და ხელახლა დაასკანირეთ."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"სკანირებისას არხები ვერ მოიძებნა. დარწმუნდით, რომ ქსელის ტუნერი ჩართულია და მიერთებულია სატელევიზიო სიგნალის წყაროსთან. \n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, დაარეგულირეთ მისი განლაგება ან მიმართულება. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს და ხელახლა დაასკანირეთ."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"ხელახლა სკანირება"</item>
+ <item msgid="2092797862490235174">"მზადაა"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"სკანირება სატელევიზიო არხების აღმოსაჩენად"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV-ტუნერის დაყენება"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV-ტუნერის დაყენება"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"ქსელის TV-ტუნერის დაყენება"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV-ტუნერი გაითიშა."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"ქსელის ტუნერი გაითიშა."</string>
+</resources>
diff --git a/usbtuner-res/values-ka/strings.xml b/usbtuner-res/values-ka/strings.xml
deleted file mode 100644
index e09428d7..00000000
--- a/usbtuner-res/values-ka/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"TV-ტუნერი"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB TV-ტუნერი"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"ჩართვა"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"გამორთვა"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"გთხოვთ, მოითმინოთ დამუშავების დასრულებამდე"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"აირჩიეთ არხების წყარო"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"სიგნალი არ არის"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g>-ზე გადართვა ვერ მოხერხდა"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"არხზე გადართვა ვერ მოხერხდა"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"ტუნერის პროგრამული უზრუნველყოფა ახლახან განახლდა. გთხოვთ, ხელახლა დაასკანიროთ არხები."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"აუდიოს ჩასართავად, სისტემის ხმის პარამეტრებში ჩართეთ მოცულობითი ხმა"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"არხების ტუნერის დაყენება"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"TV-ტუნერის დაყენება"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"არხების USB ტუნერის დაყენება"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"დარწმუნდით, რომ თქვენი ტელევიზორი მიერთებულია სატელევიზიო სიგნალის წყაროსთან..\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, არხების უმეტესობის მისაღებად, მისი განლაგების ან მიმართულების დარეგულება მოგიწევთ. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"დარწმუნდით, რომ USB ტუნერი ბუდეშია და მიერთებულია სატელევიზიო სიგნალის წყაროსთან.\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, არხების უმეტესობის მისაღებად, მისი განლაგების ან მიმართულების დარეგულება მოგიწევთ. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"გაგრძელება"</item>
- <item msgid="727245208787621142">"ახლა არა"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"გსურთ არხების ხელახლა დაყენება?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"ეს მოქმედება ამოშლის TV ტუნერით ნაპოვნ არხებს და ახალი არხების სკანირება ხელახლა მოხდება.\n\nდარწმუნდით, რომ თქვენი ტელევიზორი მიერთებულია სატელევიზიო სიგნალის წყაროსთან.\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, არხების უმეტესობის მისაღებად, მისი განლაგების ან მიმართულების დარეგულება მოგიწევთ. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"ეს მოქმედება ამოშლის USB ტუნერით ნაპოვნ არხებს და ხელახლა მოხდება ახალი არხების სკანირება.\n\nდარწმუნდით, რომ USB ტუნერი ბუდეშია და მიერთებულია სატელევიზიო სიგნალის წყაროსთან.\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, არხების უმეტესობის მისაღებად, მისი განლაგების ან მიმართულების დარეგულება მოგიწევთ. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"გაგრძელება"</item>
- <item msgid="235450158666155406">"გაუქმება"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"აირჩიეთ კავშირის ტიპი"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"აირჩიეთ ანტენა, თუ ტუნერთან მიერთებულია გარე ანტენა. აირჩიეთ კაბელი, თუ არხებს საკაბელო სერვისის პროვაიდერისგან იღებთ. თუ დარწმუნებული არ ხართ, დასკანირდება ორივე ტიპი, მაგრამ ამას შეიძლება მეტი დრო დასჭირდეს."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"ანტენა"</item>
- <item msgid="2670079958754180142">"კაბელი"</item>
- <item msgid="36774059871728525">"არ ვიცი"</item>
- <item msgid="6881204453182153978">"მხოლოდ დეველოპერებისთვის"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"TV-ტუნერის დაყენება"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"არხების USB ტუნერის დაყენება"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"ამას შეიძლება რამდენიმე წუთი დასჭირდეს"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ტუნერი დროებით მიუწვდომელია, ან უკვე გამოიყენება ჩასაწერად."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">მოიძებნა %1$d არხი</item>
- <item quantity="one">მოიძებნა %1$d არხი</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"არხების სკანირების შეწყვეტა"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">მოიძებნა %1$d არხი</item>
- <item quantity="one">მოიძებნა %1$d არხი</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">მშვენიერია! არხების სკანირებისას მოიძებნა %1$d არხი. თუ სათანადო შედეგს ვერ მიიღებთ, ცადეთ ანტენის პოზიციის დარეგულირება და ხელახლა დაასკანირეთ.</item>
- <item quantity="one">მშვენიერია! არხების სკანირებისას მოიძებნა %1$d არხი. თუ სათანადო შედეგს ვერ მიიღებთ, ცადეთ ანტენის პოზიციის დარეგულირება და ხელახლა დაასკანირეთ.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"მზადაა"</item>
- <item msgid="2480490326672924828">"ხელახლა სკანირება"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"არხები ვერ მოიძებნა"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"სკანირებისას არხები ვერ მოიძებნა. დარწმუნდით, რომ თქვენი ტელევიზორი მიერთებულია სატელევიზიო სიგნალის წყაროსთან.\n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, დაარეგულირეთ მისი განლაგება ან მიმართულება. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს და ხელახლა დაასკანირეთ."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"სკანირებისას არხები ვერ მოიძებნა. დარწმუნდით, რომ USB ტუნერი ბუდეშია და მიერთებულია სატელევიზიო სიგნალის წყაროსთან. \n\nტერესტრიული ანტენის გამოყენების შემთხვევაში, დაარეგულირეთ მისი განლაგება ან მიმართულება. საუკეთესო შედეგის მისაღებად, განათავსეთ ის სიმაღლეზე, ფანჯარასთან ახლოს და ხელახლა დაასკანირეთ."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"ხელახლა სკანირება"</item>
- <item msgid="2092797862490235174">"მზადაა"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"სატელევიზიო არხების სკანირება"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV-ტუნერის დაყენება"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV-ტუნერის დაყენება"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV-ტუნერი გაითიშა."</string>
-</resources>
diff --git a/usbtuner-res/values-kk-rKZ/strings.xml b/usbtuner-res/values-kk-rKZ/strings.xml
new file mode 100644
index 00000000..7ca732b2
--- /dev/null
+++ b/usbtuner-res/values-kk-rKZ/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"ТД тюнері"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB TД тюнері"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Желілік теледидар тюнері (БЕТА НҰСҚАСЫ)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Өңдеу аяқталғанша күте тұрыңыз"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Тюнердің бағдарламалық құралы жақында жаңартылды. Арналарды қайта іздеңіз."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Аудиомазмұнды қосу үшін жүйенің параметрлерінде көлемдік дыбысты қосыңыз"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Аудиомазмұн ойнатылмайды. Басқа теледидар арнасын қосып көріңіз"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Арна тюнерін орнату"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"ТД тюнерін орнату"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB арна тюнерін орнату"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Желі тюнерін реттеу"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Теледидардың ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, көптеген арналарды қабылдау үшін оның орнын немесе бағытын реттеу қажет болады. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырыңыз."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB тюнерін жалғанғанын және ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, көптеген арналарды қабылдау үшін оның орнын немесе бағытын реттеу қажет болады. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырыңыз."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"USB тюнері қосылып, теледидардың сигнал көзіне жалғанғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, көптеген арналарды қабылдау үшін оның орнын ауыстырыңыз немесе бағытын реттеңіз. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын жерге орналастырыңыз."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Жалғастыру"</item>
+ <item msgid="727245208787621142">"Қазір емес"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Арналарды қайта орнату қажет пе?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"ТД тюнерінде табылған арналар жойылып, жаңа арналар ізделеді.\n\nТеледидардың ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, көптеген арналарды қабылдау үшін оның орнын немесе бағытын реттеу қажет болады. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырыңыз."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"USB тюнерінде табылған арналар жойылып, жаңа арналар ізделеді.\n\nUSB тюнері жалғанғанын және ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, көптеген арналарды қабылдау үшін оның орнын немесе бағытын реттеу қажет болады. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырыңыз."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Желі тюнерінде табылған арналар өшіріліп, жаңа арналар ізделеді.\n\nЖелі тюнері қосылып, теледидардың сигнал көзіне жалғанғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, көптеген арналарды қабылдау үшін оның орнын ауыстырыңыз немесе бағытын реттеңіз. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын жерге орналастырыңыз."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Жалғастыру"</item>
+ <item msgid="235450158666155406">"Бас тарту"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Қосылу түрін таңдау"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Тюнерге қосымша антенна қосылған болса, \"Антенна\" опциясын таңдаңыз. Арналар кабельді қызмет провайдерінен алынған болса, \"Кабель\" опциясын таңдаңыз. Нақты білмесеңіз, екі түрі де ізделеді, бірақ бұған көбірек уақыт кетуі мүмкін."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Антенна"</item>
+ <item msgid="2670079958754180142">"Кабель"</item>
+ <item msgid="36774059871728525">"Нақты білмеймін"</item>
+ <item msgid="6881204453182153978">"Тек әзірлеу"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"ТД тюнерін орнату"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB арна тюнерін орнату"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Желілік арна тюнерін реттеу"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Бұл бірнеше минутты алуы мүмкін"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Тюнер қолжетімсіз немесе жазу барысында қолданылуда."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d арна табылды</item>
+ <item quantity="one">%1$d арна табылды</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"АРНА ІЗДЕУДІ ТОҚТАТУ"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d арна табылды</item>
+ <item quantity="one">%1$d арна табылды</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">Тамаша! Арналарды іздеу кезінде %1$d арна табылды. Жеткіліксіз болса, антеннаның орнын ауыстырып, қайта іздеп көріңіз.</item>
+ <item quantity="one">Тамаша! Арналарды іздеу кезінде %1$d арна табылды. Жеткіліксіз болса, антеннаның орнын ауыстырып, қайта іздеп көріңіз.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Орындалды"</item>
+ <item msgid="2480490326672924828">"Қайта іздеу"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Арналар табылмады"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Іздеу нәтижесінде ешқандай арна табылмады. Теледидардың ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, орнын немесе бағытын реттеңіз. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырып, қайта іздеп көріңіз."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Іздеу нәтижесінде арналар табылмады. USB тюнері жалғанғанын және ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, орнын немесе бағытын реттеңіз. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырып, қайта іздеп көріңіз."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Іздеу нәтижесінде арналар табылмады. Желі тюнері қосылып, теледидардың сигнал көзіне жалғанғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, оның орнын ауыстырыңыз немесе бағытын реттеңіз. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын жерге орналастырып, қайта іздеп көріңіз."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Қайта іздеу"</item>
+ <item msgid="2092797862490235174">"Орындалды"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"ТД арналарын іздеу"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"ТД тюнерін орнату"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TД тюнерін орнату"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Желілік ТД тюнерін реттеу"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TД тюнері ажыратылды."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Желі тюнері ажыратылды."</string>
+</resources>
diff --git a/usbtuner-res/values-kk/strings.xml b/usbtuner-res/values-kk/strings.xml
deleted file mode 100644
index 3c2ba4f3..00000000
--- a/usbtuner-res/values-kk/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"ТД тюнері"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB TД тюнері"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Қосу"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Өшіру"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Өңдеу аяқталғанша күте тұрыңыз"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Арна көзін таңдаңыз"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Сигнал жоқ"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> арнасына реттелмеді"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Реттелмеді"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Тюнердің бағдарламалық құралы жақында жаңартылды. Арналарды қайта іздеңіз."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Аудиомазмұнды қосу үшін жүйенің параметрлерінде көлемдік дыбысты қосыңыз"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Арна тюнерін орнату"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"ТД тюнерін орнату"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB арна тюнерін орнату"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Теледидардың ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, көптеген арналарды қабылдау үшін оның орнын немесе бағытын реттеу қажет болады. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырыңыз."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB тюнерін жалғанғанын және ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, көптеген арналарды қабылдау үшін оның орнын немесе бағытын реттеу қажет болады. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырыңыз."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Жалғастыру"</item>
- <item msgid="727245208787621142">"Қазір емес"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Арналарды қайта орнату қажет пе?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"ТД тюнерінде табылған арналар жойылып, жаңа арналар ізделеді.\n\nТеледидардың ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, көптеген арналарды қабылдау үшін оның орнын немесе бағытын реттеу қажет болады. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырыңыз."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"USB тюнерінде табылған арналар жойылып, жаңа арналар ізделеді.\n\nUSB тюнері жалғанғанын және ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, көптеген арналарды қабылдау үшін оның орнын немесе бағытын реттеу қажет болады. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырыңыз."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Жалғастыру"</item>
- <item msgid="235450158666155406">"Бас тарту"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Қосылу түрін таңдау"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Тюнерге қосымша антенна қосылған болса, \"Антенна\" опциясын таңдаңыз. Арналар кабельді қызмет провайдерінен алынған болса, \"Кабель\" опциясын таңдаңыз. Нақты білмесеңіз, екі түрі де ізделеді, бірақ бұған көбірек уақыт кетуі мүмкін."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Антенна"</item>
- <item msgid="2670079958754180142">"Кабель"</item>
- <item msgid="36774059871728525">"Нақты білмеймін"</item>
- <item msgid="6881204453182153978">"Тек әзірлеу"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"ТД тюнерін орнату"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB арна тюнерін орнату"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Бұл бірнеше минутты алуы мүмкін"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Тюнер қол жетімсіз немесе жазу барысында қолданылуда."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d арна табылды</item>
- <item quantity="one">%1$d арна табылды</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"АРНА ІЗДЕУДІ ТОҚТАТУ"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d арна табылды</item>
- <item quantity="one">%1$d арна табылды</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">Тамаша! Арналарды іздеу кезінде %1$d арна табылды. Жеткіліксіз болса, антеннаның орнын ауыстырып, қайта іздеп көріңіз.</item>
- <item quantity="one">Тамаша! Арналарды іздеу кезінде %1$d арна табылды. Жеткіліксіз болса, антеннаның орнын ауыстырып, қайта іздеп көріңіз.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Орындалды"</item>
- <item msgid="2480490326672924828">"Қайта іздеу"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Арналар табылмады"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Іздеу нәтижесінде ешқандай арна табылмады. Теледидардың ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, орнын немесе бағытын реттеңіз. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырып, қайта іздеп көріңіз."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Іздеу нәтижесінде арналар табылмады. USB тюнері жалғанғанын және ТД сигнал көзіне қосылғанын тексеріңіз.\n\nСымсыз антеннаны пайдалансаңыз, орнын немесе бағытын реттеңіз. Ең жақсы нәтижеге қол жеткізу үшін оны жоғарырақ және терезеге жақын орналастырып, қайта іздеп көріңіз."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Қайта іздеу"</item>
- <item msgid="2092797862490235174">"Орындалды"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"ТД арналарын іздеу"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"ТД тюнерін орнату"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TД тюнерін орнату"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TД тюнері ажыратылды."</string>
-</resources>
diff --git a/usbtuner-res/values-km-rKH/strings.xml b/usbtuner-res/values-km-rKH/strings.xml
new file mode 100644
index 00000000..5bca2a02
--- /dev/null
+++ b/usbtuner-res/values-km-rKH/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"អង្គរាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"ឧបករណ៍ USB រាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"កម្មវិធី​រាវ​បណ្តាញ​ទូរទស្សន៍ (បេតា)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"សូមរង់ចាំដើម្បីបញ្ចប់ដំណើរការ"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"កម្មវិធីអង្គរាវប៉ុស្តិ៍បានអាប់ដេតថ្មីៗនេះ។ សូមស្កេនរកប៉ុស្តិ៍ទាំងនេះម្តងទៀត។"</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"បើកដំណើរការសំឡេងជុំវិញនៅក្នុងការកំណត់សំឡេងប្រព័ន្ធដើម្បីបើកដំណើរការអូឌីយ៉ូ"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"មិនអាចចាក់អូឌីយ៉ូបានទេ។ សូមសាកល្បងប្រើទូរទស្សន៍ផ្សេង"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ការដំឡើងអង្គរាវប៉ុស្តិ៍"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"ការដំឡើងអង្គរាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"ការដំឡើងឧបករណ៍ USB រាវប៉ុស្តិ៍"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"រៀបចំឧបករណ៍រាវបណ្តាញ"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"សូមផ្ទៀងផ្ទាត់ថាប៉ុស្តិ៍ទូរទស្សន៍របស់អ្នកត្រូវបានភ្ជាប់ទៅប្រភពរលកសញ្ញាទូរទស្សន៍។\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ សូមសម្រួលទីតាំង ឬទិសដៅរបស់វាដើម្បីទទួលបានប៉ុស្តិ៍ច្រើនបំផុត។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងខ្ពស់ និងនៅជិតបង្អួច។"</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"ផ្ទៀងផ្ទាត់ថាអ្នកបានដោតឧបករណ៍ USB រាវប៉ុស្តិ៍ និងបានភ្ជាប់ទៅប្រភពសញ្ញាទូរទស្សន៍\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ អ្នកប្រហែលជាត្រូវកែសម្រួលទីតាំង និងទិសដៅរបស់វាដើម្បីទទួលបានប៉ុស្តិ៍ច្រើនបំផុត។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច។"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"ផ្ទៀងផ្ទាត់ថាអ្នកបានបើកឧបករណ៍រាវបណ្តាញនេះ និងបានភ្ជាប់ទៅប្រភពរលកសញ្ញាទូរទស្សន៍។\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ អ្នកត្រូវកែសម្រួលទីតាំង និងទិសដៅរបស់វា ដើម្បីទទួលបានប៉ុស្តិ៍ច្រើនបំផុត។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច។"</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"បន្ត"</item>
+ <item msgid="727245208787621142">"មិនមែនឥឡូវនេះទេ"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"ដំណើរការដំឡើងប៉ុស្តិ៍ឡើងវិញឬទេ?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"វានឹងលុបប៉ុស្តិ៍ដែលបានរកឃើញដោយអង្គរាវប៉ុស្តិ៍ទូរទស្សន៍ចេញ ហើយស្កេនរកប៉ុស្តិ៍ថ្មីម្តងទៀត។\n\nផ្ទៀងផ្ទាត់ថាអ្នកបានដោតទូរទស្សន៍ទៅប្រភពរលកសញ្ញាទូរទស្សន៍\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ អ្នកប្រហែលជាត្រូវសម្រួលទីតាំង និងទិសដៅរបស់វាដើម្បីទទួលបានប៉ុស្តិ៍ច្រើនបំផុត។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច។"</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"វានឹងលុបប៉ុស្តិ៍ដែលបានរកឃើញដោយឧបករណ៍ USB រាវប៉ុស្តិ៍ចេញ ហើយស្កេនរកប៉ុស្តិ៍ថ្មីម្តងទៀត។\n\nផ្ទៀងផ្ទាត់ថាអ្នកបានដោតឧបករណ៍ USB រាវប៉ុស្តិ៍ និងបានភ្ជាប់ទៅប្រភពសញ្ញាទូរទស្សន៍\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ អ្នកប្រហែលជាត្រូវសម្រួលទីតាំង និងទិសដៅរបស់វាដើម្បីទទួលបានប៉ុស្តិ៍ច្រើនបំផុត។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច។"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"វានឹងលុបប៉ុស្តិ៍ដែលបានរកឃើញដោយឧបករណ៍រាវបណ្តាញ ហើយបន្ទាប់មកស្កេនរកបណ្តាញថ្មី។\n\nផ្ទៀងផ្ទាត់ថាអ្នកបានបើកអង្គរាវបណ្តាញនេះ និងបានភ្ជាប់ទៅប្រភពរលកសញ្ញាទូរទស្សន៍។\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ អ្នកត្រូវសម្រួលទីតាំង និងទិសដៅរបស់វា ដើម្បីទទួលបានប៉ុស្តិ៍ច្រើនបំផុត។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច។"</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"បន្ត"</item>
+ <item msgid="235450158666155406">"បោះបង់"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"ជ្រើសប្រភេទនៃការតភ្ជាប់"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"សូមជ្រើសរើសអង់តែន ប្រសិនបើអ្នកភ្ជាប់អង់តែនខាងក្រៅទៅនឹងអង្គរាវប៉ុស្តិ៍។ ឬជ្រើសរើសខ្សែកាប ប្រសិនបើប៉ុស្តិ៍របស់អ្នកផ្តល់ដោយក្រុមហ៊ុនផ្តល់សេវាខ្សែកាប។ ប្រសិនបើអ្នកមិនប្រាកដទេ អ្នកអាចជ្រើសរើសប្រភេទទាំងពីរដើម្បីស្កេន ប៉ុន្តែវាអាចចំណាយពេលយូរ។"</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"អង់តែន"</item>
+ <item msgid="2670079958754180142">"ខ្សែកាប"</item>
+ <item msgid="36774059871728525">"មិនប្រាកដ"</item>
+ <item msgid="6881204453182153978">"ការអភិវឌ្ឍន៍ប៉ុណ្ណោះ"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"ការដំឡើងអង្គរាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"ការដំឡើងឧបករណ៍ USB រាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"ការរៀបចំឧបករណ៍រាវបណ្តាញប៉ុស្តិ៍"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"វាអាចចំណាយពេលច្រើននាទី"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"អង្គរាវប៉ុស្តិ៍មិនអាចប្រើបានជាបណ្តោះអាសន្ន ឬបានប្រើសម្រាប់ការថតរួចទៅហើយ។"</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
+ <item quantity="one">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"បញ្ឈប់ការស្កេនរកប៉ុស្តិ៍"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
+ <item quantity="one">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">ល្អណាស់! បានរកឃើញប៉ុស្តិ៍ %1$d អំឡុងពេលស្កេន។ ប្រសិនបើការស្កេននេះរកមិនឃើញប៉ុស្តិ៍ទេ សូមសាកល្បងសម្រួលទីតាំងអង់តែន ហើយស្កេនម្តងទៀត។</item>
+ <item quantity="one">ល្អណាស់! បានរកឃើញប៉ុស្តិ៍ %1$d អំឡុងពេលស្កេន។ ប្រសិនបើការស្កេននេះរកមិនឃើញប៉ុស្តិ៍ទេ សូមសាកល្បងសម្រួលទីតាំងអង់តែន ហើយស្កេនម្តងទៀត។</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"រួចរាល់"</item>
+ <item msgid="2480490326672924828">"ស្កេនម្តងទៀត"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"រកមិនឃើញប៉ុស្តិ៍ទេ"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"ការស្កេននេះរកមិនឃើញប៉ុស្តិ៍ណាមួយឡើយ។ សូមផ្ទៀងផ្ទាត់ថាប៉ុស្តិ៍ទូរទស្សន៍របស់អ្នកត្រូវបានភ្ជាប់ទៅប្រភពរលកសញ្ញាទូរទស្សន៍។\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ សូមសម្រួលទីតាំង ឬទិសដៅរបស់វា។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងខ្ពស់ និងនៅជិតបង្អួច បន្ទាប់មកធ្វើការស្កេនម្តងទៀត។"</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"ការស្កេនរកមិនឃើញប៉ុស្តិ៍ទេ។ ផ្ទៀងផ្ទាត់ថាអ្នកបានដោតឧបករណ៍ USB រាវប៉ុស្តិ៍ និងបានភ្ជាប់ទៅប្រភពសញ្ញាទូរទស្សន៍។\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ សូមសម្រួលទីតាំង និងទិសដៅរបស់វា។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច ហើយបន្ទាប់មកស្កេនម្តងទៀត។"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"ការស្កេនរកមិនឃើញប៉ុស្តិ៍ណាមួយទេ។ ផ្ទៀងផ្ទាត់ថាអ្នកបានបើកឧបករណ៍រាវបណ្តាញនេះ និងបានភ្ជាប់ទៅប្រភពរលកសញ្ញាទូរទស្សន៍។\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ សូមសម្រួលទីតាំង និងទិសដៅរបស់វា។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច បន្ទាប់មកស្កេនម្តងទៀត។"</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"ស្កេនម្តងទៀត"</item>
+ <item msgid="2092797862490235174">"រួចរាល់"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"ស្កេនរកប៉ុស្តិ៍ទូរទស្សន៍"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"ការរៀបចំអង្គរាវរកប៉ុស្តិ៍ទូរទស្សន៍"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"ការរៀបចំអង្គរាវរកប៉ុស្តិ៍ទូរទស្សន៍តាម USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"ការរៀបចំអង្គរាវរកបណ្តាញទូរទស្សន៍"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"អង្គរាវរកប៉ុស្តិ៍ USB សម្រាប់ទូរទស្សន៍ត្រូវបានផ្តាច់។"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"អង្គរាវរក​បណ្តាញ​ត្រូវ​បាន​ផ្ដាច់។"</string>
+</resources>
diff --git a/usbtuner-res/values-km/strings.xml b/usbtuner-res/values-km/strings.xml
deleted file mode 100644
index 904f3e5d..00000000
--- a/usbtuner-res/values-km/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"អង្គរាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"ឧបករណ៍ USB រាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"បើក"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"បិទ"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"សូមរង់ចាំដើម្បីបញ្ចប់ដំណើរការ"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"ជ្រើសប្រភពប៉ុស្តិ៍របស់អ្នក"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"គ្មានរលកសញ្ញាទេ"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"បានបរាជ័យក្នុងការបើកប៉ុស្តិ៍ <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"បរាជ័យក្នុងការរាវប៉ុស្តិ៍"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"កម្មវិធីអង្គរាវប៉ុស្តិ៍បានអាប់ដេតថ្មីៗនេះ។ សូមស្កេនរកប៉ុស្តិ៍ទាំងនេះម្តងទៀត។"</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"បើកដំណើរការសំឡេងជុំវិញនៅក្នុងការកំណត់សំឡេងប្រព័ន្ធដើម្បីបើកដំណើរការអូឌីយ៉ូ"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ការដំឡើងអង្គរាវប៉ុស្តិ៍"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"ការដំឡើងអង្គរាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"ការដំឡើងឧបករណ៍ USB រាវប៉ុស្តិ៍"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"សូមផ្ទៀងផ្ទាត់ថាប៉ុស្តិ៍ទូរទស្សន៍របស់អ្នកត្រូវបានភ្ជាប់ទៅប្រភពរលកសញ្ញាទូរទស្សន៍។\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ សូមសម្រួលទីតាំង ឬទិសដៅរបស់វាដើម្បីទទួលបានប៉ុស្តិ៍ច្រើនបំផុត។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងខ្ពស់ និងនៅជិតបង្អួច។"</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"ផ្ទៀងផ្ទាត់ថាអ្នកបានដោតឧបករណ៍ USB រាវប៉ុស្តិ៍ និងបានភ្ជាប់ទៅប្រភពសញ្ញាទូរទស្សន៍\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ អ្នកប្រហែលជាត្រូវកែសម្រួលទីតាំង និងទិសដៅរបស់វាដើម្បីទទួលបានប៉ុស្តិ៍ច្រើនបំផុត។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច។"</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"បន្ត"</item>
- <item msgid="727245208787621142">"មិនមែនឥឡូវនេះទេ"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"ដំណើរការដំឡើងប៉ុស្តិ៍ឡើងវិញឬទេ?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"វានឹងលុបប៉ុស្តិ៍ដែលបានរកឃើញដោយអង្គរាវប៉ុស្តិ៍ទូរទស្សន៍ចេញ ហើយស្កេនរកប៉ុស្តិ៍ថ្មីម្តងទៀត។\n\nផ្ទៀងផ្ទាត់ថាអ្នកបានដោតទូរទស្សន៍ទៅប្រភពរលកសញ្ញាទូរទស្សន៍\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ អ្នកប្រហែលជាត្រូវសម្រួលទីតាំង និងទិសដៅរបស់វាដើម្បីទទួលបានប៉ុស្តិ៍ច្រើនបំផុត។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច។"</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"វានឹងលុបប៉ុស្តិ៍ដែលបានរកឃើញដោយឧបករណ៍ USB រាវប៉ុស្តិ៍ចេញ ហើយស្កេនរកប៉ុស្តិ៍ថ្មីម្តងទៀត។\n\nផ្ទៀងផ្ទាត់ថាអ្នកបានដោតឧបករណ៍ USB រាវប៉ុស្តិ៍ និងបានភ្ជាប់ទៅប្រភពសញ្ញាទូរទស្សន៍\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ អ្នកប្រហែលជាត្រូវសម្រួលទីតាំង និងទិសដៅរបស់វាដើម្បីទទួលបានប៉ុស្តិ៍ច្រើនបំផុត។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច។"</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"បន្ត"</item>
- <item msgid="235450158666155406">"បោះបង់"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"ជ្រើសប្រភេទនៃការតភ្ជាប់"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"សូមជ្រើសរើសអង់តែន ប្រសិនបើអ្នកភ្ជាប់អង់តែនខាងក្រៅទៅនឹងអង្គរាវប៉ុស្តិ៍។ ឬជ្រើសរើសខ្សែកាប ប្រសិនបើប៉ុស្តិ៍របស់អ្នកផ្តល់ដោយក្រុមហ៊ុនផ្តល់សេវាខ្សែកាប។ ប្រសិនបើអ្នកមិនប្រាកដទេ អ្នកអាចជ្រើសរើសប្រភេទទាំងពីរដើម្បីស្កេន ប៉ុន្តែវាអាចចំណាយពេលយូរ។"</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"អង់តែន"</item>
- <item msgid="2670079958754180142">"ខ្សែកាប"</item>
- <item msgid="36774059871728525">"មិនប្រាកដ"</item>
- <item msgid="6881204453182153978">"ការអភិវឌ្ឍន៍ប៉ុណ្ណោះ"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"ការដំឡើងអង្គរាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"ការដំឡើងឧបករណ៍ USB រាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"វាអាចចំណាយពេលច្រើននាទី"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"អង្គរាវប៉ុស្តិ៍មិនអាចប្រើបានជាបណ្តោះអាសន្ន ឬបានប្រើសម្រាប់ការថតរួចទៅហើយ។"</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
- <item quantity="one">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"បញ្ឈប់ការស្កេនរកប៉ុស្តិ៍"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
- <item quantity="one">បានរកឃើញប៉ុស្តិ៍ %1$d</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">ល្អណាស់! បានរកឃើញប៉ុស្តិ៍ %1$d អំឡុងពេលស្កេន។ ប្រសិនបើការស្កេននេះរកមិនឃើញប៉ុស្តិ៍ទេ សូមសាកល្បងសម្រួលទីតាំងអង់តែន ហើយស្កេនម្តងទៀត។</item>
- <item quantity="one">ល្អណាស់! បានរកឃើញប៉ុស្តិ៍ %1$d អំឡុងពេលស្កេន។ ប្រសិនបើការស្កេននេះរកមិនឃើញប៉ុស្តិ៍ទេ សូមសាកល្បងសម្រួលទីតាំងអង់តែន ហើយស្កេនម្តងទៀត។</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"រួចរាល់"</item>
- <item msgid="2480490326672924828">"ស្កេនម្តងទៀត"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"រកមិនឃើញប៉ុស្តិ៍ទេ"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"ការស្កេននេះរកមិនឃើញប៉ុស្តិ៍ណាមួយឡើយ។ សូមផ្ទៀងផ្ទាត់ថាប៉ុស្តិ៍ទូរទស្សន៍របស់អ្នកត្រូវបានភ្ជាប់ទៅប្រភពរលកសញ្ញាទូរទស្សន៍។\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ សូមសម្រួលទីតាំង ឬទិសដៅរបស់វា។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងខ្ពស់ និងនៅជិតបង្អួច បន្ទាប់មកធ្វើការស្កេនម្តងទៀត។"</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"ការស្កេនរកមិនឃើញប៉ុស្តិ៍ទេ។ ផ្ទៀងផ្ទាត់ថាអ្នកបានដោតឧបករណ៍ USB រាវប៉ុស្តិ៍ និងបានភ្ជាប់ទៅប្រភពសញ្ញាទូរទស្សន៍។\n\nប្រសិនបើអ្នកប្រើអង់តែនឥតខ្សែ សូមសម្រួលទីតាំង និងទិសដៅរបស់វា។ ដើម្បីទទួលបានលទ្ធផលល្អបំផុត សូមដាក់វានៅកន្លែងដែលខ្ពស់ក្បែរបង្អួច ហើយបន្ទាប់មកស្កេនម្តងទៀត។"</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"ស្កេនម្តងទៀត"</item>
- <item msgid="2092797862490235174">"រួចរាល់"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"ស្កេនរកប៉ុស្តិ៍ទូរទស្សន៍"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"ការដំឡើងអង្គរាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"ការដំឡើងឧបករណ៍ USB រាវប៉ុស្តិ៍ទូរទស្សន៍"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"អង្គរាវប៉ុស្តិ៍ USB សម្រាប់ទូរទស្សន៍ត្រូវបានផ្តាច់"</string>
-</resources>
diff --git a/usbtuner-res/values-kn-rIN/strings.xml b/usbtuner-res/values-kn-rIN/strings.xml
new file mode 100644
index 00000000..af903462
--- /dev/null
+++ b/usbtuner-res/values-kn-rIN/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"ಟಿವಿ ಟ್ಯೂನರ್"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB ಟಿವಿ ಟ್ಯೂನರ್"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"ನೆಟ್‌ವರ್ಕ್ ಟಿವಿ ಟ್ಯೂನರ್ (ಬೀಟಾ)‌‌"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವುದನ್ನು ಪೂರೈಸಲು ದಯವಿಟ್ಟು ಕಾಯಿರಿ"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"ಟ್ಯೂನರ್ ಸಾಫ್ಟ್‌ವೇರ್‍ ಅನ್ನು ಇತ್ತೀಚಿಗೆ ಅಪ್‌ಡೇಟ್ ಮಾಡಲಾಗಿದೆ. ದಯವಿಟ್ಟು ಚಾನಲ್‌ಗಳನ್ನು ಮರು-ಸ್ಕ್ಯಾನ್‌ ಮಾಡಿ."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ಆಡಿಯೊ ಸಕ್ರಿಯಗೊಳಿಸಲು ಸಿಸ್ಟಂ ಧ್ವನಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಸರೌಂಡ್ ಧ್ವನಿಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"ಆಡಿಯೊವನ್ನು ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ದಯವಿಟ್ಟು ಬೇರೊಂದು ಟಿವಿಯಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ಚಾನಲ್ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"ಟಿವಿ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB ಚಾನಲ್ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"ನೆಟ್‌ವರ್ಕ್ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"ನಿಮ್ಮ ಟಿವಿಯನ್ನು ಟಿವಿ ಸಿಗ್ನಲ್‌ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ನೀವು ಅದರ ಸ್ಥಳ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಬೇಕಾಗಬಹುದು. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಇದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ಟ್ಯೂನಲ್ ಅನ್ನು ಪ್ಲಗ್ ಇನ್ ಮಾಡಲಾಗಿದೆಯೇ ಮತ್ತು ಟಿವಿ ಸಿಗ್ನಲ್ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ನೀವು ಅದರ ಸ್ಥಳ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಬೇಕಾಗಬಹುದು. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಇದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"ನೆಟ್‌ವರ್ಕ್ ಟ್ಯೂನರ್ ಆನ್ ಮಾಡಲಾಗಿದೆಯೇ ಮತ್ತು ಟಿವಿ ಸಿಗ್ನಲ್ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ನೀವು ಅದರ ಸ್ಥಳ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಬೇಕಾಗಬಹುದು. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಅದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"ಮುಂದುವರಿಸು"</item>
+ <item msgid="727245208787621142">"ಸದ್ಯಕ್ಕೆ ಬೇಡ"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"ಚಾನಲ್ ಸೆಟಪ್ ಅನ್ನು ಮರುರನ್ ಮಾಡುವುದೇ?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"ಟಿವಿ ಟ್ಯೂನರ್‌ನಿಂದ ಪತ್ತೆ ಮಾಡಲಾದ ಚಾನಲ್‌ಗಳನ್ನು ಇದು ತೆಗೆದುಹಾಕುತ್ತದೆ ಹಾಗೂ ಮತ್ತೆ ಹೊಸ ಚಾನಲ್‌ಗಳಿಗೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತದೆ.\n\nನಿಮ್ಮ ಟಿವಿಯನ್ನು ಟಿವಿ ಸಿಗ್ನಲ್‌ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ನೀವು ಅದರ ಸ್ಥಳ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಬೇಕಾಗಬಹುದು. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಇದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"USB ಟ್ಯೂನರ್‌ನಿಂದ ಪತ್ತೆ ಮಾಡಲಾದ ಚಾನಲ್‌ಗಳನ್ನು ಇದು ತೆಗೆದುಹಾಕುತ್ತದೆ ಹಾಗೂ ಮತ್ತೆ ಹೊಸ ಚಾನಲ್‌ಗಳಿಗೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತದೆ.\n\nUSB ಟ್ಯೂನಲ್ ಅನ್ನು ಪ್ಲಗ್ ಇನ್ ಮಾಡಲಾಗಿದೆಯೇ ಮತ್ತು ಟಿವಿ ಸಿಗ್ನಲ್ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ನೀವು ಅದರ ಸ್ಥಳ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಬೇಕಾಗಬಹುದು. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಇದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"ನೆಟ್‌ವರ್ಕ್ ಟ್ಯೂನರ್‌ನಿಂದ ಪತ್ತೆ ಮಾಡಲಾದ ಚಾನಲ್‌ಗಳನ್ನು ಇದು ತೆಗೆದುಹಾಕುತ್ತದೆ ಹಾಗೂ ಮತ್ತೆ ಹೊಸ ಚಾನಲ್‌ಗಳಿಗೆ ಸ್ಕ್ಯಾನ್ ಮಾಡುತ್ತದೆ.\n\nನೆಟ್‌ವರ್ಕ್ ಟ್ಯೂನಲ್ ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆಯೇ ಮತ್ತು ಟಿವಿ ಸಿಗ್ನಲ್ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ನೀವು ಅದರ ಸ್ಥಳ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಬೇಕಾಗಬಹುದು. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಅದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"ಮುಂದುವರಿಸು"</item>
+ <item msgid="235450158666155406">"ರದ್ದುಮಾಡಿ"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"ಸಂಪರ್ಕದ ಪ್ರಕಾರ ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"ಟ್ಯೂನರ್‌ಗೆ ಬಾಹ್ಯ ಆಂಟೆನಾವನ್ನು ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದ್ದರೆ ಆಂಟೆನಾ ಆರಿಸಿಕೊಳ್ಳಿ. ನಿಮ್ಮ ಚಾನಲ್‌ಗಳು ಕೇಬಲ್ ಸೇವೆ ಪೂರೈಕೆದಾರರಿಂದ ಬರುತ್ತಿದ್ದರೆ ಕೇಬಲ್ ಆರಿಸಿಕೊಳ್ಳಿ. ನಿಮಗೆ ಯಾವುದು ಎಂದು ಖಚಿತವಿಲ್ಲದಿದ್ದರೆ, ಎರಡೂ ಪ್ರಕಾರಗಳನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತದೆ, ಆದರೆ ಇದಕ್ಕೆ ಹೆಚ್ಚು ಸಮಯ ತೆಗೆದುಕೊಳ್ಳಬಹುದು."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"ಆಂಟೆನಾ"</item>
+ <item msgid="2670079958754180142">"ಕೇಬಲ್"</item>
+ <item msgid="36774059871728525">"ಖಚಿತವಾಗಿಲ್ಲ"</item>
+ <item msgid="6881204453182153978">"ಅಭಿವೃದ್ಧಿ ಮಾತ್ರ"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"ಟಿವಿ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB ಚಾನಲ್ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"ನೆಟ್‌ವರ್ಕ್ ಚಾನಲ್ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"ಇದಕ್ಕೆ ಹಲವಾರು ನಿಮಿಷಗಳು ತೆಗೆದುಕೊಳ್ಳಬಹುದು"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ಟ್ಯೂನರ್ ತಾತ್ಕಾಲಿಕವಾಗಿ ಲಭ್ಯವಿಲ್ಲ ಅಥವಾ ಈಗಾಗಲೇ ರೆಕಾರ್ಡಿಂಗ್‌ಗೆ ಬಳಸಲಾಗಿದೆ."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="one">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
+ <item quantity="other">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಮಾಡುವುದನ್ನು ನಿಲ್ಲಿಸಿ"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="one">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
+ <item quantity="other">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="one">ಉತ್ತಮ! ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಸಮಯದಲ್ಲಿ %1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ. ಇದು ಸರಿಯಲ್ಲವೆಂದು ತೋರಿದರೆ, ಆಂಟೆನಾ ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ.</item>
+ <item quantity="other">ಉತ್ತಮ! ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಸಮಯದಲ್ಲಿ %1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ. ಇದು ಸರಿಯಲ್ಲವೆಂದು ತೋರಿದರೆ, ಆಂಟೆನಾ ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"ಮುಗಿದಿದೆ"</item>
+ <item msgid="2480490326672924828">"ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡು"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"ಯಾವುದೇ ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"ಸ್ಕ್ಯಾನ್ ಯಾವುದೇ ಚಾನಲ್‌ಗಳನ್ನು ಪತ್ತೆ ಮಾಡಿಲ್ಲ. ನಿಮ್ಮ ಟಿವಿಯನ್ನು ಟಿವಿ ಸಿಗ್ನಲ್‌ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಇದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"ಸ್ಕ್ಯಾನ್ ಯಾವುದೇ ಚಾನಲ್‌ಗಳನ್ನು ಪತ್ತೆ ಮಾಡಿಲ್ಲ. USB ಟ್ಯೂನಲ್ ಅನ್ನು ಪ್ಲಗ್ ಇನ್ ಮಾಡಲಾಗಿದೆಯೇ ಮತ್ತು ಟಿವಿ ಸಿಗ್ನಲ್ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಅದರ ಸ್ಥಳ ಅಥವಾ ದಿಕ್ಕನ್ನು ಸರಿಹೊಂದಿಸಿ. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"ಸ್ಕ್ಯಾನ್ ನಂತರ ಯಾವುದೇ ಚಾನಲ್ ಕಂಡುಬಂದಿಲ್ಲ. ನೆಟ್‌ವರ್ಕ್ ಟ್ಯೂನರ್ ಆನ್ ಮಾಡಲಾಗಿದೆಯೇ ಮತ್ತು ಟಿವಿ ಸಿಗ್ನಲ್ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ನೆಟ್‌ವರ್ಕ್ ಸಂಪರ್ಕದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಅದರ ಸ್ಥಳ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಿ. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಅದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ ಹಾಗೂ ಮತ್ತೊಮ್ಮೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡು"</item>
+ <item msgid="2092797862490235174">"ಮುಗಿದಿದೆ"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"ಟಿವಿ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಿ"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"ಟಿವಿ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB ಟಿವಿ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"ನೆಟ್‌ವರ್ಕ್ ಟಿವಿ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB ಟಿವಿ ಟ್ಯೂನರ್ ಸಂಪರ್ಕ ಕಡಿತಗೊಂಡಿದೆ."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"ನೆಟ್‌ವರ್ಕ್ ಟ್ಯೂನರ್ ಸಂಪರ್ಕ ಕಡಿತಗೊಂಡಿದೆ."</string>
+</resources>
diff --git a/usbtuner-res/values-kn/strings.xml b/usbtuner-res/values-kn/strings.xml
deleted file mode 100644
index fb97ae2b..00000000
--- a/usbtuner-res/values-kn/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"ಟಿವಿ ಟ್ಯೂನರ್"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB ಟಿವಿ ಟ್ಯೂನರ್"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"ಆನ್"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"ಆಫ್"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವುದನ್ನು ಪೂರೈಸಲು ದಯವಿಟ್ಟು ಕಾಯಿರಿ"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"ನಿಮ್ಮ ಚಾನಲ್ ಮೂಲವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"ಯಾವುದೇ ಸಂಕೇತವಿಲ್ಲ"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> ಗೆ ಟ್ಯೂನ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ಟ್ಯೂನ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"ಟ್ಯೂನರ್ ಸಾಫ್ಟ್‌ವೇರ್‍ ಅನ್ನು ಇತ್ತೀಚಿಗೆ ಅಪ್‌ಡೇಟ್ ಮಾಡಲಾಗಿದೆ. ದಯವಿಟ್ಟು ಚಾನಲ್‌ಗಳನ್ನು ಮರು-ಸ್ಕ್ಯಾನ್‌ ಮಾಡಿ."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ಆಡಿಯೊ ಸಕ್ರಿಯಗೊಳಿಸಲು ಸಿಸ್ಟಂ ಧ್ವನಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಸರೌಂಡ್ ಧ್ವನಿಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ಚಾನಲ್ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"ಟಿವಿ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB ಚಾನಲ್ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"ನಿಮ್ಮ ಟಿವಿಯನ್ನು ಟಿವಿ ಸಿಗ್ನಲ್‌ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ನೀವು ಅದರ ಸ್ಥಾನ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಬೇಕಾಗಬಹುದು. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಇದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ಟ್ಯೂನಲ್ ಅನ್ನು ಪ್ಲಗ್ ಇನ್ ಮಾಡಲಾಗಿದೆಯೇ ಮತ್ತು ಟಿವಿ ಸಿಗ್ನಲ್ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ನೀವು ಅದರ ಸ್ಥಾನ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಬೇಕಾಗಬಹುದು. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಇದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"ಮುಂದುವರಿಸು"</item>
- <item msgid="727245208787621142">"ಸದ್ಯಕ್ಕೆ ಬೇಡ"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"ಚಾನಲ್ ಸೆಟಪ್ ಅನ್ನು ಮರುರನ್ ಮಾಡುವುದೇ?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"ಟಿವಿ ಟ್ಯೂನರ್‌ನಿಂದ ಪತ್ತೆ ಮಾಡಲಾದ ಚಾನಲ್‌ಗಳನ್ನು ಇದು ತೆಗೆದುಹಾಕುತ್ತದೆ ಹಾಗೂ ಮತ್ತೆ ಹೊಸ ಚಾನಲ್‌ಗಳಿಗೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತದೆ.\n\nನಿಮ್ಮ ಟಿವಿಯನ್ನು ಟಿವಿ ಸಿಗ್ನಲ್‌ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ನೀವು ಅದರ ಸ್ಥಾನ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಬೇಕಾಗಬಹುದು. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಇದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"USB ಟ್ಯೂನರ್‌ನಿಂದ ಪತ್ತೆ ಮಾಡಲಾದ ಚಾನಲ್‌ಗಳನ್ನು ಇದು ತೆಗೆದುಹಾಕುತ್ತದೆ ಹಾಗೂ ಮತ್ತೆ ಹೊಸ ಚಾನಲ್‌ಗಳಿಗೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತದೆ.\n\nUSB ಟ್ಯೂನಲ್ ಅನ್ನು ಪ್ಲಗ್ ಇನ್ ಮಾಡಲಾಗಿದೆಯೇ ಮತ್ತು ಟಿವಿ ಸಿಗ್ನಲ್ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಹೆಚ್ಚಿನ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ನೀವು ಅದರ ಸ್ಥಾನ ಅಥವಾ ದಿಕ್ಕನ್ನು ಹೊಂದಿಸಬೇಕಾಗಬಹುದು. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಇದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"ಮುಂದುವರಿಸು"</item>
- <item msgid="235450158666155406">"ರದ್ದುಮಾಡಿ"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"ಸಂಪರ್ಕದ ಪ್ರಕಾರ ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"ಟ್ಯೂನರ್‌ಗೆ ಬಾಹ್ಯ ಆಂಟೆನಾವನ್ನು ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದ್ದರೆ ಆಂಟೆನಾ ಆರಿಸಿಕೊಳ್ಳಿ. ನಿಮ್ಮ ಚಾನಲ್‌ಗಳು ಕೇಬಲ್ ಸೇವೆ ಪೂರೈಕೆದಾರರಿಂದ ಬರುತ್ತಿದ್ದರೆ ಕೇಬಲ್ ಆರಿಸಿಕೊಳ್ಳಿ. ನಿಮಗೆ ಯಾವುದು ಎಂದು ಖಚಿತವಿಲ್ಲದಿದ್ದರೆ, ಎರಡೂ ಪ್ರಕಾರಗಳನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತದೆ, ಆದರೆ ಇದಕ್ಕೆ ಹೆಚ್ಚು ಸಮಯ ತೆಗೆದುಕೊಳ್ಳಬಹುದು."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"ಆಂಟೆನಾ"</item>
- <item msgid="2670079958754180142">"ಕೇಬಲ್"</item>
- <item msgid="36774059871728525">"ಖಚಿತವಾಗಿಲ್ಲ"</item>
- <item msgid="6881204453182153978">"ಅಭಿವೃದ್ಧಿ ಮಾತ್ರ"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"ಟಿವಿ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB ಚಾನಲ್ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"ಇದಕ್ಕೆ ಹಲವಾರು ನಿಮಿಷಗಳು ತೆಗೆದುಕೊಳ್ಳಬಹುದು"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ಟ್ಯೂನರ್ ತಾತ್ಕಾಲಿಕವಾಗಿ ಲಭ್ಯವಿಲ್ಲ ಅಥವಾ ಈಗಾಗಲೇ ರೆಕಾರ್ಡಿಂಗ್‌ಗೆ ಬಳಸಲಾಗಿದೆ."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="one">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
- <item quantity="other">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಮಾಡುವುದನ್ನು ನಿಲ್ಲಿಸು"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="one">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
- <item quantity="other">%1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="one">ಉತ್ತಮ! ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಸಮಯದಲ್ಲಿ %1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ. ಇದು ಸರಿಯಲ್ಲವೆಂದು ತೋರಿದರೆ, ಆಂಟೆನಾ ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ.</item>
- <item quantity="other">ಉತ್ತಮ! ಚಾನಲ್ ಸ್ಕ್ಯಾನ್ ಸಮಯದಲ್ಲಿ %1$d ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿವೆ. ಇದು ಸರಿಯಲ್ಲವೆಂದು ತೋರಿದರೆ, ಆಂಟೆನಾ ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"ಮುಗಿದಿದೆ"</item>
- <item msgid="2480490326672924828">"ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡು"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"ಯಾವುದೇ ಚಾನಲ್‌ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"ಸ್ಕ್ಯಾನ್ ಯಾವುದೇ ಚಾನಲ್‌ಗಳನ್ನು ಪತ್ತೆ ಮಾಡಿಲ್ಲ. ನಿಮ್ಮ ಟಿವಿಯನ್ನು ಟಿವಿ ಸಿಗ್ನಲ್‌ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nನೀವು ಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಇದನ್ನು ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"ಸ್ಕ್ಯಾನ್ ಯಾವುದೇ ಚಾನಲ್‌ಗಳನ್ನು ಪತ್ತೆ ಮಾಡಿಲ್ಲ. USB ಟ್ಯೂನಲ್ ಅನ್ನು ಪ್ಲಗ್ ಇನ್ ಮಾಡಲಾಗಿದೆಯೇ ಮತ್ತು ಟಿವಿ ಸಿಗ್ನಲ್ ಮೂಲಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆಯೆ ಎಂದು ಪರಿಶೀಲಿಸಿ.\n\nಪ್ರಸಾರದ ಮೂಲಕ ಆಂಟೆನಾ ಬಳಸುತ್ತಿದ್ದರೆ, ಅದರ ಸ್ಥಾನ ಅಥವಾ ದಿಕ್ಕನ್ನು ಸರಿಹೊಂದಿಸಿ. ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗೆ, ಎತ್ತರದಲ್ಲಿ ಮತ್ತು ಕಿಟಕಿಯ ಬಳಿ ಇರಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"ಮತ್ತೆ ಸ್ಕ್ಯಾನ್ ಮಾಡು"</item>
- <item msgid="2092797862490235174">"ಮುಗಿದಿದೆ"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"ಟಿವಿ ಚಾನಲ್‌ಗಳನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಿ"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"ಟಿವಿ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB ಟಿವಿ ಟ್ಯೂನರ್ ಸೆಟಪ್"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB ಟಿವಿ ಟ್ಯೂನರ್ ಸಂಪರ್ಕ ಕಡಿತಗೊಂಡಿದೆ."</string>
-</resources>
diff --git a/usbtuner-res/values-ko/strings.xml b/usbtuner-res/values-ko/strings.xml
index 2c67ab6f..fa5b6e60 100644
--- a/usbtuner-res/values-ko/strings.xml
+++ b/usbtuner-res/values-ko/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV 튜너"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB TV 튜너"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"사용"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"사용 안함"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"네트워크 TV 튜너(BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"처리가 완료될 때까지 기다려 주세요."</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"채널 소스 선택"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"신호 없음"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g>에 맞추지 못함"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"조정 실패"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"튜너 소프트웨어가 최근 업데이트되었습니다. 채널을 다시 스캔하세요."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"오디오를 사용하려면 시스템 사운드 설정에서 서라운드 사운드를 사용 설정하세요."</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"오디오를 재생할 수 없습니다. 다른 TV를 사용해 보세요."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"채널 튜너 설정"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"TV 튜너 설정"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB 채널 튜너 설정"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"네트워크 튜너 설정"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"TV가 TV 신호 소스에 연결되어 있는지 확인하세요.\n\n무선 안테나를 사용하는 경우 대부분의 채널을 수신하려면 위치나 방향을 조정해야 할 수도 있습니다. 안테나를 창가 가까이에 높게 설치하면 가장 좋습니다."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"USB 튜너가 전원 및 TV 신호 소스에 연결되어 있는지 확인하세요.\n\n무선 안테나를 사용 중인 경우 안테나 위치나 방향을 조정하세요. 창가 가까이에 높게 설치하면 가장 좋습니다."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"네트워크 튜너의 전원이 켜져 있고 TV 신호 소스에 연결되어 있는지 확인하세요.\n\n무선 안테나를 사용하는 경우 안테나 위치나 방향을 조정하세요. 최상의 결과를 얻으려면 안테나를 창가 가까이에 높게 설치하세요."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"계속"</item>
<item msgid="727245208787621142">"나중에"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"채널 설정을 다시 실행하시겠습니까?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"이렇게 하면 TV 튜너에서 찾은 채널을 삭제하고 새로운 채널을 다시 스캔하게 됩니다.\n\nTV가 TV 신호 소스에 연결되어 있는지 확인하세요.\n\n무선 안테나를 사용하는 경우 대부분의 채널을 수신하려면 위치나 방향을 조정해야 할 수 있습니다. 안테나를 창가 가까이에 높게 설치하면 가장 좋습니다."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"이 작업을 수행하면 USB 튜너에서 찾은 채널이 삭제되며 새로운 채널을 다시 스캔합니다.\n\nUSB 튜너가 전원 및 TV 신호 소스에 연결되어 있는지 확인하세요.\n\n무선 안테나를 사용 중인 경우 안테나 위치나 방향을 조정하세요. 창가 가까이에 높게 설치하면 가장 좋습니다."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"네트워크 튜너에서 찾은 채널이 삭제되며 새로운 채널을 다시 스캔합니다.\n\n네트워크 튜너의 전원이 켜져 있고 TV 신호 소스에 연결되어 있는지 확인하세요.\n\n무선 안테나를 사용하는 경우 안테나 위치나 방향을 조정하세요. 최상의 결과를 얻으려면 안테나를 창가 가까이에 높게 설치하고 다시 스캔해보세요."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"계속"</item>
<item msgid="235450158666155406">"취소"</item>
@@ -54,8 +53,9 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"TV 튜너 설정"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB 채널 튜너 설정"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"네트워크 채널 튜너 설정"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"이 작업은 몇 분 정도 걸릴 수 있습니다."</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"일시적으로 튜너를 사용할 수 없거나 녹화에서 이미 사용하고 있습니다."</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"일시적으로 튜너를 사용할 수 없거나 이미 녹화에 사용하고 있습니다."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
<item quantity="other">채널 %1$d개 발견</item>
<item quantity="one">채널 %1$d개 발견</item>
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"채널 없음"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"스캔 결과 채널을 찾지 못했습니다. TV가 TV 신호 소스에 연결되어 있는지 확인하세요.\n\n무선 안테나를 사용하는 경우 위치나 방향을 조정하세요. 안테나를 창가 가까이에 높게 설치하면 가장 좋습니다."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"스캔하여 채널을 찾을 수 없습니다. USB 튜너가 전원 및 TV 신호 소스에 연결되어 있는지 확인하세요.\n\n무선 안테나를 사용 중인 경우 안테나 위치나 방향을 조정하세요. 창가 가까이에 높게 설치하면 가장 좋습니다. 그런 다음 다시 스캔해 보세요."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"스캔 결과 채널을 찾지 못했습니다. 네트워크 튜너의 전원이 켜져 있고 TV 신호 소스에 연결되어 있는지 확인하세요.\n\n무선 안테나를 사용하는 경우 안테나 위치나 방향을 조정하세요. 최상의 결과를 얻으려면 안테나를 창가 가까이에 높게 설치하고 다시 스캔해보세요."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"다시 스캔"</item>
<item msgid="2092797862490235174">"완료"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"TV 채널 스캔"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV 튜너 설정"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV 튜너 설정"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV 튜너 연결 끊어짐"</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"TV 채널 스캔"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV 튜너 설정"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV 튜너 설정"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"네트워크 TV 튜너 설정"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV 튜너의 연결이 끊겼습니다."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"네트워크 튜너의 연결이 끊겼습니다."</string>
</resources>
diff --git a/usbtuner-res/values-ky-rKG/strings.xml b/usbtuner-res/values-ky-rKG/strings.xml
new file mode 100644
index 00000000..18118225
--- /dev/null
+++ b/usbtuner-res/values-ky-rKG/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"Сыналгы күүлөгүчү"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB сыналгы күүлөгүчү"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Тармактык ТВ-тюнер (БЕТА)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Иштетүүнү бүтүрүү үчүн күтө туруңуз"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Күүлөгүчтүн программасы жакында жаңыртылды. Каналдарды кайрадан издеңиз."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Каналдын үнүн чыгаруу үчүн тутумдун үн жөндөөлөрүнө өтүп, көлөмдүү добушту иштетүү керек"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Аудио ойнотулбай жатат. Башка каналды байкап көрүңүз"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Канал күүлөгүчтү жөндөө"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"Сыналгынын күүлөгүчүн жөндөө"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB канал күүлөгүчүнүн жөндөөсү"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Тармактык тюнерди жөндөө"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Сыналдыңыз сыналгынын сигнал булагына туташтырылганын текшериңиз. \n\nЭгер телеантенна колдонулуп жатса, анын ордун же багытын тууралаңыз. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB күүлөгүч сайылып турганын жана сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, көпчүлүк каналдарды табуу үчүн анын ордун же багытын тууралашыңыз керек болот. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Тармактык тюнер сайылып турганын жана сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, каналдарды табуу үчүн анын ордун же багытын тууралашыңыз керек болот. Антенна жакшы кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеп көрүңүз."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Улантуу"</item>
+ <item msgid="727245208787621142">"Азыр эмес"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Канал кайра жөндөлсүнбү?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Ушуну менен сыналгынын күүлөгүчүнөн табылган каналдар алынып салынып, жаңы каналдар кайра изделет.\n\nСыналдыңыз сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nIЭгер телеантенна колдонулуп жатса, көпчүлүк каналдарды табуу үчүн анын ордун же багытын тууралашыңыз керек болот. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"Ушуну менен USB күүлөгүчтөн табылган каналдар алынып салынып, жаңы каналдар кайра изделет.\n\nUSB күүлөгүч сайылып турганын жана сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, көпчүлүк каналдарды табуу үчүн анын ордун же багытын тууралашыңыз керек болот. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Ушуну менен тармактык тюнер аркылуу табылган каналдар алынып салынып, жаңы каналдар кайра изделет.\n\nТармактык тюнер сайылып турганын жана сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, каналдарды табуу үчүн анын ордун же багытын тууралашыңыз керек болот. Антенна жакшы кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеп көрүңүз."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Улантуу"</item>
+ <item msgid="235450158666155406">"Токтотуу"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Туташуу түрүн тандаңыз"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Күүлөгүчтө туташтырылган тышкы антенна болсо, Антеннаны тандаңыз. Эгер каналдарыңыз кабелдик кызмат камсыздоочусунан алынса, Кабелди тандаңыз. Эгер так билбесеңиз, эки түрү тең изделет, бирок ал узагыраак созулушу мүмкүн."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Антенна"</item>
+ <item msgid="2670079958754180142">"Кабель"</item>
+ <item msgid="36774059871728525">"Так айта албайм"</item>
+ <item msgid="6881204453182153978">"Иштеп чыгуучулар үчүн гана"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"Сыналгы күүлөгүчүн жөндөө"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB канал күүлөгүчүн жөндөө"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Тармактык каналдын тюнерин жөндөө"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Бир нече мүнөт созулушу мүмкүн"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Тюнер убактылуу жеткиликсиз же жаздыруу үчүн колдонулууда."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d канал табылды</item>
+ <item quantity="one">%1$d канал табылды</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"КАНАЛ ИЗДӨӨНҮ ТОКТОТУУ"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d канал табылды</item>
+ <item quantity="one">%1$d канал табылды</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">Сонун! %1$d канал табылды. Керектүү каналдар табылбаса, антеннанын багытын өзгөртүп, кайра издеп көрүңүз.</item>
+ <item quantity="one">Сонун! %1$d канал табылды. Керектүү каналдар табылбаса, антеннанын багытын өзгөртүп, кайра издеп көрүңүз.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Бүттү"</item>
+ <item msgid="2480490326672924828">"Кайра издөө"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Бир да канал табылган жок"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Издөөдөн эч бир канал табылган жок. Сыналдыңыз сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, анын ордун же багытын тууралаңыз. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Издөөдөн эч бир канал табылган жок. USB күүлөгүч сайылып турганын жана сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, анын ордун же багытын тууралаңыз. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Каналдар табылган жок. Тармактык тюнер сайылып турганын жана сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, анын ордун же багытын тууралаңыз. Антенна жакшы кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеп көрүңүз."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Кайра издөө"</item>
+ <item msgid="2092797862490235174">"Бүттү"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Сыналгы каналдарын издөө"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"ТВ-тюнерди жөндөө"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB ТВ-тюнерин жөндөө"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Тармактык ТВ-тюнерди жөндөө"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV күүлөгүчү ажыратылды."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Тармак күүлөгүчү ажыратылды."</string>
+</resources>
diff --git a/usbtuner-res/values-ky/strings.xml b/usbtuner-res/values-ky/strings.xml
deleted file mode 100644
index 39e9d1df..00000000
--- a/usbtuner-res/values-ky/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"Сыналгы күүлөгүчү"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB сыналгы күүлөгүчү"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Күйүк"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Өчүк"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Иштетүүнү бүтүрүү үчүн күтө туруңуз"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Каналыңыздын булагын тандаңыз"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Сигнал жок"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> каналы кармалган жок"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Канал кармалбай койду"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Күүлөгүчтүн программасы жакында жаңыртылды. Каналдарды кайрадан издеңиз."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Каналдын үнүн чыгаруу үчүн тутумдун үн жөндөөлөрүнө өтүп, көлөмдүү добушту иштетүү керек"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Канал күүлөгүчтү жөндөө"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"Сыналгынын күүлөгүчүн жөндөө"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB канал күүлөгүчүнүн жөндөөсү"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Сыналдыңыз сыналгынын сигнал булагына туташтырылганын текшериңиз. \n\nЭгер телеантенна колдонулуп жатса, анын ордун же багытын тууралаңыз. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB күүлөгүч сайылып турганын жана сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, көпчүлүк каналдарды табуу үчүн анын ордун же багытын тууралашыңыз керек болот. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Улантуу"</item>
- <item msgid="727245208787621142">"Азыр эмес"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Канал кайра жөндөлсүнбү?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Ушуну менен сыналгынын күүлөгүчүнөн табылган каналдар алынып салынып, жаңы каналдар кайра изделет.\n\nСыналдыңыз сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nIЭгер телеантенна колдонулуп жатса, көпчүлүк каналдарды табуу үчүн анын ордун же багытын тууралашыңыз керек болот. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"Ушуну менен USB күүлөгүчтөн табылган каналдар алынып салынып, жаңы каналдар кайра изделет.\n\nUSB күүлөгүч сайылып турганын жана сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, көпчүлүк каналдарды табуу үчүн анын ордун же багытын тууралашыңыз керек болот. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Улантуу"</item>
- <item msgid="235450158666155406">"Токтотуу"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Туташуу түрүн тандаңыз"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Күүлөгүчтө туташтырылган тышкы антенна болсо, Антеннаны тандаңыз. Эгер каналдарыңыз кабелдик кызмат камсыздоочусунан алынса, Кабелди тандаңыз. Эгер так билбесеңиз, эки түрү тең изделет, бирок ал узагыраак созулушу мүмкүн."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Антенна"</item>
- <item msgid="2670079958754180142">"Кабель"</item>
- <item msgid="36774059871728525">"Так айта албайм"</item>
- <item msgid="6881204453182153978">"Иштеп чыгуучулар үчүн гана"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"Сыналгы күүлөгүчүн жөндөө"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB канал күүлөгүчүн жөндөө"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Бир нече мүнөт созулушу мүмкүн"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Тюнер убактылуу жеткиликсиз же жаздыруу үчүн колдонулууда."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d канал табылды</item>
- <item quantity="one">%1$d канал табылды</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"КАНАЛ ИЗДӨӨНҮ ТОКТОТУУ"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d канал табылды</item>
- <item quantity="one">%1$d канал табылды</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">Сонун! %1$d канал табылды. Керектүү каналдар табылбаса, антеннанын багытын өзгөртүп, кайра издеп көрүңүз.</item>
- <item quantity="one">Сонун! %1$d канал табылды. Керектүү каналдар табылбаса, антеннанын багытын өзгөртүп, кайра издеп көрүңүз.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Бүттү"</item>
- <item msgid="2480490326672924828">"Кайра издөө"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Бир да канал табылган жок"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Издөөдөн эч бир канал табылган жок. Сыналдыңыз сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, анын ордун же багытын тууралаңыз. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Издөөдөн эч бир канал табылган жок. USB күүлөгүч сайылып турганын жана сыналгынын сигнал булагына туташтырылганын текшериңиз.\n\nЭгер телеантенна колдонулуп жатса, анын ордун же багытын тууралаңыз. Мыкты кармашы үчүн аны бийик жана терезеге жакын жерге коюп, кайра издеңиз."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Кайра издөө"</item>
- <item msgid="2092797862490235174">"Бүттү"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Сыналгы каналдарын издөө"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Сыналгы күүлөгүчүн жөндөө"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB күүлөгүчүнүн жөндөөсү"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV күүлөгүчү ажыратылды."</string>
-</resources>
diff --git a/usbtuner-res/values-lo-rLA/strings.xml b/usbtuner-res/values-lo-rLA/strings.xml
new file mode 100644
index 00000000..306576a2
--- /dev/null
+++ b/usbtuner-res/values-lo-rLA/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"ຕົວຮັບສັນຍານໂທລະພາບ"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"ຕົວຮັບສັນຍານໂທລະພາບ USB"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Network TV Tuner (ເບຕ້າ)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"ກະລຸນາລໍຖ້າເພື່ອປະມວນຜົນໃຫ້ສຳເລັດ"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"ຊອບແວຕົວປັບສັນຍານໄດ້ຮັບການອັບເດດເມື່ອບໍ່ດົນມານີ້ແລ້ວ. ກະລຸນາສະແກນຫາຊ່ອງຄືນໃໝ່."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ເປີດໃຊ້ສຽງຮອບທິດທາງໃນການຕັ້ງຄ່າລະບົບສຽງເພື່ອເປີດໃຊ້ສຽງ."</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Cannot play audio. Please try another TV"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ຕັ້ງເຄື່ອງຮັບສັນຍານຊ່ອງ"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"ຕັ້ງຄ່າຕົວຮັບສັນຍານໂທລະພາບ"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"ຕັ້ງເຄື່ອງຮັບສັນຍານຊ່ອງ USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Network tuner setup"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"ໃຫ້ກວດສອບວ່າທ່ານເຊື່ອມຕໍ່ໂທລະພາບຂອງທ່ານຫາແຫລ່ງສັນຍານໂທລະພາບແລ້ວ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"ກວດສອບເບິ່ງເຄື່ອງຮັບສັນຍານ USB ວ່າ ໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"ກວດສອບເບິ່ງເຄື່ອງຮັບສັນຍານເຄືອຂ່າຍວ່າ ໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫຼຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ່ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"ສືບຕໍ່"</item>
+ <item msgid="727245208787621142">"ບໍ່ແມ່ນຕອນນີ້"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"ຕັ້ງຄ່າຊ່ອງຄືນໃໝ່ບໍ່?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"ນີ້ເປັນການລຶບຊ່ອງທີ່ພົບແລ້ວອອກໄປຈາກຕົວຮັບສັນຍານໂທລະພາບ ແລະ ສະແກນຫາຊ່ອງໃໝ່ອີກຄັ້ງ.\n\nກວດສອບເບິ່ງຕົວຮັບສັນຍານໂທລະພາບວ່າໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"ນີ້ຈະເປັນການລຶບຊ່ອງທີ່ພົບແລ້ວອອກໄປຈາກເຄື່ອງຮັບສັນຍານ USB ແລະ ສະແກນຫາຊ່ອງໃໝ່ອີກ.\n\nໃຫ້ກວດສອບເບິ່ງເຄື່ອງຮັບສັນຍານ USB ວ່າ ໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"ນີ້ຈະເປັນການລຶບຊ່ອງທີ່ພົບແລ້ວອອກໄປຈາກເຄື່ອງຮັບສັນຍານເຄືອຂ່າຍ ແລະ ສະແກນຫາຊ່ອງໃໝ່ອີກຄັ້ງ.\n\nໃຫ້ກວດສອບເບິ່ງເຄື່ອງຮັບສັນຍານເຄືອຂ່າຍວ່າໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫາກໃຊ້ເສົາອາກາດ, ທ່ານອາດຈະຕ້ອງໄດ້ປັບການຕັ້ງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນດີຂຶ້ນ, ວາງມັນໄວ້ສູງ ແລະ ໃກ້ກັບປ່ອງຢ້ຽມແລ້ວສະແກນໃໝ່ອີກຄັ້ງ."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"ສືບຕໍ່"</item>
+ <item msgid="235450158666155406">"ຍົກເລີກ"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"ເລືອກປະເພດການເຊື່ອມຕໍ່"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"ເລືອກເສົາອາກາດ ຖ້າມີເສົາອາກາດແບບແຍກທີ່ເຊື່ອມຕໍ່ກັບເຄື່ອງຮັບສັນຍານ. ເລືອກສາຍເຄເບິ້ນ ຖ້າຊ່ອງຂອງທ່ານມາຈາກຜູ້ໃຫ້ບໍລິການສາຍເຄເບິ້ນ. ຖ້າທ່ານບໍ່ແນ່ໃຈ, ຈະມີການສະແກນທັງສອງປະເພດ, ແຕ່ແບບນີ້ຈະໃຊ້ເວລາດົນກວ່າ."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"ເສົາອາກາດ"</item>
+ <item msgid="2670079958754180142">"ສາຍຕໍ່"</item>
+ <item msgid="36774059871728525">"ບໍ່ແນ່ໃຈ"</item>
+ <item msgid="6881204453182153978">"ການພັດທະນາເທົ່ານັ້ນ"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"ຕັ້ງຄ່າຕົວຮັບສັນຍານໂທລະພາບ"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"ການຕັ້ງເຄື່ອງຮັບສັນຍານຊ່ອງ USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"ຕັ້ງຄ່າຕົວຈູນສັນຍານຊ່ອງເຄືອຂ່າຍ"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"ຂັ້ນຕອນນີ້ອາດຈະໃຊ້ເວລາຫຼາຍນາທີ"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ຈູນເນີບໍ່ສາມາດໃຊ້ໄດ້ຊົ່ວຄາວ ຫຼື ຖືກໃຊ້ໂດຍການບັນທຶກໃດໜຶ່ງຢູ່ກ່ອນແລ້ວ."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">ພົບ %1$d ຊ່ອງ</item>
+ <item quantity="one">ພົບ %1$d ຊ່ອງ</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"ຢຸດການສະແກນຊ່ອງ"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">ພົບ %1$d ຊ່ອງ</item>
+ <item quantity="one">ພົບ %1$d ຊ່ອງ</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">ດີຫຼາຍ! ພົບ %1$d ຊ່ອງໃນລະຫວ່າງການສະແກນຫາຊ່ອງ. ຖ້ານີ້ປາກົດວ່າບໍ່ຖືກຕ້ອງ, ໃຫ້ລອງປັບຕຳແໜ່ງເສົາອາກາດ ແລ້ວສະແກນໃໝ່.</item>
+ <item quantity="one">ດີຫຼາຍ! ພົບ %1$d ຊ່ອງໃນລະຫວ່າງການສະແກນຫາຊ່ອງ. ຖ້ານີ້ປາກົດວ່າບໍ່ຖືກຕ້ອງ, ໃຫ້ລອງປັບຕຳແໜ່ງເສົາອາກາດ ແລ້ວສະແກນໃໝ່.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"ແລ້ວໆ"</item>
+ <item msgid="2480490326672924828">"ສະແກນອີກ"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"ບໍ່ພົບຊ່ອງໃດ"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"ການສະແກນບໍ່ພົບຊ່ອງໃດໆເລີຍ. ໃຫ້ຢັ້ງຢືນວ່າທ່ານເຊື່ອມຕໍ່ໂທລະພາບຂອງທ່ານຫາແຫລ່ງສັນຍານໂທລະພາບແລ້ວ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"ການສະແກນບໍ່ພົບຊ່ອງໃດ. ໃຫ້ກວດສອບເບິ່ງເຄື່ອງຮັບສັນຍານ USB ວ່າໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"ການສະແກນບໍ່ພົບຊ່ອງໃດ. ໃຫ້ກວດສອບເບິ່ງເຄື່ອງຮັບສັນຍານເຄືອຂ່າຍວ່າໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"ສະແກນອີກ"</item>
+ <item msgid="2092797862490235174">"ແລ້ວໆ"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"ສະແກນຫາຊ່ອງໂທລະທັດ"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"ຕັ້ງຄ່າຕົວຮັບສັນຍານໂທລະທັດ"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"ຕັ້ງຄ່າຕົວຮັບສັນຍານໂທລະທັດແບບ USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"ຕັ້ງຄ່າຕົວຮັບສັນຍານໂທລະທັດເຄືອຂ່າຍ"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"ຕັດການເຊື່ອມຕໍ່ USB TV tuner ແລ້ວ."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"ຕັດການເຊື່ອມຕໍ່ຕົວຈູນສັນຍານເຄືອຂ່າຍແລ້ວ."</string>
+</resources>
diff --git a/usbtuner-res/values-lo/strings.xml b/usbtuner-res/values-lo/strings.xml
deleted file mode 100644
index 954baabe..00000000
--- a/usbtuner-res/values-lo/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"ຕົວຮັບສັນຍານໂທລະພາບ"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"ຕົວຮັບສັນຍານໂທລະພາບ USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"ເປີດ"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"ປິດ"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"ກະລຸນາລໍຖ້າເພື່ອປະມວນຜົນໃຫ້ສຳເລັດ"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"ເລືອກແຫຼ່ງສັນຍານຊ່ອງຂອງທ່ານ"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"ບໍ່ມີສັນຍານ"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"ປັບຫາ <xliff:g id="CHANNEL_NAME">%s</xliff:g> ບໍ່ສຳເລັດ"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ປັບຊ່ອງບໍ່ສຳເລັດ"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"ຊອບແວຕົວປັບສັນຍານໄດ້ຮັບການອັບເດດເມື່ອບໍ່ດົນມານີ້ແລ້ວ. ກະລຸນາສະແກນຫາຊ່ອງຄືນໃໝ່."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ເປີດໃຊ້ສຽງຮອບທິດທາງໃນການຕັ້ງຄ່າລະບົບສຽງເພື່ອເປີດໃຊ້ສຽງ."</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ຕັ້ງເຄື່ອງຮັບສັນຍານຊ່ອງ"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"ຕັ້ງຄ່າຕົວຮັບສັນຍານໂທລະພາບ"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"ຕັ້ງເຄື່ອງຮັບສັນຍານຊ່ອງ USB"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"ໃຫ້ກວດສອບວ່າທ່ານເຊື່ອມຕໍ່ໂທລະພາບຂອງທ່ານຫາແຫລ່ງສັນຍານໂທລະພາບແລ້ວ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"ກວດສອບເບິ່ງເຄື່ອງຮັບສັນຍານ USB ວ່າ ໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"ສືບຕໍ່"</item>
- <item msgid="727245208787621142">"ບໍ່ແມ່ນຕອນນີ້"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"ຕັ້ງຄ່າຊ່ອງຄືນໃໝ່ບໍ່?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"ນີ້ເປັນການລຶບຊ່ອງທີ່ພົບແລ້ວອອກໄປຈາກຕົວຮັບສັນຍານໂທລະພາບ ແລະ ສະແກນຫາຊ່ອງໃໝ່ອີກຄັ້ງ.\n\nກວດສອບເບິ່ງຕົວຮັບສັນຍານໂທລະພາບວ່າໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"ນີ້ຈະເປັນການລຶບຊ່ອງທີ່ພົບແລ້ວອອກໄປຈາກເຄື່ອງຮັບສັນຍານ USB ແລະ ສະແກນຫາຊ່ອງໃໝ່ອີກ.\n\nໃຫ້ກວດສອບເບິ່ງເຄື່ອງຮັບສັນຍານ USB ວ່າ ໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"ສືບຕໍ່"</item>
- <item msgid="235450158666155406">"ຍົກເລີກ"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"ເລືອກປະເພດການເຊື່ອມຕໍ່"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"ເລືອກເສົາອາກາດ ຖ້າມີເສົາອາກາດແບບແຍກທີ່ເຊື່ອມຕໍ່ກັບເຄື່ອງຮັບສັນຍານ. ເລືອກສາຍເຄເບິ້ນ ຖ້າຊ່ອງຂອງທ່ານມາຈາກຜູ້ໃຫ້ບໍລິການສາຍເຄເບິ້ນ. ຖ້າທ່ານບໍ່ແນ່ໃຈ, ຈະມີການສະແກນທັງສອງປະເພດ, ແຕ່ແບບນີ້ຈະໃຊ້ເວລາດົນກວ່າ."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"ເສົາອາກາດ"</item>
- <item msgid="2670079958754180142">"ສາຍຕໍ່"</item>
- <item msgid="36774059871728525">"ບໍ່ແນ່ໃຈ"</item>
- <item msgid="6881204453182153978">"ການພັດທະນາເທົ່ານັ້ນ"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"ຕັ້ງຄ່າຕົວຮັບສັນຍານໂທລະພາບ"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"ການຕັ້ງເຄື່ອງຮັບສັນຍານຊ່ອງ USB"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"ຂັ້ນຕອນນີ້ອາດຈະໃຊ້ເວລາຫຼາຍນາທີ"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ຈູນເນີບໍ່ສາມາດໃຊ້ໄດ້ຊົ່ວຄາວ ຫຼື ຖືກໃຊ້ໂດຍການບັນທຶກໃດໜຶ່ງຢູ່ກ່ອນແລ້ວ."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">ພົບ %1$d ຊ່ອງ</item>
- <item quantity="one">ພົບ %1$d ຊ່ອງ</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"ຢຸດການສະແກນຊ່ອງ"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">ພົບ %1$d ຊ່ອງ</item>
- <item quantity="one">ພົບ %1$d ຊ່ອງ</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">ດີຫຼາຍ! ພົບ %1$d ຊ່ອງໃນລະຫວ່າງການສະແກນຫາຊ່ອງ. ຖ້ານີ້ປາກົດວ່າບໍ່ຖືກຕ້ອງ, ໃຫ້ລອງປັບຕຳແໜ່ງເສົາອາກາດ ແລ້ວສະແກນໃໝ່.</item>
- <item quantity="one">ດີຫຼາຍ! ພົບ %1$d ຊ່ອງໃນລະຫວ່າງການສະແກນຫາຊ່ອງ. ຖ້ານີ້ປາກົດວ່າບໍ່ຖືກຕ້ອງ, ໃຫ້ລອງປັບຕຳແໜ່ງເສົາອາກາດ ແລ້ວສະແກນໃໝ່.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"ແລ້ວໆ"</item>
- <item msgid="2480490326672924828">"ສະແກນອີກ"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"ບໍ່ພົບຊ່ອງໃດ"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"ການສະແກນບໍ່ພົບຊ່ອງໃດໆເລີຍ. ໃຫ້ຢັ້ງຢືນວ່າທ່ານເຊື່ອມຕໍ່ໂທລະພາບຂອງທ່ານຫາແຫລ່ງສັນຍານໂທລະພາບແລ້ວ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"ການສະແກນບໍ່ພົບຊ່ອງໃດ. ໃຫ້ກວດສອບເບິ່ງເຄື່ອງຮັບສັນຍານ USB ວ່າໄດ້ສຽບສາຍ ແລະ ເຊື່ອມຕໍ່ກັບແຫຼ່ງສັນຍານໂທລະພາບແລ້ວຫຼືຍັງ.\n\nຫາກໃຊ້ເສົາອາກາດ, ໃຫ້ຍ້າຍບ້ອນວາງ ຫຼື ທິດທາງຂອງມັນ. ເພື່ອໃຫ້ໄດ້ຜົນທີ່ດີທີ່ສຸດ, ໃຫ້ວາງໄວ້ບ່ອນສູງໃກ້ໆປ່ອງຢ້ຽມ ແລ້ວລອງສະແກນໃໝ່."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"ສະແກນອີກ"</item>
- <item msgid="2092797862490235174">"ແລ້ວໆ"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"ສະແກນຫາຊ່ອງໂທລະພາບ"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"ຕັ້ງຄ່າຕົວຮັບສັນຍານໂທລະພາບ"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"ຕັ້ງຄ່າຕົວຮັບສັນຍານໂທລະພາບແບບ USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"ການເຊື່ອມຕໍ່ USB TV tuner ຖືກຕັດແລ້ວ."</string>
-</resources>
diff --git a/usbtuner-res/values-lt/strings.xml b/usbtuner-res/values-lt/strings.xml
index 3ce2efc7..c55020bd 100644
--- a/usbtuner-res/values-lt/strings.xml
+++ b/usbtuner-res/values-lt/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV imtuvas"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB TV imtuvas"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Įjungta"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Išjungti"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Tinklo TV imtuvas (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Palaukite, kol baigsis apdorojimas"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Pasirinkite kanalo šaltinį"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Nėra signalo"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Nepavyko įjungti kanalo „<xliff:g id="CHANNEL_NAME">%s</xliff:g>“"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Nepavyko suderinti"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Imtuvo programinė įranga buvo neseniai atnaujinta. Iš naujo nuskaitykite kanalus."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Įgalinkite erdvinį garsą sistemos garso nustatymuose, kad galėtumėte įgalinti garsą"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Negalima paleisti garso įrašo. Bandykite naudoti kitą TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanalų imtuvo sąranka"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"TV imtuvo sąranka"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB kanalų imtuvo sąranka"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Tinklo imtuvo sąranka"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Įsitikinkite, kad jūsų TV prijungtas prie TV signalo šaltinio.\n\nJei naudojate belaidę anteną, koreguokite jos vietą arba kryptį. Kad pasiektumėte geriausių rezultatų, ją padėkite aukštai prie lango."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Įsitikinkite, kad USB imtuvas prijungtas prie maitinimo ir TV signalo šaltinio.\n\nJei naudojate belaidę anteną, koreguokite jos vietą arba kryptį, kad būtų rodoma kuo daugiau kanalų. Kad pasiektumėte geriausių rezultatų, ją padėkite aukštai prie lango."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Įsitikinkite, kad tinklo imtuvas yra įjungtas ir prijungtas prie TV signalo šaltinio.\n\nJei naudojate belaidę anteną, koreguokite jos vietą arba kryptį. Kad pasiektumėte geriausių rezultatų, ją padėkite aukštai prie lango ir nuskaitykite dar kartą."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Tęsti"</item>
<item msgid="727245208787621142">"Ne dabar"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Iš naujo vykdyti kanalų sąranką?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Tai atlikus bus pašalinti kanalai, kuriuos aptiko TV imtuvas, ir bus vėl ieškoma naujų kanalų.\n\nNuskaičius nerasta jokių kanalų. Įsitikinkite, kad jūsų TV prijungtas prie TV signalo šaltinio.\n\nJei naudojate belaidę anteną, koreguokite jos vietą arba kryptį. Kad pasiektumėte geriausių rezultatų, ją padėkite aukštai prie lango."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Taip bus pašalinti rasti kanalai iš USB imtuvo ir nauji kanalai nuskaityti dar kartą.\n\nĮsitikinkite, kad USB imtuvas prijungtas prie maitinimo ir TV signalo šaltinio.\n\nJei naudojate belaidę anteną, koreguokite jos vietą arba kryptį, kad būtų rodoma kuo daugiau kanalų. Kad pasiektumėte geriausių rezultatų, ją padėkite aukštai prie lango."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Atlikus šį veiksmą iš tinklo imtuvo bus pašalinti rasti kanalai ir bus dar kartą nuskaitoma ieškant naujų kanalų.\n\nĮsitikinkite, kad tinklo imtuvas yra įjungtas ir prijungtas prie TV signalo šaltinio.\n\nJei naudojate belaidę anteną, koreguokite jos vietą arba kryptį. Kad pasiektumėte geriausių rezultatų, ją padėkite aukštai prie lango ir nuskaitykite dar kartą."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Tęsti"</item>
<item msgid="235450158666155406">"Atšaukti"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"TV imtuvo sąranka"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB kanalų imtuvo sąranka"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Tinklo kanalų imtuvo sąranka"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Tai gali užtrukti kelias minutes"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Derintuvas laikinai nepasiekiamas arba jau yra naudojamas įrašant."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -82,12 +82,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Nerasta kanalų"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Nuskaičius nerasta jokių kanalų. Įsitikinkite, kad jūsų TV prijungtas prie TV signalo šaltinio.\n\nJei naudojate belaidę anteną, koreguokite jos vietą arba kryptį. Kad pasiektumėte geriausių rezultatų, ją padėkite aukštai prie lango ir nuskaitykite dar kartą."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Nuskaitant nerasta kanalų. Patvirtinkite, ar USB imtuvas prijungtas prie TV signalo šaltinio.\n\nJei naudojate belaidę anteną, koreguokite jos vietą arba kryptį. Kad pasiektumėte geriausių rezultatų, ją padėkite aukštai prie lango ir nuskaitykite dar kartą."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Nuskaičius nerasta jokių kanalų. Įsitikinkite, kad tinklo imtuvas yra įjungtas ir prijungtas prie TV signalo šaltinio.\n\nJei naudojate belaidę anteną, koreguokite jos vietą arba kryptį. Kad pasiektumėte geriausių rezultatų, ją padėkite aukštai prie lango ir nuskaitykite dar kartą."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Nuskaityti dar kartą"</item>
<item msgid="2092797862490235174">"Atlikta"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Vykdykite TV kanalų nuskaitymą"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV imtuvo sąranka"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV imtuvo sąranka"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV imtuvas atjungtas."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Nuskaitykite TV kanalus"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV imtuvo sąranka"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV imtuvo sąranka"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Tinklo TV imtuvo sąranka"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV imtuvas atjungtas."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Tinklo imtuvas atjungtas."</string>
</resources>
diff --git a/usbtuner-res/values-lv/strings.xml b/usbtuner-res/values-lv/strings.xml
index 9337e7b3..df910fab 100644
--- a/usbtuner-res/values-lv/strings.xml
+++ b/usbtuner-res/values-lv/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV kanālu meklētājs"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB TV kanālu meklētājs"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Ieslēgta"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Izslēgta"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Interneta TV kanālu meklētājs (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Lūdzu, uzgaidiet, līdz tiks pabeigta apstrāde!"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Atlasiet kanāla avotu"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Nav signāla"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Neizdevās atrast kanālu <xliff:g id="CHANNEL_NAME">%s</xliff:g>."</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Neizdevās atrast"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Nesen tika atjaunināta kanālu meklētāja programmatūra. Lūdzu, atkārtoti meklējiet kanālus."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Lai ieslēgtu audio, sistēmas skaņas iestatījumos iespējojiet ieskaujošo skaņu."</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Nevar atskaņot audio. Lūdzu, izmantojiet citu televizoru."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanālu meklētāja iestatīšana"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"TV kanālu meklētāja iestatīšana"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB kanālu meklētāja iestatīšana"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Interneta kanālu meklētāja iestatīšana"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Pārbaudiet, vai televizors ir pievienots TV signāla avotam.\n\nJa izmantojat bezvadu antenu, iespējams, būs jāmaina tās novietojums vai virziens, lai uztvertu lielāko daļu kanālu. Lai iegūtu labākos rezultātus, novietojiet antenu augstu pie loga."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Pārbaudiet, vai USB kanālu meklētājs ir pievienots strāvas avotam un TV signāla avotam.\n\nJa izmantojat bezvadu antenu, mainiet tās novietojumu un virzienu. Lai iegūtu labākos rezultātus, novietojiet antenu augstu pie loga un atkārtojiet kanālu meklēšanu."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Pārbaudiet, vai interneta kanālu meklētājs ir ieslēgts un pievienots TV signāla avotam.\n\nJa izmantojat bezvadu antenu, iespējams, jāmaina tās novietojums vai virziens, lai uztvertu lielāko daļu kanālu. Lai iegūtu labākos rezultātus, novietojiet antenu augstu pie loga."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Turpināt"</item>
<item msgid="727245208787621142">"Vēlāk"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Vai atkārtot kanālu iestatīšanu?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Šādi no TV kanālu meklētāja tiks noņemti atrastie kanāli un tiks vēlreiz meklēti jauni kanāli.\n\nPārbaudiet, vai televizors ir pievienots TV signāla avotam.\n\nJa izmantojat bezvadu antenu, iespējams, būs jāmaina tās novietojums vai virziens, lai uztvertu lielāko daļu kanālu. Lai iegūtu labākos rezultātus, novietojiet antenu augstu pie loga."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Tādējādi tiks noņemti kanāli, kas tika atrasti ar USB kanālu meklētāju, un tiks atkārtota kanālu meklēšana.\n\nPārbaudiet, vai USB kanālu meklētājs ir pievienots strāvas avotam un TV signāla avotam.\n\nJa izmantojat bezvadu antenu, mainiet tās novietojumu un virzienu, lai uztvertu lielāko daļu kanālu. Lai iegūtu labākos rezultātus, novietojiet antenu augstu pie loga."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Šādi no interneta kanālu meklētāja tiks noņemti atrastie kanāli un tiks vēlreiz meklēti jauni kanāli.\n\nPārbaudiet, vai interneta kanālu meklētājs ir ieslēgts un pievienots TV signāla avotam.\n\nJa izmantojat bezvadu antenu, iespējams, jāmaina tās novietojums vai virziens, lai uztvertu lielāko daļu kanālu. Lai iegūtu labākos rezultātus, novietojiet antenu augstu pie loga."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Turpināt"</item>
<item msgid="235450158666155406">"Atcelt"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"TV kanālu meklētāja iestatīšana"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB kanālu meklētāja iestatīšana"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Interneta kanālu meklētāja iestatīšana"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Tas var ilgt vairākas minūtes."</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Kanālu meklētājs īslaicīgi nav pieejams, vai arī tas jau tiek izmantots ierakstīšanai."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -79,12 +79,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Netika atrasts neviens kanāls"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Veicot meklēšanu, netika atrasts neviens kanāls. Pārbaudiet, vai televizors pievienots TV signāla avotam.\n\nJa izmantojat bezvadu antenu, mainiet tās novietojumu vai virzienu. Lai iegūtu labākos rezultātus, novietojiet antenu augstu pie loga, bet pēc tam vēlreiz veiciet meklēšanu."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Netika atrasts neviens kanāls. Pārbaudiet, vai USB kanālu meklētājs ir pievienots strāvas avotam un TV signāla avotam.\n\nJa izmantojat bezvadu antenu, mainiet tās novietojumu un virzienu. Lai iegūtu labākos rezultātus, novietojiet antenu augstu pie loga un atkārtojiet kanālu meklēšanu."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Netika atrasts neviens kanāls. Pārbaudiet, vai interneta kanālu meklētājs ir ieslēgts un pievienots TV signāla avotam.\n\nJa izmantojat bezvadu antenu, mainiet tās novietojumu un virzienu. Lai iegūtu labākos rezultātus, novietojiet antenu augstu pie loga un atkārtojiet kanālu meklēšanu."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Meklēt vēlreiz"</item>
<item msgid="2092797862490235174">"Gatavs"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"TV kanālu meklēšana"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV kanālu meklētāja iestatīšana"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV kanālu meklētāja iestatīšana"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV kanālu meklētājs ir atvienots."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"TV kanālu meklēšana"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV kanālu meklētāja iestatīšana"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV kanālu meklētāja iestatīšana"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Interneta TV kanālu meklētāja iestatīšana"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV kanālu meklētājs ir atvienots."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Interneta kanālu meklētājs ir atvienots."</string>
</resources>
diff --git a/usbtuner-res/values-mk-rMK/strings.xml b/usbtuner-res/values-mk-rMK/strings.xml
new file mode 100644
index 00000000..2db086e1
--- /dev/null
+++ b/usbtuner-res/values-mk-rMK/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"ТВ приемник"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"ТВ приемник со USB"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Мрежен ТВ приемник (БЕТА)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Почекајте да заврши обработувањето"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Софтверот на приемникот неодамна е ажуриран. Скенирајте ги каналите повторно."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Овозможете опкружувачки звук во поставките за звуци на системот за да овозможите аудио"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Не може да се пушти аудио. Обидете се со друг ТВ"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Поставување приемник на канали"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"Поставување ТВ приемник"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"Поставување на USB-приемникот за канали"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Поставување мрежен приемник"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Потврдете дека телевизорот е приклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, можеби ќе треба да ја приспособите поставеноста или насоката за да примате најмногу канали. За најдобри резултати, поставете ја високо и во близина на прозорец."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"Потврдете дека USB-приемникот е приклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, можеби ќе треба да ја приспособите поставеноста или насоката за да примате најмногу канали. За најдобри резултати, поставете ја високо и во близина на прозорец."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Потврдете дека мрежниот приемник е вклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, може ќе треба да ја приспособите поставеноста или насоката за да примате најмногу канали. За најдобри резултати, поставете ја високо и во близина на прозорец."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Продолжи"</item>
+ <item msgid="727245208787621142">"Не сега"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Да се изврши поставувањето на каналите повторно?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Ова ќе ги отстрани каналите од ТВ приемникот и ќе скенира за нови канали повторно.\n\nПотврдете дека телевизорот е поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, приспособете ја поставеноста или насоката. За најдобри резултати, поставете ја високо и во близина на прозорец."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"Ова ќе ги отстрани каналите од USB-приемникот и ќе скенира за нови канали повторно.\n\nПотврдете дека USB-приемникот е приклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, можеби ќе треба да ја приспособите поставеноста или насоката за да примате најмногу канали. За најдобри резултати, поставете ја високо и во близина на прозорец."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Ова ќе ги отстрани каналите од мрежниот приемник и ќе скенира за нови канали повторно.\n\nПотврдете дека мрежниот приемник е вклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, може ќе треба да ја приспособите поставеноста или насоката. За најдобри резултати, поставете ја високо и во близина на прозорец."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Продолжи"</item>
+ <item msgid="235450158666155406">"Откажи"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Изберете го типот врска"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Изберете „Антена“ ако има надворешна антена поврзана со приемникот. Изберете „Кабел“ ако каналите ви ги обезбедува кабелски оператор. Ако не сте сигурни, и двата типа ќе се скенираат, но тоа може да трае подолго."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Антена"</item>
+ <item msgid="2670079958754180142">"Кабел"</item>
+ <item msgid="36774059871728525">"Не сум сигурен"</item>
+ <item msgid="6881204453182153978">"Само за програмери"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"Поставување ТВ приемник"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"Поставување на USB-приемникот за канали"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Поставување мрежен приемник на канали"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Ова може да трае неколку минути"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Приемникот е привремено недостапен или веќе се користи за снимање."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="one">Пронајден е %1$d канал</item>
+ <item quantity="other">Пронајдени се %1$d канали</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"ЗАПРИ ГО СКЕНИРАЊЕТО КАНАЛИ"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="one">Пронајден е %1$d канал</item>
+ <item quantity="other">Пронајдени се %1$d канали</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="one">Убаво! Пронајдени се %1$d канали во текот на скенирањето канали. Ако се чини дека тоа не е во ред, обидете се со приспособување на позицијата на антената и скенирајте повторно.</item>
+ <item quantity="other">Убаво! Пронајдени се %1$d канали во текот на скенирањето канали. Ако се чини дека тоа не е во ред, обидете се со приспособување на позицијата на антената и скенирајте повторно.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Готово"</item>
+ <item msgid="2480490326672924828">"Скенирај пак"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Не се пронајдени канали"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Скенирањето не пронајде ниеден канал. Потврдете дека телевизорот е поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, приспособете ја поставеноста или насоката. За најдобри резултати, поставете ја високо и во близина на прозорец и скенирајте повторно."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Скенирањето не пронајде ниеден канал. Потврдете дека USB-приемникот е приклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, приспособете ја поставеноста или насоката. За најдобри резултати, поставете ја високо и во близина на прозорец и скенирајте повторно."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Скенирањето не пронајде ниеден канал. Потврдете дека мрежниот приемник е вклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, приспособете ја поставеноста или насоката. За најдобри резултати, поставете ја високо и во близина на прозорец, па скенирајте повторно."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Скенирај пак"</item>
+ <item msgid="2092797862490235174">"Готово"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Скенирајте ТВ-канали"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Поставување ТВ приемник"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Поставување ТВ приемник со USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Поставување мрежен ТВ приемник"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-приемникот за TV е исклучен."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Мрежниот приемник е исклучен."</string>
+</resources>
diff --git a/usbtuner-res/values-mk/strings.xml b/usbtuner-res/values-mk/strings.xml
deleted file mode 100644
index fb2e71e7..00000000
--- a/usbtuner-res/values-mk/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"ТВ приемник"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"ТВ приемник со USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Вклучено"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Исклучено"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Почекајте да заврши обработувањето"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Изберете го изворот на каналот"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Нема сигнал"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Не успеа да се избере <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Не успеа да се избере"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Софтверот на приемникот неодамна е ажуриран. Скенирајте ги каналите повторно."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Овозможете опкружувачки звук во поставките за звуци на системот за да овозможите аудио"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Поставување приемник на канали"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"Поставување ТВ приемник"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"Поставување на USB-приемникот за канали"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Потврдете дека телевизорот е приклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, можеби ќе треба да ја приспособите поставеноста или насоката за да примате најмногу канали. За најдобри резултати, поставете ја високо и во близина на прозорец."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"Потврдете дека USB-приемникот е приклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, можеби ќе треба да ја приспособите поставеноста или насоката за да примате најмногу канали. За најдобри резултати, поставете ја високо и во близина на прозорец."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Продолжи"</item>
- <item msgid="727245208787621142">"Не сега"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Да се изврши поставувањето на каналите повторно?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Ова ќе ги отстрани каналите од ТВ приемникот и ќе скенира за нови канали повторно.\n\nПотврдете дека телевизорот е поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, приспособете ја поставеноста или насоката. За најдобри резултати, поставете ја високо и во близина на прозорец."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"Ова ќе ги отстрани каналите од USB-приемникот и ќе скенира за нови канали повторно.\n\nПотврдете дека USB-приемникот е приклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, можеби ќе треба да ја приспособите поставеноста или насоката за да примате најмногу канали. За најдобри резултати, поставете ја високо и во близина на прозорец."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Продолжи"</item>
- <item msgid="235450158666155406">"Откажи"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Изберете го типот врска"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Изберете „Антена“ ако има надворешна антена поврзана со приемникот. Изберете „Кабел“ ако каналите ви ги обезбедува кабелски оператор. Ако не сте сигурни, и двата типа ќе се скенираат, но тоа може да трае подолго."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Антена"</item>
- <item msgid="2670079958754180142">"Кабел"</item>
- <item msgid="36774059871728525">"Не сум сигурен"</item>
- <item msgid="6881204453182153978">"Само за програмери"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"Поставување ТВ приемник"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"Поставување на USB-приемникот за канали"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Ова може да трае неколку минути"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Приемникот е привремено недостапен или веќе се користи за снимање."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="one">Пронајден е %1$d канал</item>
- <item quantity="other">Пронајдени се %1$d канали</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"ЗАПРИ ГО СКЕНИРАЊЕТО КАНАЛИ"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="one">Пронајден е %1$d канал</item>
- <item quantity="other">Пронајдени се %1$d канали</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="one">Убаво! Пронајдени се %1$d канали во текот на скенирањето канали. Ако се чини дека тоа не е во ред, обидете се со приспособување на позицијата на антената и скенирајте повторно.</item>
- <item quantity="other">Убаво! Пронајдени се %1$d канали во текот на скенирањето канали. Ако се чини дека тоа не е во ред, обидете се со приспособување на позицијата на антената и скенирајте повторно.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Готово"</item>
- <item msgid="2480490326672924828">"Скенирај пак"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Не се пронајдени канали"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Скенирањето не пронајде ниеден канал. Потврдете дека телевизорот е поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, приспособете ја поставеноста или насоката. За најдобри резултати, поставете ја високо и во близина на прозорец и скенирајте повторно."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Скенирањето не пронајде ниеден канал. Потврдете дека USB-приемникот е приклучен и поврзан со изворот на ТВ сигналот.\n\nАко користите безжична антена, приспособете ја поставеноста или насоката. За најдобри резултати, поставете ја високо и во близина на прозорец и скенирајте повторно."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Скенирај пак"</item>
- <item msgid="2092797862490235174">"Готово"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Скенирај ТВ-канали"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Поставување ТВ приемник"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Поставување ТВ приемник со USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"TV приемникот преку USB е исклучен."</string>
-</resources>
diff --git a/usbtuner-res/values-ml-rIN/strings.xml b/usbtuner-res/values-ml-rIN/strings.xml
new file mode 100644
index 00000000..2befa74c
--- /dev/null
+++ b/usbtuner-res/values-ml-rIN/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"ടിവി ട്യൂണർ"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB ടിവി ട്യൂണർ"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"നെറ്റ്‌വർക്ക് ടിവി ട്യൂണർ (ബീറ്റ)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"പ്രോസസ്സുചെയ്യൽ പൂർത്തിയാകുന്നത് വരെ കാത്തിരിക്കുക"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"ട്യൂണർ സോഫ്‌റ്റ്‌വെയർ അടുത്തിടെ അപ്‌ഡേറ്റുചെയ്‌തു. ചാനലുകൾ വീണ്ടും സ്‌കാൻ ചെയ്യുക."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ഓഡിയോ പ്രവർത്തനക്ഷമമാക്കുന്നതിന് സിസ്റ്റം ശബ്ദ ക്രമീകരണത്തിൽ സറൗണ്ട് ശബ്‌ദം പ്രവർത്തനക്ഷമമാക്കുക"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"ഓഡിയോ പ്ലേ ചെയ്യാൻ കഴിയുന്നില്ല. മറ്റൊരു ടിവിയിൽ ശ്രമിച്ചുനോക്കൂ"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ചാനൽ ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"ടിവി ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB ചാനൽ ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"നെറ്റ്‌വർക്ക് ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് നിങ്ങളുടെ ടിവി കണക്റ്റുചെയ്തിട്ടുണ്ടെന്ന് ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, പരമാവധി ചാനലുകൾ ലഭിക്കുന്നതിന്, അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കേണ്ടി വരാം. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിക്കുക."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ട്യൂണർ പ്ലഗിൻ ചെയ്തിട്ടുണ്ടെന്നും ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് കണക്റ്റുചെയ്തിട്ടുണ്ടെന്നും ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, പരമാവധി ചാനലുകൾ ലഭിക്കുന്നതിന്, അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കേണ്ടി വരാം. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിക്കുക."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"നെറ്റ്‌വർക്ക് ട്യൂണർ ഓണാക്കിയിട്ടുണ്ടെന്നും ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് കണക്റ്റുചെയ്തിട്ടുണ്ടെന്നും ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, പരമാവധി ചാനലുകൾ ലഭിക്കുന്നതിന്, അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കേണ്ടി വരാം. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിക്കുക."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"തുടരുക"</item>
+ <item msgid="727245208787621142">"ഇപ്പോൾ വേണ്ട"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"ചാനൽ സജ്ജമാക്കൽ വീണ്ടും റൺ ചെയ്യണോ?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"ടിവി ട്യൂണറിൽ നിന്ന് കണ്ടെത്തിയ ചാനലുകളെ ഇത് നീക്കംചെയ്യും, പുതിയ ചാനലുകൾക്കായി വീണ്ടും സ്കാൻ ചെയ്യും.\n\nഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് നിങ്ങളുടെ ടിവി കണക്റ്റുചെയ്തിട്ടുണ്ടെന്ന് ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, പരമാവധി ചാനലുകൾ ലഭിക്കുന്നതിന്, അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കേണ്ടി വരാം. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിക്കുക."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"USB ട്യൂണറിൽ നിന്ന് കണ്ടെത്തിയ ചാനലുകളെ ഇത് നീക്കംചെയ്യും, പുതിയ ചാനലുകൾക്കായി വീണ്ടും സ്കാൻ ചെയ്യും.\n\nസ്കാൻ ചെയ്തപ്പോൾ ചാനലുകളൊന്നും കണ്ടെത്തിയില്ല. USB ട്യൂണർ പ്ലഗിൻ ചെയ്തിട്ടുണ്ടെന്നും ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് കണക്റ്റുചെയ്തിട്ടുണ്ടെന്നും ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, പരമാവധി ചാനലുകൾ ലഭിക്കുന്നതിന്, അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കേണ്ടി വരാം. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിക്കുക."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"നെറ്റ്‌വർക്ക് ട്യൂണറിൽ നിന്ന് കണ്ടെത്തിയ ചാനലുകളെ ഇത് നീക്കംചെയ്യും, പുതിയ ചാനലുകൾക്കായി വീണ്ടും സ്കാൻ ചെയ്യും.\n\nനെറ്റ്‌വർക്ക് ട്യൂണർ ഓണാക്കിയിട്ടുണ്ടെന്നും ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് കണക്റ്റുചെയ്തിട്ടുണ്ടെന്നും ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, പരമാവധി ചാനലുകൾ ലഭിക്കുന്നതിന്, അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കേണ്ടി വരാം മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിക്കുക."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"തുടരുക"</item>
+ <item msgid="235450158666155406">"റദ്ദാക്കൂ"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"കണക്ഷൻ തരം തിരഞ്ഞെടുക്കുക"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"ട്യൂണറിലേക്ക് കണക്റ്റുചെയ്തിട്ടുള്ള ഒരു ബാഹ്യ ആന്റിന ഉണ്ടെങ്കിൽ, ആന്റിന തിരഞ്ഞെടുക്കുക. കേബിൾ സേവന ദാതാവിൽ നിന്നാണ് ചാനലുകൾ ലഭിക്കുന്നതെങ്കിൽ കേബിൾ തിരഞ്ഞെടുക്കുക. ഏതാണ് ഉള്ളതെന്ന് നിങ്ങൾക്ക് അറിയില്ലെങ്കിൽ, രണ്ട് രീതികളും സ്കാൻ ചെയ്യപ്പെടും, എന്നാലിതിന് സമയമെടുക്കും."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"ആന്റിന"</item>
+ <item msgid="2670079958754180142">"കേബിള്‍"</item>
+ <item msgid="36774059871728525">"ഉറപ്പില്ല"</item>
+ <item msgid="6881204453182153978">"ഡെവലപ്പ്‌മെന്റ് മാത്രം"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"ടിവി ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB ചാനൽ ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"നെറ്റ്‌വർക്ക് ചാനൽ ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"ഇതിന് കുറച്ച് സമയം എടുത്തേക്കാം"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ട്യൂണർ നിലവിൽ ലഭ്യമല്ല അല്ലെങ്കിൽ ഇതിനകം തന്നെ റെക്കോർഡിംഗ് ഉപയോഗിച്ചുകൊണ്ടിരിക്കുന്നു."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d ചാനലുകൾ കണ്ടെത്തി</item>
+ <item quantity="one">%1$d ചാനൽ കണ്ടെത്തി</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"ചാനൽ സ്കാൻ ചെയ്യുന്നത് നിർത്തുക"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d ചാനലുകൾ കണ്ടെത്തി</item>
+ <item quantity="one">%1$d ചാനൽ കണ്ടെത്തി</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">കൊള്ളാം! ചാനൽ സ്കാൻ വേളയിൽ %1$d ചാനലുകൾ കണ്ടെത്തി. എന്തോ കുഴപ്പമുണ്ടെന്ന് തോന്നുന്നുവെങ്കിൽ, ആന്റിനയുടെ ദിശ ക്രമീകരിച്ചുകൊണ്ട് വീണ്ടും സ്കാൻ ചെയ്യുക.</item>
+ <item quantity="one">കൊള്ളാം! ചാനൽ സ്കാൻ വേളയിൽ %1$d ചാനൽ കണ്ടെത്തി. എന്തോ കുഴപ്പമുണ്ടെന്ന് തോന്നുന്നുവെങ്കിൽ, ആന്റിനയുടെ ദിശ ക്രമീകരിച്ചുകൊണ്ട് വീണ്ടും സ്കാൻ ചെയ്യുക.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"പൂർത്തിയായി"</item>
+ <item msgid="2480490326672924828">"വീണ്ടും സ്കാൻ ചെയ്യുക"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"ചാനലുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"സ്കാൻ ചെയ്തപ്പോൾ ചാനലുകളൊന്നും കണ്ടെത്തിയില്ല. ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് നിങ്ങളുടെ ടിവി കണക്റ്റുചെയ്തിട്ടുണ്ടെന്ന് ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കുക. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിച്ച് വീണ്ടും സ്കാൻ ചെയ്യുക."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"സ്കാൻ ചെയ്തപ്പോൾ ചാനലുകളൊന്നും കണ്ടെത്തിയില്ല. USB ട്യൂണർ പ്ലഗിൻ ചെയ്തിട്ടുണ്ടെന്നും ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് കണക്റ്റുചെയ്തിട്ടുണ്ടെന്നും ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കുക. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിച്ച് വീണ്ടും സ്കാൻ ചെയ്യുക."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"സ്കാൻ ചെയ്തപ്പോൾ ചാനലുകളൊന്നും കണ്ടെത്തിയില്ല. നെറ്റ്‌വർക്ക് ട്യൂണർ ഓണാക്കിയിട്ടുണ്ടെന്നും ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് കണക്റ്റുചെയ്തിട്ടുണ്ടെന്നും ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കുക. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിച്ച് വീണ്ടും സ്കാൻ ചെയ്യുക."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"വീണ്ടും സ്കാൻ ചെയ്യുക"</item>
+ <item msgid="2092797862490235174">"പൂർത്തിയായി"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"ടിവി ചാനലുകൾക്കായി സ്കാൻ ചെയ്യുക"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"ടിവി ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB ടിവി ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"നെറ്റ്‌വർക്ക് ടിവി ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB ടിവി ട്യൂണർ വിച്ഛേദിച്ചു."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"നെറ്റ്‌വർക്ക് ട്യൂണർ വിച്ഛേദിച്ചു."</string>
+</resources>
diff --git a/usbtuner-res/values-ml/strings.xml b/usbtuner-res/values-ml/strings.xml
deleted file mode 100644
index d025ec7b..00000000
--- a/usbtuner-res/values-ml/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"ടിവി ട്യൂണർ"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB ടിവി ട്യൂണർ"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"ഓണാക്കുക"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"ഓഫാക്കുക"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"പ്രോസസ്സുചെയ്യൽ പൂർത്തിയാകുന്നത് വരെ കാത്തിരിക്കുക"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"നിങ്ങളുടെ ചാനൽ ഉറവിടം തിരഞ്ഞെടുക്കുക"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"സിഗ്‌നൽ ഇല്ല"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> എന്നതിലേക്ക് ട്യൂൺ ചെയ്യുന്നത് പരാജയപ്പെട്ടു"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ട്യൂൺ ചെയ്യുന്നത് പരാജയപ്പെട്ടു"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"ട്യൂണർ സോഫ്‌റ്റ്‌വെയർ അടുത്തിടെ അപ്‌ഡേറ്റുചെയ്‌തു. ചാനലുകൾ വീണ്ടും സ്‌കാൻ ചെയ്യുക."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ഓഡിയോ പ്രവർത്തനക്ഷമമാക്കുന്നതിന് സിസ്റ്റം ശബ്ദ ക്രമീകരണത്തിൽ സറൗണ്ട് ശബ്‌ദം പ്രവർത്തനക്ഷമമാക്കുക"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ചാനൽ ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"ടിവി ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB ചാനൽ ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് നിങ്ങളുടെ ടിവി കണക്റ്റുചെയ്തിട്ടുണ്ടെന്ന് ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, പരമാവധി ചാനലുകൾ ലഭിക്കുന്നതിന്, അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കേണ്ടി വരാം. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിക്കുക."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ട്യൂണർ പ്ലഗിൻ ചെയ്തിട്ടുണ്ടെന്നും ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് കണക്റ്റുചെയ്തിട്ടുണ്ടെന്നും ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, പരമാവധി ചാനലുകൾ ലഭിക്കുന്നതിന്, അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കേണ്ടി വരാം. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിക്കുക."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"തുടരുക"</item>
- <item msgid="727245208787621142">"ഇപ്പോൾ വേണ്ട"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"ചാനൽ സജ്ജമാക്കൽ വീണ്ടും റൺ ചെയ്യണോ?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"ടിവി ട്യൂണറിൽ നിന്ന് കണ്ടെത്തിയ ചാനലുകളെ ഇത് നീക്കംചെയ്യും, പുതിയ ചാനലുകൾക്കായി വീണ്ടും സ്കാൻ ചെയ്യും.\n\nഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് നിങ്ങളുടെ ടിവി കണക്റ്റുചെയ്തിട്ടുണ്ടെന്ന് ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, പരമാവധി ചാനലുകൾ ലഭിക്കുന്നതിന്, അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കേണ്ടി വരാം. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിക്കുക."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"USB ട്യൂണറിൽ നിന്ന് കണ്ടെത്തിയ ചാനലുകളെ ഇത് നീക്കംചെയ്യും, പുതിയ ചാനലുകൾക്കായി വീണ്ടും സ്കാൻ ചെയ്യും.\n\nസ്കാൻ ചെയ്തപ്പോൾ ചാനലുകളൊന്നും കണ്ടെത്തിയില്ല. USB ട്യൂണർ പ്ലഗിൻ ചെയ്തിട്ടുണ്ടെന്നും ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് കണക്റ്റുചെയ്തിട്ടുണ്ടെന്നും ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ, പരമാവധി ചാനലുകൾ ലഭിക്കുന്നതിന്, അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കേണ്ടി വരാം. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിക്കുക."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"തുടരുക"</item>
- <item msgid="235450158666155406">"റദ്ദാക്കൂ"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"കണക്ഷൻ തരം തിരഞ്ഞെടുക്കുക"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"ട്യൂണറിലേക്ക് കണക്റ്റുചെയ്തിട്ടുള്ള ഒരു ബാഹ്യ ആന്റിന ഉണ്ടെങ്കിൽ, ആന്റിന തിരഞ്ഞെടുക്കുക. കേബിൾ സേവന ദാതാവിൽ നിന്നാണ് ചാനലുകൾ ലഭിക്കുന്നതെങ്കിൽ കേബിൾ തിരഞ്ഞെടുക്കുക. ഏതാണ് ഉള്ളതെന്ന് നിങ്ങൾക്ക് അറിയില്ലെങ്കിൽ, രണ്ട് രീതികളും സ്കാൻ ചെയ്യപ്പെടും, എന്നാലിതിന് സമയമെടുക്കും."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"ആന്റിന"</item>
- <item msgid="2670079958754180142">"കേബിള്‍"</item>
- <item msgid="36774059871728525">"ഉറപ്പില്ല"</item>
- <item msgid="6881204453182153978">"ഡെവലപ്പ്‌മെന്റ് മാത്രം"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"ടിവി ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB ചാനൽ ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"ഇതിന് കുറച്ച് സമയം എടുത്തേക്കാം"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ട്യൂണർ നിലവിൽ ലഭ്യമല്ല അല്ലെങ്കിൽ ഇതിനകം തന്നെ റെക്കോർഡിംഗ് ഉപയോഗിച്ചുകൊണ്ടിരിക്കുന്നു."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d ചാനലുകൾ കണ്ടെത്തി</item>
- <item quantity="one">%1$d ചാനൽ കണ്ടെത്തി</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"ചാനൽ സ്കാൻ ചെയ്യുന്നത് നിർത്തുക"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d ചാനലുകൾ കണ്ടെത്തി</item>
- <item quantity="one">%1$d ചാനൽ കണ്ടെത്തി</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">കൊള്ളാം! ചാനൽ സ്കാൻ വേളയിൽ %1$d ചാനലുകൾ കണ്ടെത്തി. എന്തോ കുഴപ്പമുണ്ടെന്ന് തോന്നുന്നുവെങ്കിൽ, ആന്റിനയുടെ ദിശ ക്രമീകരിച്ചുകൊണ്ട് വീണ്ടും സ്കാൻ ചെയ്യുക.</item>
- <item quantity="one">കൊള്ളാം! ചാനൽ സ്കാൻ വേളയിൽ %1$d ചാനൽ കണ്ടെത്തി. എന്തോ കുഴപ്പമുണ്ടെന്ന് തോന്നുന്നുവെങ്കിൽ, ആന്റിനയുടെ ദിശ ക്രമീകരിച്ചുകൊണ്ട് വീണ്ടും സ്കാൻ ചെയ്യുക.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"പൂർത്തിയായി"</item>
- <item msgid="2480490326672924828">"വീണ്ടും സ്കാൻ ചെയ്യുക"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"ചാനലുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"സ്കാൻ ചെയ്തപ്പോൾ ചാനലുകളൊന്നും കണ്ടെത്തിയില്ല. ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് നിങ്ങളുടെ ടിവി കണക്റ്റുചെയ്തിട്ടുണ്ടെന്ന് ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കുക. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിച്ച് വീണ്ടും സ്കാൻ ചെയ്യുക."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"സ്കാൻ ചെയ്തപ്പോൾ ചാനലുകളൊന്നും കണ്ടെത്തിയില്ല. USB ട്യൂണർ പ്ലഗിൻ ചെയ്തിട്ടുണ്ടെന്നും ഒരു ടിവി സിഗ്നൽ ഉറവിടത്തിലേക്ക് കണക്റ്റുചെയ്തിട്ടുണ്ടെന്നും ഉറപ്പാക്കുക.\n\nഉയരത്തിൽ വയ്ക്കേണ്ട തരത്തിലുള്ള ആന്റിനയാണ് നിങ്ങൾ ഉപയോഗിക്കുന്നതെങ്കിൽ അതിന്റെ ഇരിപ്പോ ദിശയോ ക്രമീകരിക്കുക. മികച്ച ഫലം ലഭിക്കാൻ, കുറച്ചുകൂടി ഉയരത്തിലും ജാലകത്തിന് അരികിലായും അത് സ്ഥാപിച്ച് വീണ്ടും സ്കാൻ ചെയ്യുക."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"വീണ്ടും സ്കാൻ ചെയ്യുക"</item>
- <item msgid="2092797862490235174">"പൂർത്തിയായി"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"ടിവി ചാനലുകൾക്കായി സ്കാൻ ചെയ്യുക"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"ടിവി ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB ടിവി ട്യൂണർ സജ്ജമാക്കല്‍‌"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB ടിവി ട്യൂണർ വിച്ഛേദിച്ചു."</string>
-</resources>
diff --git a/usbtuner-res/values-mn-rMN/strings.xml b/usbtuner-res/values-mn-rMN/strings.xml
new file mode 100644
index 00000000..996341b4
--- /dev/null
+++ b/usbtuner-res/values-mn-rMN/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"ТВ тохируулагч"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB ТВ тохируулагч"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Сүлжээний ТВ Тохируулагч (БЭТА)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Боловсруулж дуусах хүртэл хүлээнэ үү"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Тохируулагчийн програмыг саяхан шинэчилсэн байна. Дахин суваг хайна уу."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Аудиог идэвхжүүлэхийн тулд орчны дууны системийг дууны тохиргоонд идэвхжүүлнэ үү"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Аудиог тоглуулах боломжгүй байна. Өөр ТВ дээр оролдож үзнэ үү"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Суваг тохируулагчийн тохиргоо"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"ТВ тохируулагчийн тохиргоо"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB суваг тохируулагчийн тохиргоо"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Сүлжээ тохируулагчийн тохиргоо"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"ТВ-ээ ТВ дохионы үүсвэртэй холбосон эсэхээ батална уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол олон суваг авахын тулд антены байршил эсвэл чиглэлийг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулах нь илүү үр дүнтэй."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB тохируулагчийг залгасан ба ТВ дохионы үүсвэртэй холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол олон суваг авахын тулд антены байршлыг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулах нь илүү үр дүнтэй байдаг."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Сүлжээ тохируулагчийг асааж, ТВ дохионы үүсвэртэй холбосон эсэхээ баталгаажуулна уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол олон суваг авахын тулд антены байршлыг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулна уу."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Үргэлжлүүлэх"</item>
+ <item msgid="727245208787621142">"Одоо биш"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Сувгийн тохируулгыг дахин ажиллуулах уу?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Энэ нь ТВ тохируулагчаас олсон сувгийг устгаад, шинэ суваг хайх болно.\n\nТВ тохируулагчаа ТВ дохионы үүсвэртэй холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол олон суваг авахын тулд антены байршил эсвэл чиглэлийг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулах нь илүү үр дүнтэй."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"Энэ нь USB тохируулагчаас олдсон сувгийг устгаад, шинэ суваг хайх болно.\n\nUSB тохируулагчийг залгасан, ТВ дохионы үүсвэртэй холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол олон суваг авахын тулд антены байршлыг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулах нь илүү үр дүнтэй."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Энэ нь сүлжээ тохируулагчаас олдсон сувгийг устгаж, шинэ суваг хайх болно.\n\nСүлжээ тохируулагчийг асааж, ТВ дохио үүсвэртэй холбосон эсэхээ шалгана уу.\n\nХэрэв антен хэрэглэж байгаа бол антены байршлыг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулаад, дахин хайна уу."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Үргэлжлүүлэх"</item>
+ <item msgid="235450158666155406">"Цуцлах"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Холболтын төрөл сонгоно уу"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Тохируулагчтай нэмэлт антен холбосон бол Антенаа сонгоно уу. Хэрэв сувгаа кабелийн үйлчилгээ эрхлэгчээс авдаг бол Кабелиа сонгоно уу. Та итгэлгүй байвал энэ хоёр төрлийг хоёуланг нь хайх боловч хэсэг хугацаа зарцуулах болно."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Антен"</item>
+ <item msgid="2670079958754180142">"Кабель"</item>
+ <item msgid="36774059871728525">"Итгэлгүй байна"</item>
+ <item msgid="6881204453182153978">"Зөвхөн хөгжүүлэлтийн хэрэгцээнд"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"ТВ тохируулагчийн тохиргоо"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB суваг тохируулагчийн тохиргоо"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Сүлжээний суваг тохируулагчийн тохиргоо"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Хэдэн минут шаардлагатай"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Суваг солигч одоогоор боломжгүй, эсвэл үүнийг өөр бичлэгт ашиглаж байна."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d суваг оллоо</item>
+ <item quantity="one">%1$d суваг оллоо</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"СУВАГ ХАЙХЫГ ЗОГСООХ"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d суваг оллоо</item>
+ <item quantity="one">%1$d суваг оллоо</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">Сайн байна! Суваг хайх явцад %1$d сувгийг олсон байна. Хэрэв илүү олон суваг хайх бол антенаа хөдөлгөөд, дахин хайна уу.</item>
+ <item quantity="one">Сайн байна! Суваг хайх явцад %1$d суваг олдсон. Хэрэв илүү олон суваг хайх бол антенаа хөдөлгөөд, дахин хайна уу.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Дууссан"</item>
+ <item msgid="2480490326672924828">"Дахин хайх"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Суваг олсонгүй"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Хайлтын явцад суваг олсонгүй. ТВ-ээ ТВ дохионы үүсвэрт холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол антены байршлыг эсвэл чиглэлийг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулаад, дахин хайх нь илүү үр дүнтэй."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Хайлтын явцад суваг олдсонгүй. USB тохируулагчийг залгасан бөгөөд ТВ дохионы үүсвэртэй холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол антены байршил эсвэл чиглэлийг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулахаад, дахин хайх нь илүү үр дүнтэй."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Хайлтын явцад суваг олдсонгүй. Сүлжээ тохируулагчийг асааж, ТВ дохионы үүсвэртэй холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол антены байршил, эсвэл чиглэлийг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулаад, дахин хайна уу."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Дахин хайх"</item>
+ <item msgid="2092797862490235174">"Дууссан"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"TВ-н суваг хайх"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"ТВ тохируулагчийн тохиргоо"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB ТВ тохируулагчийн тохиргоо"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Сүлжээний ТВ тохируулагчийн тохиргоо"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB ТВ тохируулагч салсан байна."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Сүлжээ тааруулагч салсан байна."</string>
+</resources>
diff --git a/usbtuner-res/values-mn/strings.xml b/usbtuner-res/values-mn/strings.xml
deleted file mode 100644
index 51f7a8dd..00000000
--- a/usbtuner-res/values-mn/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"ТВ тохируулагч"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB ТВ тохируулагч"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Идэвхтэй"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Идэвхгүй"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Боловсруулж дуусах хүртэл хүлээнэ үү"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Сувгийн эх үүсвэрээ сонгоно уу"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Дохио алга"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g>-д тохируулж чадсангүй"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Тохируулж чадсангүй"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Тохируулагчийн програмыг саяхан шинэчилсэн байна. Дахин суваг хайна уу."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Аудиог идэвхжүүлэхийн тулд орчны дууны системийг дууны тохиргоонд идэвхжүүлнэ үү"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Суваг тохируулагчийн тохиргоо"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"ТВ тохируулагчийн тохиргоо"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB суваг тохируулагчийн тохиргоо"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"ТВ-ээ ТВ дохионы үүсвэртэй холбосон эсэхээ батална уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол олон суваг авахын тулд антены байршил эсвэл чиглэлийг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулах нь илүү үр дүнтэй."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB тохируулагчийг залгасан ба ТВ дохионы үүсвэртэй холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол олон суваг авахын тулд антены байршлыг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулах нь илүү үр дүнтэй байдаг."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Үргэлжлүүлэх"</item>
- <item msgid="727245208787621142">"Одоо биш"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Сувгийн тохируулгыг дахин ажиллуулах уу?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Энэ нь ТВ тохируулагчаас олсон сувгийг устгаад, шинэ суваг хайх болно.\n\nТВ тохируулагчаа ТВ дохионы үүсвэртэй холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол олон суваг авахын тулд антены байршил эсвэл чиглэлийг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулах нь илүү үр дүнтэй."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"Энэ нь USB тохируулагчаас олдсон сувгийг устгаад, шинэ суваг хайх болно.\n\nUSB тохируулагчийг залгасан, ТВ дохионы үүсвэртэй холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол олон суваг авахын тулд антены байршлыг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулах нь илүү үр дүнтэй."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Үргэлжлүүлэх"</item>
- <item msgid="235450158666155406">"Цуцлах"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Холболтын төрөл сонгоно уу"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Тохируулагчтай нэмэлт антен холбосон бол Антенаа сонгоно уу. Хэрэв сувгаа кабелийн үйлчилгээ эрхлэгчээс авдаг бол Кабелиа сонгоно уу. Та итгэлгүй байвал энэ хоёр төрлийг хоёуланг нь хайх боловч хэсэг хугацаа зарцуулах болно."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Антен"</item>
- <item msgid="2670079958754180142">"Кабель"</item>
- <item msgid="36774059871728525">"Итгэлгүй байна"</item>
- <item msgid="6881204453182153978">"Зөвхөн хөгжүүлэлтийн хэрэгцээнд"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"ТВ тохируулагчийн тохиргоо"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB суваг тохируулагчийн тохиргоо"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Хэдэн минут шаардлагатай"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Суваг солигч одоогоор боломжгүй, эсвэл үүнийг өөр бичлэгт ашиглаж байна."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d суваг оллоо</item>
- <item quantity="one">%1$d суваг оллоо</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"СУВАГ ХАЙХЫГ ЗОГСООХ"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d суваг оллоо</item>
- <item quantity="one">%1$d суваг оллоо</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">Сайн байна! Суваг хайх явцад %1$d сувгийг олсон байна. Хэрэв илүү олон суваг хайх бол антенаа хөдөлгөөд, дахин хайна уу.</item>
- <item quantity="one">Сайн байна! Суваг хайх явцад %1$d суваг олдсон. Хэрэв илүү олон суваг хайх бол антенаа хөдөлгөөд, дахин хайна уу.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Дууссан"</item>
- <item msgid="2480490326672924828">"Дахин хайх"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Суваг олсонгүй"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Хайлтын явцад суваг олсонгүй. ТВ-ээ ТВ дохионы үүсвэрт холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол антены байршлыг эсвэл чиглэлийг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулаад, дахин хайх нь илүү үр дүнтэй."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Хайлтын явцад суваг олдсонгүй. USB тохируулагчийг залгасан бөгөөд ТВ дохионы үүсвэртэй холбосон эсэхээ шалгана уу.\n\nХэрэв агаарын антен хэрэглэж байгаа бол антены байршил эсвэл чиглэлийг өөрчилнө үү. Антеныг өндөрт, цонхны дэргэд байрлуулахаад, дахин хайх нь илүү үр дүнтэй."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Дахин хайх"</item>
- <item msgid="2092797862490235174">"Дууссан"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"TВ-н суваг хайх"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"ТВ тохируулагчийн тохиргоо"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB ТВ тохируулагчийн тохиргоо"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB ТВ тохируулагч салсан байна."</string>
-</resources>
diff --git a/usbtuner-res/values-mr-rIN/strings.xml b/usbtuner-res/values-mr-rIN/strings.xml
new file mode 100644
index 00000000..3b8c9011
--- /dev/null
+++ b/usbtuner-res/values-mr-rIN/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"टीव्ही ट्यूनर"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB टीव्ही ट्यूनर"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"नेटवर्क टीव्ही ट्यूनर (बीटा)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"कृपया प्रक्रिया पूर्ण होण्‍याची प्रतीक्षा करा"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"ट्यूनर सॉफ्टवेअर अलीकडे अद्यतनित केले आहे. कृपया चॅनेल पुन्हा स्कॅन करा."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ऑडिओ सक्षम करण्यासाठी सिस्टीम ध्वनी सेटिंग्ज मध्ये सराउंड ध्वनी सक्षम करा"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"ऑडिओ प्ले करू शकत नाही. कृपया दुसरा टीव्ही वापरून पहा"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"चॅनेल ट्यूनर सेटअप"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"टीव्ही ट्यूनर सेटअप"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB चॅनेल ट्यूनर सेटअप"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"नेटवर्क ट्यूनर सेटअप"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"टीव्ही सिग्नल स्रोताशी आपला टीव्ही कनेक्ट केला असल्याची खात्री करा. \n\n बिनतारी अँटेना वापरत असल्‍यास, आपल्‍याला कदाचित सर्वाधिक चॅनेल मिळविण्‍यासाठी त्याचे स्थान किंवा दिशा समायोजित करावी लागेल. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ट्यूनर प्लगिन केले आणि TV सिग्नल स्रोताशी कनेक्‍ट केले आहे हे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, आपल्‍याला कदाचित सर्वाधिक चॅनेल मिळविण्‍यासाठी त्याचे स्थान किंवा दिशा समायोजित करावी लागेल. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"नेटवर्क ट्यूनर प्लगिन केले आणि TV सिग्नल स्रोताशी कनेक्‍ट केले आहे हे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, आपल्‍याला कदाचित सर्वाधिक चॅनेल मिळविण्‍यासाठी त्याचे स्थान किंवा दिशा समायोजित करावी लागेल. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"सुरू ठेवा"</item>
+ <item msgid="727245208787621142">"सध्या नाही"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"चॅनेल सेटअप वर परत यायचे?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"हे टीव्ही ट्यूनर वरून शोधलेले चॅनेल काढेल आणि नवीन चॅनेलसाठी पुन्हा स्कॅन करेल.\n\n टीव्ही सिग्नल स्रोताशी आपला टीव्ही कनेक्ट केला असल्याचे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, आपल्‍याला कदाचित सर्वाधिक चॅनेल मिळविण्‍यासाठी त्याचे स्थान किंवा दिशा समायोजित करावी लागेल. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"हे USB ट्यूनर वरून शोधलेले चॅनेल काढेल आणि नवीन चॅनेलसाठी पुन्हा स्कॅन करेल.\n\n USB ट्यूनर प्लगिन केले आणि TV सिग्नल स्त्रोताशी कनेक्‍ट केले आहे हे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, आपल्‍याला कदाचित सर्वाधिक चॅनेल मिळविण्‍यासाठी त्याचे स्थान किंवा दिशा समायोजित करावी लागेल. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"हे नेटवर्क ट्यूनर वरून शोधलेले चॅनेल काढेल आणि नवीन चॅनेलसाठी पुन्हा स्कॅन करेल.\n\n नेटवर्क ट्यूनर प्लगिन केले आणि टीव्ही सिग्नल स्रोताशी कनेक्‍ट केले आहे हे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, आपल्याला कदाचित सर्वाधिक चॅनेल मिळविण्‍यासाठी त्याचे स्थान किंवा दिशा समायोजित करावी लागेल. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"सुरू ठेवा"</item>
+ <item msgid="235450158666155406">"रद्द करा"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"कनेक्‍शन प्रकार निवडा"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"ट्यूनरशी बाह्य अँटेना कनेक्‍ट केला असल्‍यास अँटेना निवडा. आपले चॅनेल केबल सेवा प्रदात्याकडून येत असल्‍यास केबल निवडा. आपल्‍याला खात्री नसल्‍यास, दोन्ही प्रकार स्कॅन केले जातील परंतु यास वेळ लागेल."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"अँटेना"</item>
+ <item msgid="2670079958754180142">"केबल"</item>
+ <item msgid="36774059871728525">"खात्री नाही"</item>
+ <item msgid="6881204453182153978">"केवळ विकास"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"टीव्ही ट्यूनर सेटअप"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB चॅनेल ट्यूनर सेटअप"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"नेटवर्क चॅनेल ट्यूनर सेटअप"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"यास काही मिनिटे लागू शकतात"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ट्यूनर तात्पुरते उपलब्ध नाही किंवा रेकॉर्डिंगद्वारे आधीपासून वापरले गेले आहे."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="one">%1$d चॅनेल सापडले</item>
+ <item quantity="other">%1$d चॅनेल सापडले</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"चॅनेल स्कॅन करणे थांबवा"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="one">%1$d चॅनेल सापडले</item>
+ <item quantity="other">%1$d चॅनेल सापडले</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="one">छान! चॅनेल स्कॅन करताना %1$d चॅनेल सापडले. हे योग्य वाटत नसल्यास, अँटेना स्थिती समायोजित करून पहा आणि पुन्हा स्कॅन करा.</item>
+ <item quantity="other">छान! चॅनेल स्कॅन करताना %1$d चॅनेल सापडले. हे योग्य वाटत नसल्यास, अँटेना स्थिती समायोजित करून पहा आणि पुन्हा स्कॅन करा.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"पूर्ण झाले"</item>
+ <item msgid="2480490326672924828">"पुन्हा स्कॅन करा"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"कोणतेही चॅनेल आढळले नाही"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"स्कॅन करताना कोणतेही चॅनेल आढळले नाही. टीव्ही सिग्नल स्रोताशी आपला टीव्ही कनेक्ट केला असल्याचे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, त्याचे स्थान किंवा दिशा समायोजित करा. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा आणि पुन्हा स्कॅन करा."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"स्कॅन करताना कोणतेही चॅनेल आढळले नाही. USB ट्यूनर प्लगिन केले आणि TV सिग्नल स्रोताशी कनेक्‍ट केले आहे हे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, त्याचे स्थान किंवा दिशा समायोजित करा. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा आणि पुन्हा स्कॅन करा."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"स्कॅन करताना कोणतेही चॅनेल आढळले नाहीत. नेटवर्क ट्यूनर प्लगिन केले आणि टीव्ही सिग्नल स्रोताशी कनेक्‍ट केले आहे हे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, त्याचे स्थान किंवा दिशा समायोजित करा. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा आणि पुन्हा स्कॅन करा."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"पुन्हा स्कॅन करा"</item>
+ <item msgid="2092797862490235174">"पूर्ण झाले"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"टीव्ही चॅनेलसाठी स्कॅन करा"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"टीव्ही ट्यूनर सेटअप"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB टीव्ही ट्यूनर सेटअप"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"नेटवर्क टीव्ही ट्यूनर सेटअप"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB टीव्ही ट्यूनर डिस्कनेक्ट केला."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"नेटवर्क ट्यूनर डिस्कनेक्ट केले."</string>
+</resources>
diff --git a/usbtuner-res/values-mr/strings.xml b/usbtuner-res/values-mr/strings.xml
deleted file mode 100644
index 2ea242f1..00000000
--- a/usbtuner-res/values-mr/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"टीव्ही ट्यूनर"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB टीव्ही ट्यूनर"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"चालू"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"बंद"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"कृपया प्रक्रिया पूर्ण होण्‍याची प्रतीक्षा करा"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"आपला चॅनेल स्रोत निवडा"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"सिग्नल नाही"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> वर ट्यून करण्‍यात अयशस्वी झाले"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ट्यून करण्यात अयशस्वी झाले"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"ट्यूनर सॉफ्टवेअर अलीकडे अद्यतनित केले आहे. कृपया चॅनेल पुन्हा स्कॅन करा."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ऑडिओ सक्षम करण्यासाठी सिस्टीम ध्वनी सेटिंग्ज मध्ये सराउंड ध्वनी सक्षम करा"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"चॅनेल ट्यूनर सेटअप"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"टीव्ही ट्यूनर सेटअप"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB चॅनेल ट्यूनर सेटअप"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"टीव्ही सिग्नल स्रोताशी आपला टीव्ही कनेक्ट केला असल्याची खात्री करा. \n\n बिनतारी अँटेना वापरत असल्‍यास, आपल्‍याला कदाचित सर्वाधिक चॅनेल मिळविण्‍यासाठी त्याचे स्थान किंवा दिशा समायोजित करावी लागेल. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ट्यूनर प्लगिन केले आणि TV सिग्नल स्रोताशी कनेक्‍ट केले आहे हे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, आपल्‍याला कदाचित सर्वाधिक चॅनेल मिळविण्‍यासाठी त्याचे स्थान किंवा दिशा समायोजित करावी लागेल. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"सुरू ठेवा"</item>
- <item msgid="727245208787621142">"सध्या नाही"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"चॅनेल सेटअप वर परत यायचे?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"हे टीव्ही ट्यूनर वरून शोधलेले चॅनेल काढेल आणि नवीन चॅनेलसाठी पुन्हा स्कॅन करेल.\n\n टीव्ही सिग्नल स्रोताशी आपला टीव्ही कनेक्ट केला असल्याचे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, आपल्‍याला कदाचित सर्वाधिक चॅनेल मिळविण्‍यासाठी त्याचे स्थान किंवा दिशा समायोजित करावी लागेल. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"हे USB ट्यूनर वरून शोधलेले चॅनेल काढेल आणि नवीन चॅनेलसाठी पुन्हा स्कॅन करेल.\n\n USB ट्यूनर प्लगिन केले आणि TV सिग्नल स्त्रोताशी कनेक्‍ट केले आहे हे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, आपल्‍याला कदाचित सर्वाधिक चॅनेल मिळविण्‍यासाठी त्याचे स्थान किंवा दिशा समायोजित करावी लागेल. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"सुरू ठेवा"</item>
- <item msgid="235450158666155406">"रद्द करा"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"कनेक्‍शन प्रकार निवडा"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"ट्यूनरशी बाह्य अँटेना कनेक्‍ट केला असल्‍यास अँटेना निवडा. आपले चॅनेल केबल सेवा प्रदात्याकडून येत असल्‍यास केबल निवडा. आपल्‍याला खात्री नसल्‍यास, दोन्ही प्रकार स्कॅन केले जातील परंतु यास वेळ लागेल."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"अँटेना"</item>
- <item msgid="2670079958754180142">"केबल"</item>
- <item msgid="36774059871728525">"खात्री नाही"</item>
- <item msgid="6881204453182153978">"केवळ विकास"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"टीव्ही ट्यूनर सेटअप"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB चॅनेल ट्यूनर सेटअप"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"यास काही मिनिटे लागू शकतात"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ट्यूनर तात्पुरते उपलब्ध नाही किंवा रेकॉर्डिंगद्वारे आधीपासून वापरले गेले आहे."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="one">%1$d चॅनेल सापडले</item>
- <item quantity="other">%1$d चॅनेल सापडले</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"चॅनेल स्कॅन करणे थांबवा"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="one">%1$d चॅनेल सापडले</item>
- <item quantity="other">%1$d चॅनेल सापडले</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="one">छान! चॅनेल स्कॅन करताना %1$d चॅनेल सापडले. हे योग्य वाटत नसल्यास, अँटेना स्थिती समायोजित करून पहा आणि पुन्हा स्कॅन करा.</item>
- <item quantity="other">छान! चॅनेल स्कॅन करताना %1$d चॅनेल सापडले. हे योग्य वाटत नसल्यास, अँटेना स्थिती समायोजित करून पहा आणि पुन्हा स्कॅन करा.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"पूर्ण झाले"</item>
- <item msgid="2480490326672924828">"पुन्हा स्कॅन करा"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"कोणतेही चॅनेल आढळले नाही"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"स्कॅन करताना कोणतेही चॅनेल आढळले नाही. टीव्ही सिग्नल स्रोताशी आपला टीव्ही कनेक्ट केला असल्याचे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, त्याचे स्थान किंवा दिशा समायोजित करा. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा आणि पुन्हा स्कॅन करा."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"स्कॅन करताना कोणतेही चॅनेल आढळले नाही. USB ट्यूनर प्लगिन केले आणि TV सिग्नल स्रोताशी कनेक्‍ट केले आहे हे सत्यापित करा.\n\nबिनतारी अँटेना वापरत असल्‍यास, त्याचे स्थान किंवा दिशा समायोजित करा. उत्कृष्‍ट परिणामांसाठी, त्‍यास उंचावर आणि खिडकी जवळ ठेवा आणि पुन्हा स्कॅन करा."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"पुन्हा स्कॅन करा"</item>
- <item msgid="2092797862490235174">"पूर्ण झाले"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"टीव्ही चॅनेलसाठी स्कॅन करा"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"टीव्ही ट्यूनर सेटअप"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB टीव्ही ट्यूनर सेटअप"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV ट्यूनर डिस्कनेक्ट केला."</string>
-</resources>
diff --git a/usbtuner-res/values-ms-rMY/strings.xml b/usbtuner-res/values-ms-rMY/strings.xml
new file mode 100644
index 00000000..c85ce142
--- /dev/null
+++ b/usbtuner-res/values-ms-rMY/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"Penala TV"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"Penala TV USB"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Penala TV Rangkaian (BETA)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Sila tunggu sehingga proses selesai"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Perisian penala telah dikemas kini baru-baru ini. Sila imbas semula saluran."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Dayakan bunyi keliling dalam tetapan bunyi sistem untuk mendayakan audio"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Tidak dapat memainkan audio. Sila cuba TV lain"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Persediaan penala saluran"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"Persediaan Penala TV"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"Persediaan penala saluran USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Persediaan penala rangkaian"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Sahkan bahawa TV anda disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, anda mungkin perlu melaraskan peletakan atau arahnya untuk menerima saluran terbanyak. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"Sahkan bahawa penala USB dipalamkan dan disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, anda mungkin perlu melaraskan peletakan atau arahnya untuk menerima saluran terbanyak. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Sahkan bahawa penala rangkaian telah dihidupkan dan disambungkan pada sumber isyarat TV\n\nJika menggunakan antena siaran, anda mungkin perlu melaraskan peletakan atau arahnya untuk menerima saluran terbanyak. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Teruskan"</item>
+ <item msgid="727245208787621142">"Bukan sekarang"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Jalankan semula persediaan saluran?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Tindakan ini akan mengalih keluar saluran yang ditemui daripada penala TV dan mengimbas saluran baharu sekali lagi.\n\nSahkan bahawa penala TV telah disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, anda mungkin perlu melaraskan peletakan atau arahnya untuk menerima saluran terbanyak. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"Tindakan ini akan mengalih keluar saluran yang ditemui daripada penala USB dan mengimbas saluran baharu sekali lagi.\n\nSahkan bahawa penala USB telah dipalamkan dan disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, anda mungkin perlu melaraskan peletakan atau arahnya untuk menerima saluran terbanyak. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Tindakan ini akan mengalih keluar saluran yang ditemui daripada penala rangkaian dan mengimbas saluran baharu sekali lagi.\n\nSahkan bahawa penala rangkaian telah dihidupkan dan disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, anda mungkin perlu melaraskan peletakan atau arahnya untuk menerima saluran terbanyak. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Teruskan"</item>
+ <item msgid="235450158666155406">"Batal"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Pilih jenis sambungan"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Pilih Antena jika terdapat antena luaran yang disambungkan pada penala. Pilih Kabel jika saluran anda adalah daripada penyedia perkhidmatan kabel. Jika anda tidak pasti, kedua-dua jenis sambungan akan diimbas tetapi proses ini mungkin mengambil masa yang lebih lama."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Antena"</item>
+ <item msgid="2670079958754180142">"Kabel"</item>
+ <item msgid="36774059871728525">"Tidak pasti"</item>
+ <item msgid="6881204453182153978">"Pembangunan sahaja"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"Persediaan penala TV"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"Persediaan penala saluran USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Persediaan penala saluran rangkaian"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Proses ini mungkin mengambil masa beberapa minit"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Penala tidak tersedia buat sementara waktu atau sudah pun digunakan oleh rakaman."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d saluran ditemui</item>
+ <item quantity="one">%1$d saluran ditemui</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"HENTIKAN PENGIMBASAN SALURAN"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d saluran ditemui</item>
+ <item quantity="one">%1$d saluran ditemui</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">Bagus! %1$d saluran ditemui semasa pengimbasan saluran. Jika hasil pengimbasan ini salah, cuba laraskan kedudukan antena dan imbas sekali lagi.</item>
+ <item quantity="one">Bagus! %1$d saluran ditemui semasa pengimbasan saluran. Jika hasil pengimbasan ini salah, cuba laraskan kedudukan antena dan imbas sekali lagi.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Selesai"</item>
+ <item msgid="2480490326672924828">"Imbas lagi"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Tiada Saluran ditemui"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Pengimbasan ini tidak menemui sebarang saluran. Sahkan bahawa TV anda disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, laraskan peletakan atau arahnya. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap, kemudian imbas sekali lagi."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Pengimbasan tidak menemui sebarang saluran. Sahkan bahawa penala USB dipalamkan dan disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, laraskan peletakan atau arahnya. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap, kemudian imbas sekali lagi."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Pengimbasan ini tidak menemui sebarang saluran. Sahkan bahawa penala rangkaian telah dihidupkan dan disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, laraskan peletakan atau arahnya. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap, kemudian imbas sekali lagi."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Imbas lagi"</item>
+ <item msgid="2092797862490235174">"Selesai"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Imbas saluran TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Persediaan Penala TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Persediaan Penala TV USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Persediaan Penala TV Rangkaian"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Penala TV USB diputuskan sambungan."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Penala rangkaian diputuskan sambungan."</string>
+</resources>
diff --git a/usbtuner-res/values-ms/strings.xml b/usbtuner-res/values-ms/strings.xml
deleted file mode 100644
index 578e8ae5..00000000
--- a/usbtuner-res/values-ms/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"Penala TV"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"Penala TV USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Hidupkan"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Matikan"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Sila tunggu sehingga proses selesai"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Pilih sumber saluran anda"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Tiada Isyarat"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Gagal menala ke <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Gagal menala"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Perisian penala telah dikemas kini baru-baru ini. Sila imbas semula saluran."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Dayakan bunyi keliling dalam tetapan bunyi sistem untuk mendayakan audio"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Persediaan penala saluran"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"Persediaan Penala TV"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"Persediaan penala saluran USB"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Sahkan bahawa TV anda disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, anda mungkin perlu melaraskan peletakan atau arahnya untuk menerima saluran terbanyak. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"Sahkan bahawa penala USB dipalamkan dan disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, anda mungkin perlu melaraskan peletakan atau arahnya untuk menerima saluran terbanyak. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Teruskan"</item>
- <item msgid="727245208787621142">"Bukan sekarang"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Jalankan semula persediaan saluran?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Tindakan ini akan mengalih keluar saluran yang ditemui daripada penala TV dan mengimbas saluran baharu sekali lagi.\n\nSahkan bahawa penala TV telah disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, anda mungkin perlu melaraskan peletakan atau arahnya untuk menerima saluran terbanyak. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"Tindakan ini akan mengalih keluar saluran yang ditemui daripada penala USB dan mengimbas saluran baharu sekali lagi.\n\nSahkan bahawa penala USB telah dipalamkan dan disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, anda mungkin perlu melaraskan peletakan atau arahnya untuk menerima saluran terbanyak. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Teruskan"</item>
- <item msgid="235450158666155406">"Batal"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Pilih jenis sambungan"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Pilih Antena jika terdapat antena luaran yang disambungkan pada penala. Pilih Kabel jika saluran anda adalah daripada penyedia perkhidmatan kabel. Jika anda tidak pasti, kedua-dua jenis sambungan akan diimbas tetapi proses ini mungkin mengambil masa yang lebih lama."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Antena"</item>
- <item msgid="2670079958754180142">"Kabel"</item>
- <item msgid="36774059871728525">"Tidak pasti"</item>
- <item msgid="6881204453182153978">"Pembangunan sahaja"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"Persediaan penala TV"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"Persediaan penala saluran USB"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Proses ini mungkin mengambil masa beberapa minit"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Penala tidak tersedia buat sementara waktu atau sudah pun digunakan oleh rakaman."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d saluran ditemui</item>
- <item quantity="one">%1$d saluran ditemui</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"HENTIKAN PENGIMBASAN SALURAN"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d saluran ditemui</item>
- <item quantity="one">%1$d saluran ditemui</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">Bagus! %1$d saluran ditemui semasa pengimbasan saluran. Jika hasil pengimbasan ini salah, cuba laraskan kedudukan antena dan imbas sekali lagi.</item>
- <item quantity="one">Bagus! %1$d saluran ditemui semasa pengimbasan saluran. Jika hasil pengimbasan ini salah, cuba laraskan kedudukan antena dan imbas sekali lagi.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Selesai"</item>
- <item msgid="2480490326672924828">"Imbas lagi"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Tiada Saluran ditemui"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Pengimbasan ini tidak menemui sebarang saluran. Sahkan bahawa TV anda disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, laraskan peletakan atau arahnya. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap, kemudian imbas sekali lagi."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Pengimbasan tidak menemui sebarang saluran. Sahkan bahawa penala USB dipalamkan dan disambungkan pada sumber isyarat TV.\n\nJika menggunakan antena siaran, laraskan peletakan atau arahnya. Untuk mendapatkan hasil yang terbaik, letakkan antena itu di tempat yang tinggi dan berdekatan dengan tingkap, kemudian imbas sekali lagi."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Imbas lagi"</item>
- <item msgid="2092797862490235174">"Selesai"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Imbas saluran TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Persediaan Penala TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Persediaan Penala TV USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Penala TV USB diputuskan sambungan."</string>
-</resources>
diff --git a/usbtuner-res/values-my-rMM/strings.xml b/usbtuner-res/values-my-rMM/strings.xml
new file mode 100644
index 00000000..a2cf6c80
--- /dev/null
+++ b/usbtuner-res/values-my-rMM/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"တီဗီချန်နယ်ချိန်ကိရိယာ"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB တီဗီချန်နယ်ချိန်ကိရိယာ"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"ကွန်ရက်တီဗီ လိုင်းချိန်စနစ် (စမ်းသပ်ဆော့ဖ်ဝဲ)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"စီမံဆောင်ရွက်မှု အဆုံးသတ်ရန် ခဏစောင့်ပါ"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"ချန်နယ်ချိန်ဆော့ဖ်ဝဲကို မကြာသေးမီက အပ်ဒိတ်လုပ်ခဲ့သည်။ ချန်နယ်လိုင်းများကို ပြန်ရှာပါ။"</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"အသံဖွင့်ရန် ပတ်ပတ်လည်အသံစနစ်ဆက်တင်များကို ဖွင့်ပါ"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"အသံဖွင့်၍မရပါ။ အခြားတီဗီတွင် စမ်းကြည့်ပါ"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ချန်နယ်ချိန်ကိရိယာ ထည့်သွင်းတပ်ဆင်မှု"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"တီဗီချန်နယ်ချိန်ကိရိယာ ပြင်ဆင်သတ်မှတ်မှု"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB ချန်နယ်ချိန်ကိရိယာ ပြင်ဆင်သတ်မှတ်မှု"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"တီဗီလိုင်းဖမ်းကိရိယာ စနစ်ထည့်သွင်းမှု"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"သင့်တီဗီသည် တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\nအကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ချန်နယ်အများစုကို ဖမ်းယူနိုင်ရန် ၎င်း၏အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိရန် လိုပါသည်။ ရလဒ်များအကောင်းဆုံး ဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပါ။"</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ချန်နယ်ချိန်ကိရိယာကို တပ်ဆင်ထားပြီး တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\nအကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ချန်နယ်အများစုကို ဖမ်းယူနိုင်ရန် ၎င်း၏အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိရန် လိုပါသည်။ ရလဒ်များအကောင်းဆုံး ဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပါ။"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"တီဗီလိုင်းဖမ်းကိရိယာကို ပါဝါဖွင့်ထားခြင်း ရှိ မရှိနှင့် တီဗီစလောင်းသို့ ချိတ်ဆက်ထားခြင်းရှိမရှိ စစ်ဆေးပါ။\n\nအင်တင်နာကို အသုံးပြုလျှင် ၎င်း၏အနေအထား သို့မဟုတ် ဦးတည်ချက်တို့ကို ချိန်ညှိရန် လိုအပ်ပါသည်။ အကောင်းဆုံးရလဒ်အတွက် ပြတင်းပေါက်အနီး အမြင့်ပိုင်းတွင် ထားပါ။"</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"ရှေ့ဆက်ရန်"</item>
+ <item msgid="727245208787621142">"မလုပ်သေးပါ"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"ချန်နယ်စနစ်ထည့်သွင်းမှု ပြန်စမလား။"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"ဤလုပ်ဆောင်ချက်သည် တီဗီချန်နယ်ချိန်ကိရိယာက တွေ့ရှိထားသော ချန်နယ်လိုင်းများကို ဖယ်ရှားလိုက်ပြီး ချန်နယ်အသစ်များကို ထပ်မံရှာဖွေလိမ့်မည်။\n\nသင့်တီဗီသည် တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\nအကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ချန်နယ်အများစုကို ဖမ်းယူနိုင်ရန် ၎င်း၏အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိရန် လိုပါသည်။ ရလဒ်များအကောင်းဆုံး ဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပါ။"</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"ဤလုပ်ဆောင်ချက်သည် USB ချန်နယ်ချိန်ကိရိယာက တွေ့ရှိထားသော ချန်နယ်လိုင်းများကို ဖယ်ရှားလိုက်ပြီး ချန်နယ်အသစ်များကို ထပ်မံရှာဖွေလိမ့်မည်။\n\nUSB ချန်နယ်ချိန်ကိရိယာကို တပ်ဆင်ထားပြီး တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\nအကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ချန်နယ်အများစုကို ဖမ်းယူနိုင်ရန် ၎င်း၏အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိရန် လိုပါသည်။ ရလဒ်များအကောင်းဆုံး ဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပါ။"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"၎င်းသည် တီဗီလိုင်းဖမ်းကိရိယာက ရှာဖွေတွေ့ရှိခဲ့သည့် ချန်နယ်များကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး ချန်နယ်အသစ်များကို ထပ်မံရှာဖွေသွားပါမည်။\n\nတီဗီလိုင်းဖမ်းကိရိယာကို ပါဝါဖွင့်ထားခြင်း ရှိ မရှိနှင့် တီဗီစလောင်းသို့ ချိတ်ဆက်ထားခြင်းရှိမရှိ စစ်ဆေးပါ။\n\nအင်တင်နာကို အသုံးပြုလျှင် ၎င်း၏အနေအထား သို့မဟုတ် ဦးတည်ချက်တို့ကို ချိန်ညှိရန် လိုအပ်ပါသည်။ အကောင်းဆုံးရလဒ်အတွက် ပြတင်းပေါက်အနီး အမြင့်ပိုင်းတွင် ထားပါ။"</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"ရှေ့ဆက်ရန်"</item>
+ <item msgid="235450158666155406">"မလုပ်တော့"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"ချိတ်ဆက်မှု အမျိုးအစားကို ရွေးပါ"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"ချန်နယ်ချိန်ကိရိယာနှင့် ချိတ်ဆက်ထားသော ပြင်ပအန်တန်နာရှိပါက အန်တန်နာကို ရွေးပါ။ ချန်နယ်လိုင်းများအသုံးပြုရန် ကေဘယ်စနစ်သုံး ဝန်ဆောင်မှုပေးသူနှင့် ချိတ်ဆက်ထားပါက ကေဘယ်ကြိုးကို ရွေးပါ။ မသေချာဖြစ်နေလျှင် နှစ်မျိုးလုံးဖြင့် ရှာဖွေနိုင်သော်လည်း အချိန်ပိုကြာနိုင်ပါသည်။"</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"အန်တန်နာ"</item>
+ <item msgid="2670079958754180142">"ကေဘယ်ကြိုး"</item>
+ <item msgid="36774059871728525">"မသေချာပါ။"</item>
+ <item msgid="6881204453182153978">"စမ်းသပ်မှုအတွက်သာ"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"တီဗီချန်နယ်ချိန်ကိရိယာ ပြင်ဆင်သတ်မှတ်မှု"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB ချန်နယ်ချိန်ကိရိယာ ပြင်ဆင်သတ်မှတ်မှု"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"တီဗီလိုင်းဖမ်းကိရိယာ စနစ်ထည့်သွင်းမှု"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"မိနစ်အနည်းငယ် ကြာနိုင်ပါသည်"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"လိုင်းချိန်စက်သည် ယာယီမရနိုင်သေးပါ သို့မဟုတ် ဖမ်းယူခြင်းအတွက် အသုံးပြုနေပြီး ဖြစ်ပါသည်။"</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">ချန်နယ် %1$d လိုင်းတွေ့သည်</item>
+ <item quantity="one">ချန်နယ် %1$d လိုင်းတွေ့သည်</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"ချန်နယ်ရှာဖွေမှုကို ရပ်ရန်"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">ချန်နယ် %1$d လိုင်းတွေ့သည်</item>
+ <item quantity="one">ချန်နယ် %1$d လိုင်းတွေ့သည်</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">သိပ်ကောင်း။ ချန်နယ်ရှာဖွေရာတွင် ချန်နယ် %1$d လိုင်းတွေ့သည်။ မှားယွင်းနေသည်ဟုထင်လျှင် အန်တန်နာအနေအထားကို ချိန်ညှိပြီး ထပ်ရှာကြည့်ပါ။</item>
+ <item quantity="one">သိပ်ကောင်း။ ချန်နယ်ရှာဖွေရာတွင် ချန်နယ် %1$d လိုင်းတွေ့သည်။ မှားယွင်းနေသည်ဟုထင်လျှင် အန်တန်နာအနေအထားကို ချိန်ညှိပြီး ထပ်ရှာကြည့်ပါ။</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"ပြီးသွားပြီ"</item>
+ <item msgid="2480490326672924828">"ထပ်ရှာရန်"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"ချန်နယ်တစ်လိုင်းမျှ မတွေ့ပါ"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"ချန်နယ်များရှာဖွေရာတွင် တစ်လိုင်းမျှ ရှာမတွေ့ပါ။ သင့်တီဗီသည် တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\n အကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ၎င်း၏ အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိပါ။ ရလဒ်များအကောင်းဆုံးဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပြီး ထပ်ရှာကြည့်ပါ။"</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"ချန်နယ်များရှာဖွေရာတွင် တစ်လိုင်းမျှ ရှာမတွေ့ပါ။ USB ချန်နယ်ချိန်ကိရိယာကို တပ်ဆင်ထား၍ တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\n အကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ၎င်း၏ အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိပါ။ ရလဒ်များအကောင်းဆုံးဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပြီး ထပ်ရှာကြည့်ပါ။"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"မည်သည့် ချန်နယ်မျှ ရှာမတွေ့ပါ။ တီဗီလိုင်းဖမ်းကိရိယာကို ပါဝါဖွင့်ထားခြင်းရှိ မရှိနှင့် တီဗီစလောင်းသို့ ချိတ်ဆက်ထားခြင်းရှိမရှိ စစ်ဆေးပါ။\n\nအင်တင်နာကို အသုံးပြုလျှင် ၎င်း၏အနေအထား သို့မဟုတ် ဦးတည်ချက်တို့ကို ချိန်ညှိရန် လိုအပ်ပါသည်။ အကောင်းဆုံးရလဒ်အတွက် ပြတင်းပေါက်အနီး အမြင့်ပိုင်းတွင် ထားပါ။"</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"ထပ်ရှာရန်"</item>
+ <item msgid="2092797862490235174">"ပြီးသွားပြီ"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"TV ချန်နယ်ရှာမည်"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"တီဗီဖမ်းစက် အပြင်အဆင်"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB တီဗီဖမ်းစက် အပြင်အဆင်"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"အင်တာနက် တီဗီဖမ်းစက် အပြင်အဆင်"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB တီဗီလိုင်းချိန်ကိရိယာကို ဖြုတ်လိုက်ပါပြီ။"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"ကွန်ရက်လိုင်းချိန်ကိရိယာကို ဖြုတ်လိုက်ပါပြီ။"</string>
+</resources>
diff --git a/usbtuner-res/values-my/strings.xml b/usbtuner-res/values-my/strings.xml
deleted file mode 100644
index 56a29e51..00000000
--- a/usbtuner-res/values-my/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"တီဗီချန်နယ်ချိန်ကိရိယာ"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB တီဗီချန်နယ်ချိန်ကိရိယာ"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"ဖွင့်ပါ"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"ပိတ်ပါ"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"စီမံဆောင်ရွက်မှု အဆုံးသတ်ရန် ခဏစောင့်ပါ"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"သင့်ချန်နယ်လိုင်းထုတ်လွှင့်ရာ အရင်းအမြစ်ကို ရွေးပါ"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"လိုင်းမမိပါ"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> သို့ ချိန်ညှိခြင်း မအောင်မြင်ပါ"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ချိန်ညှိ၍ မရခဲ့ပါ"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"ချန်နယ်ချိန်ဆော့ဖ်ဝဲကို မကြာသေးမီက အပ်ဒိတ်လုပ်ခဲ့သည်။ ချန်နယ်လိုင်းများကို ပြန်ရှာပါ။"</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"အသံဖွင့်ရန် ပတ်ပတ်လည်အသံစနစ်ဆက်တင်များကို ဖွင့်ပါ"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ချန်နယ်ချိန်ကိရိယာ ထည့်သွင်းတပ်ဆင်မှု"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"တီဗီချန်နယ်ချိန်ကိရိယာ ပြင်ဆင်သတ်မှတ်မှု"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB ချန်နယ်ချိန်ကိရိယာ ပြင်ဆင်သတ်မှတ်မှု"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"သင့်တီဗီသည် တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\nအကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ချန်နယ်အများစုကို ဖမ်းယူနိုင်ရန် ၎င်း၏အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိရန် လိုပါသည်။ ရလဒ်များအကောင်းဆုံး ဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပါ။"</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ချန်နယ်ချိန်ကိရိယာကို တပ်ဆင်ထားပြီး တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\nအကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ချန်နယ်အများစုကို ဖမ်းယူနိုင်ရန် ၎င်း၏အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိရန် လိုပါသည်။ ရလဒ်များအကောင်းဆုံး ဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပါ။"</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"ရှေ့ဆက်ရန်"</item>
- <item msgid="727245208787621142">"မလုပ်သေးပါ"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"ချန်နယ်စနစ်ထည့်သွင်းမှု ပြန်စမလား။"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"ဤလုပ်ဆောင်ချက်သည် တီဗီချန်နယ်ချိန်ကိရိယာက တွေ့ရှိထားသော ချန်နယ်လိုင်းများကို ဖယ်ရှားလိုက်ပြီး ချန်နယ်အသစ်များကို ထပ်မံရှာဖွေလိမ့်မည်။\n\nသင့်တီဗီသည် တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\nအကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ချန်နယ်အများစုကို ဖမ်းယူနိုင်ရန် ၎င်း၏အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိရန် လိုပါသည်။ ရလဒ်များအကောင်းဆုံး ဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပါ။"</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"ဤလုပ်ဆောင်ချက်သည် USB ချန်နယ်ချိန်ကိရိယာက တွေ့ရှိထားသော ချန်နယ်လိုင်းများကို ဖယ်ရှားလိုက်ပြီး ချန်နယ်အသစ်များကို ထပ်မံရှာဖွေလိမ့်မည်။\n\nUSB ချန်နယ်ချိန်ကိရိယာကို တပ်ဆင်ထားပြီး တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\nအကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ချန်နယ်အများစုကို ဖမ်းယူနိုင်ရန် ၎င်း၏အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိရန် လိုပါသည်။ ရလဒ်များအကောင်းဆုံး ဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပါ။"</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"ရှေ့ဆက်ရန်"</item>
- <item msgid="235450158666155406">"မလုပ်တော့"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"ချိတ်ဆက်မှု အမျိုးအစားကို ရွေးပါ"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"ချန်နယ်ချိန်ကိရိယာနှင့် ချိတ်ဆက်ထားသော ပြင်ပအန်တန်နာရှိပါက အန်တန်နာကို ရွေးပါ။ ချန်နယ်လိုင်းများအသုံးပြုရန် ကေဘယ်စနစ်သုံး ဝန်ဆောင်မှုပေးသူနှင့် ချိတ်ဆက်ထားပါက ကေဘယ်ကြိုးကို ရွေးပါ။ မသေချာဖြစ်နေလျှင် နှစ်မျိုးလုံးဖြင့် ရှာဖွေနိုင်သော်လည်း အချိန်ပိုကြာနိုင်ပါသည်။"</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"အန်တန်နာ"</item>
- <item msgid="2670079958754180142">"ကေဘယ်ကြိုး"</item>
- <item msgid="36774059871728525">"မသေချာပါ။"</item>
- <item msgid="6881204453182153978">"စမ်းသပ်မှုအတွက်သာ"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"တီဗီချန်နယ်ချိန်ကိရိယာ ပြင်ဆင်သတ်မှတ်မှု"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB ချန်နယ်ချိန်ကိရိယာ ပြင်ဆင်သတ်မှတ်မှု"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"မိနစ်အနည်းငယ် ကြာနိုင်ပါသည်"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"လိုင်းချိန်စက်သည် ယာယီမရနိုင်သေးပါ သို့မဟုတ် ဖမ်းယူခြင်းအတွက် အသုံးပြုနေပြီး ဖြစ်ပါသည်။"</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">ချန်နယ် %1$d လိုင်းတွေ့သည်</item>
- <item quantity="one">ချန်နယ် %1$d လိုင်းတွေ့သည်</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"ချန်နယ်ရှာဖွေမှုကို ရပ်ရန်"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">ချန်နယ် %1$d လိုင်းတွေ့သည်</item>
- <item quantity="one">ချန်နယ် %1$d လိုင်းတွေ့သည်</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">သိပ်ကောင်း။ ချန်နယ်ရှာဖွေရာတွင် ချန်နယ် %1$d လိုင်းတွေ့သည်။ မှားယွင်းနေသည်ဟုထင်လျှင် အန်တန်နာအနေအထားကို ချိန်ညှိပြီး ထပ်ရှာကြည့်ပါ။</item>
- <item quantity="one">သိပ်ကောင်း။ ချန်နယ်ရှာဖွေရာတွင် ချန်နယ် %1$d လိုင်းတွေ့သည်။ မှားယွင်းနေသည်ဟုထင်လျှင် အန်တန်နာအနေအထားကို ချိန်ညှိပြီး ထပ်ရှာကြည့်ပါ။</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"ပြီးသွားပြီ"</item>
- <item msgid="2480490326672924828">"ထပ်ရှာရန်"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"ချန်နယ်တစ်လိုင်းမျှ မတွေ့ပါ"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"ချန်နယ်များရှာဖွေရာတွင် တစ်လိုင်းမျှ ရှာမတွေ့ပါ။ သင့်တီဗီသည် တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\n အကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ၎င်း၏ အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိပါ။ ရလဒ်များအကောင်းဆုံးဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပြီး ထပ်ရှာကြည့်ပါ။"</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"ချန်နယ်များရှာဖွေရာတွင် တစ်လိုင်းမျှ ရှာမတွေ့ပါ။ USB ချန်နယ်ချိန်ကိရိယာကို တပ်ဆင်ထား၍ တီဗီချန်နယ်ထုတ်လွှင့်ရာ အရင်းအမြစ်တစ်ခုနှင့် ချိတ်ဆက်ထားကြောင်း အတည်ပြုပါ။\n\n အကယ်၍ ကောင်းကင်အန်တန်နာတိုင်ကို အသုံးပြုနေပါက ၎င်း၏ အနေအထား (သို့) ဦးတည်ဘက်ကို ချိန်ညှိပါ။ ရလဒ်များအကောင်းဆုံးဖြစ်စေရန် ၎င်းကို ပြတင်းပေါက်နားတွင် မြင့်မြင့်ထားပြီး ထပ်ရှာကြည့်ပါ။"</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"ထပ်ရှာရန်"</item>
- <item msgid="2092797862490235174">"ပြီးသွားပြီ"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"တီဗီချန်နယ်များကို ရှာပါ"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"တီဗီချန်နယ်ချိန် ကိရိယာအက်ပ် ထည့်သွင်းမှု"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB တီဗီချန်နယ်ချိန်အက်ပ် ထည့်သွင်းမှု"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB တီဗီချိန်စက်ကို ဖြုတ်လိုက်ပါပြီ"</string>
-</resources>
diff --git a/usbtuner-res/values-nb/strings.xml b/usbtuner-res/values-nb/strings.xml
index bce9e176..ed45555b 100644
--- a/usbtuner-res/values-nb/strings.xml
+++ b/usbtuner-res/values-nb/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV-tuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB-tuneren for TV"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"På"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Av"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Nettverkstuner for TV (betaversjon)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Vent til behandlingen er fullført"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Velg en kanalkilde"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Ikke noe signal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Kunne ikke bytte kanal til <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Kunne ikke bytte kanal"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Programvaren for tuneren er nylig blitt oppdatert. Du må skanne kanalene på nytt."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Slå på surroundlyd i innstillingene for systemlyd for å slå på lyd"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Kan ikke spille av lyd. Prøv en annen TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Konfigurasjon av kanaler via tuneren"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Konfigurasjon av TV-tuneren"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Konfigurasjon av kanaler via USB-tuneren"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Konfigurasjon av nettverkstuner"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Bekreft at TV-en din er koblet til en TV-signalkilde.\n\nHvis du bruker en trådløs antenne, kan det hende du må justere posisjonen eller retningen for å motta flest mulig kanaler. For å få de beste resultatene bør du plassere antennen høyt og i nærheten av et vindu."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Bekreft at USB-tuneren er plugget i og koblet til en TV-signalkilde.\n\nHvis du bruker en trådløs antenne, kan det hende du må justere posisjonen eller retningen for å motta flest mulig kanaler. For å få de beste resultatene bør du plassere antennen høyt og i nærheten av et vindu."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Bekreft at nettverkstuneren er slått på og koblet til en TV-signalkilde.\n\nHvis du bruker en trådløs antenne, må du kanskje justere posisjonen eller retningen for å motta flere kanaler. For å få de beste resultatene bør du plassere antennen høyt og i nærheten av et vindu."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Fortsett"</item>
<item msgid="727245208787621142">"Ikke nå"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Vil du kjøre kanalkonfigureringen på nytt?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Dette fjerner kanalene som ble funnet med TV-tuneren, og skanner etter nye kanaler igjen.\n\nBekreft at TV-en din er koblet til en TV-signalkilde.\n\nHvis du bruker en trådløs antenne, kan det hende du må justere posisjonen eller retningen for å motta flest mulig kanaler. For å få de beste resultatene bør du plassere antennen høyt og i nærheten av et vindu."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Dette fjerner kanaler som er funnet via USB-tuneren, og skanner på nytt etter nye kanaler.\n\nBekreft at USB-tuneren er plugget i og koblet til en TV-signalkilde.\n\nHvis du bruker en trådløs antenne, kan det hende du må justere posisjonen eller retningen for å motta flest mulig kanaler. For å få de beste resultatene bør du plassere antennen høyt og i nærheten av et vindu."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Dette fjerner kanalene som ble funnet av nettverkstuneren, og skanner på nytt etter nye kanaler.\n\nBekreft at nettverkstuneren er slått på og koblet til en TV-signalkilde.\n\nHvis du bruker en trådløs antenne, må du kanskje justere posisjonen eller retningen for å motta flere kanaler. For å få de beste resultatene bør du plassere antennen høyt og i nærheten av et vindu."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Fortsett"</item>
<item msgid="235450158666155406">"Avbryt"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Konfigurasjon av TV-tuneren"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Konfigurasjon av kanaler via USB-tuneren"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Konfigurasjon av tuner for nettverkskanaler"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Dette kan ta flere minutter"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuneren er midlertidig utilgjengelig eller brukes allerede av opptak."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Fant ingen kanaler"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Ingen kanaler ble funnet under skanningen. Bekreft at TV-en din er koblet til en TV-signalkilde.\n\nHvis du bruker en trådløs antenne, kan du justere posisjonen eller retningen. For å få de beste resultatene bør du plassere antennen høyt og i nærheten av et vindu. Deretter skanner du på nytt."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Fant ingen kanaler under skanningen. Bekreft at USB-tuneren er plugget i og koblet til en TV-signalkilde.\n\nHvis du bruker en trådløs antenne, kan du justere posisjonen eller retningen. For å få de beste resultatene bør du plassere antennen høyt og i nærheten av et vindu. Deretter skanner du på nytt."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Skanningen fant ingen kanaler. Bekreft at nettverkstuneren er slått på og koblet til en TV-signalkilde.\n\nHvis du bruker en trådløs antenne, må du justere posisjonen eller retningen. For å få de beste resultatene bør du plassere antennen høyt og i nærheten av et vindu. Deretter skanner du på nytt."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Skann på nytt"</item>
<item msgid="2092797862490235174">"Ferdig"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Skann etter TV-kanaler"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Konfigurasjon av TV-tuneren"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Konfigurasjon av USB-tuner for TV"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB-tuneren for TV er frakoblet."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Skann etter TV-kanaler"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Konfigurasjon av TV-tuneren"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Konfigurasjon av USB-tuner for TV"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Konfigurasjon av nettverkstuner for TV"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-tuneren for TV er frakoblet."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Nettverkstuneren er frakoblet."</string>
</resources>
diff --git a/usbtuner-res/values-ne-rNP/strings.xml b/usbtuner-res/values-ne-rNP/strings.xml
new file mode 100644
index 00000000..5f1e3330
--- /dev/null
+++ b/usbtuner-res/values-ne-rNP/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"TV ट्युनर"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB TV ट्युनर"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"नेटवर्कको TV ट्युनर (बिटा)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"कृपया प्रक्रिया सम्पन्न हुने प्रतीक्षा गर्नुहोस्"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"ट्युनरको सफ्टवेयरलाई हालसालै अद्यावधिक गरिएको छ। कृपया च्यानलहरू पुन:स्क्यान गर्नुहोस्।"</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"अडियोलाई सक्षम पार्न प्रणालीको ध्वनि सम्बन्धी सेटिङहरूमा गई सराउन्ड साउन्डलाई सक्षम पार्नुहोस्"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"अडियो बजाउन सकिँदैन। कृपया अर्को TV को प्रयोग गरी हेर्नुहोस्"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"च्यानल ट्युनरको सेटअप"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"TV ट्युनरको सेटअप"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB च्यानल ट्युनरको सेटअप"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"नेटवर्क ट्युनरको सेटअप"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"तपाईँको TV कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने धेरै च्यानलहरू प्राप्त गर्न तपाईँले त्यसको स्थान वा दिशा समायोजन गर्नुपर्ने हुन सक्छ। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राख्नुहोस्।"</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ट्युनर प्लगइन रहेको र कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने धेरै च्यानलहरू प्राप्त गर्न तपाईँले त्यसको स्थान वा दिशा समायोजन गर्नुपर्ने हुन सक्छ। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राख्नुहोस्।"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"नेटवर्क ट्युनर सक्रिय रहेको र कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने धेरै च्यानलहरू प्राप्त गर्न तपाईंले त्यसको स्थान वा दिशा समायोजन गर्नुपर्ने हुन सक्छ। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राख्नुहोस्।"</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"जारी राख्नुहोस्"</item>
+ <item msgid="727245208787621142">"अहिले होइन"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"च्यानलको सेटअप पुनःसञ्चालन गर्ने हो?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"यसले USB ट्युनरबाट भेट्टिएका च्यानलहरूलाई हटाउनेछ र नयाँ च्यानलहरू भेट्टाउन फेरि स्क्यान गर्नेछ।\n\nतपाईँको TV कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने धेरै च्यानलहरू प्राप्त गर्न तपाईँले त्यसको स्थान वा दिशा समायोजन गर्नुपर्ने हुन सक्छ। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राख्नुहोस्।"</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"यसले USB ट्युनरबाट भेट्टिएका च्यानलहरूलाई हटाउनेछ र नयाँ च्यानलहरू भेट्टाउन फेरि स्क्यान गर्नेछ।\n\nUSB ट्युनर प्लगइन गरिएको र कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने धेरै च्यानलहरू प्राप्त गर्न तपाईँले त्यसको स्थान वा दिशा समायोजन गर्नुपर्ने हुन सक्छ। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राख्नुहोस्।"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"यसले नेटवर्क ट्युनर मार्फत भेट्टिएका च्यानलहरूलाई हटाउनेछ र नयाँ च्यानलहरू भेट्टाउन फेरि स्क्यान गर्नेछ।\n\nनेटवर्क ट्युनरलाई सक्रिय गरिएको र कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने धेरै च्यानलहरू प्राप्त गर्न तपाईंले त्यसको स्थान वा दिशा समायोजन गर्नुपर्ने हुन सक्छ। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राख्नुहोस्।"</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"जारी राख्नुहोस्"</item>
+ <item msgid="235450158666155406">"रद्द गर्नुहोस्"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"जडानको प्रकार चयन गर्नुहोस्"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"यदि उक्त ट्युनरमा कुनै बाह्य एन्टेना जडान गरिएको छ भने एन्टेना छनौट गर्नुहोस्। यदि तपाईंका च्यानलहरू केबल सेवा प्रदायक मार्फत आउँछन् भने केबल छनौट गर्नुहोस्। यदि तपाईं निश्चित हुनुहुन्न भने दुवै प्रकारहरू स्क्यान गरिने छन् तर यसमा लामो समय लाग्न सक्छ।"</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"एन्टेना"</item>
+ <item msgid="2670079958754180142">"केबल"</item>
+ <item msgid="36774059871728525">"निश्चित छैन"</item>
+ <item msgid="6881204453182153978">"विकासका लागि मात्र"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"TV ट्युनरको सेटअप"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB च्यानल ट्युनरको सेटअप"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"नेटवर्कको च्यानल ट्युनरको सेटअप"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"यसमा धेरै मिनेट लाग्न सक्छ"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ट्युनर अस्थायी रूपले अनुपलब्ध छ वा रेकर्डिङद्वारा पहिले नै प्रयोग गरिएको छ।"</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d च्यानलहरू भेट्टिए</item>
+ <item quantity="one">%1$d च्यानल भेट्टियो</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"च्यानल स्क्यान गर्न रोक्नुहोस्"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d च्यानलहरू भेट्टिए</item>
+ <item quantity="one">%1$d च्यानल भेट्टियो</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">राम्रो खबर छ! च्यानल स्क्यान गर्दा %1$d च्यानलहरू भेट्टिए। यदि यो सही हो जस्तो लाग्दैन भने एन्टेनाको स्थिति समायोजन गरी हेर्नुहोस् र फेरि स्क्यान गर्नुहोस्।</item>
+ <item quantity="one">राम्रो खबर छ! च्यानल स्क्यान गर्दा %1$d च्यानल भेट्टियो। यदि यो सही हो जस्तो लाग्दैन भने एन्टेनाको स्थिति समायोजन गरी हेर्नुहोस् र फेरि स्क्यान गर्नुहोस्।</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"सम्पन्न भयो"</item>
+ <item msgid="2480490326672924828">"फेरि स्क्यान गर्नुहोस्"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"कुनै च्यानल भेट्टिएन"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"उक्त स्क्यानले कुनै पनि च्यानल भेट्टाएन। तपाईँको TV कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने त्यसको स्थान वा दिशा समायोजन गर्नुहोस्। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राखी फेरि स्क्यान गर्नुहोस्।"</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"उक्त स्क्यानले कुनै पनि च्यानल भेट्टाएन। USB ट्युनर प्लगइन गरिएको र कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने त्यसको स्थान वा दिशा समायोजन गर्नुहोस्। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राखी फेरि स्क्यान गर्नुहोस्।"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"उक्त स्क्यानले कुनै पनि च्यानल भेट्टाएन। नेटवर्क ट्युनरलाई सक्रिय गरिएको र कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने त्यसको स्थान वा दिशा समायोजन गर्नुहोस्। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राखी फेरि स्क्यान गर्नुहोस्।"</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"फेरि स्क्यान गर्नुहोस्"</item>
+ <item msgid="2092797862490235174">"सम्पन्न भयो"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"TV च्यानलहरू भेट्टाउन स्क्यान गर्नुहोस्"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV ट्युनरको सेटअप"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV ट्युनरको सेटअप"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"नेटवर्कको TV ट्युनरको सेटअप"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV ट्युनरलाई विच्छेद गरियो।"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"नेटवर्क ट्युनरलाई विच्छेद गरियो।"</string>
+</resources>
diff --git a/usbtuner-res/values-ne/strings.xml b/usbtuner-res/values-ne/strings.xml
deleted file mode 100644
index 07d68e2c..00000000
--- a/usbtuner-res/values-ne/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"TV ट्युनर"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB TV ट्युनर"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"सक्रिय"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"निष्क्रिय"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"कृपया प्रक्रिया सम्पन्न हुने प्रतीक्षा गर्नुहोस्"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"आफ्नो च्यानलको स्रोत चयन गर्नुहोस्"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"कुनै सिग्‍नल छैन"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> मा ट्युन गर्न सकिएन"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ट्युन गर्न सकिएन"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"ट्युनरको सफ्टवेयरलाई हालसालै अद्यावधिक गरिएको छ। कृपया च्यानलहरू पुन:स्क्यान गर्नुहोस्।"</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"अडियोलाई सक्षम पार्न प्रणालीको ध्वनि सम्बन्धी सेटिङहरूमा गई सराउन्ड साउन्डलाई सक्षम पार्नुहोस्"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"च्यानल ट्युनरको सेटअप"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"TV ट्युनरको सेटअप"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB च्यानल ट्युनरको सेटअप"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"तपाईँको TV कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने धेरै च्यानलहरू प्राप्त गर्न तपाईँले त्यसको स्थान वा दिशा समायोजन गर्नुपर्ने हुन सक्छ। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राख्नुहोस्।"</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ट्युनर प्लगइन रहेको र कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने धेरै च्यानलहरू प्राप्त गर्न तपाईँले त्यसको स्थान वा दिशा समायोजन गर्नुपर्ने हुन सक्छ। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राख्नुहोस्।"</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"जारी राख्नुहोस्"</item>
- <item msgid="727245208787621142">"अहिले होइन"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"च्यानलको सेटअप पुनःसञ्चालन गर्ने हो?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"यसले USB ट्युनरबाट भेट्टिएका च्यानलहरूलाई हटाउनेछ र नयाँ च्यानलहरू भेट्टाउन फेरि स्क्यान गर्नेछ।\n\nतपाईँको TV कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने धेरै च्यानलहरू प्राप्त गर्न तपाईँले त्यसको स्थान वा दिशा समायोजन गर्नुपर्ने हुन सक्छ। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राख्नुहोस्।"</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"यसले USB ट्युनरबाट भेट्टिएका च्यानलहरूलाई हटाउनेछ र नयाँ च्यानलहरू भेट्टाउन फेरि स्क्यान गर्नेछ।\n\nUSB ट्युनर प्लगइन गरिएको र कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने धेरै च्यानलहरू प्राप्त गर्न तपाईँले त्यसको स्थान वा दिशा समायोजन गर्नुपर्ने हुन सक्छ। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राख्नुहोस्।"</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"जारी राख्नुहोस्"</item>
- <item msgid="235450158666155406">"रद्द गर्नुहोस्"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"जडानको प्रकार चयन गर्नुहोस्"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"यदि उक्त ट्युनरमा कुनै बाह्य एन्टेना जडान गरिएको छ भने एन्टेना छनौट गर्नुहोस्। यदि तपाईँका च्यानलहरू केबल सेवा प्रदायक मार्फत आउँछन् भने केबल छनौट गर्नुहोस्। यदि तपाईँ निश्चित हुनुहुन्न भने दुवै प्रकारहरू स्क्यान गरिने छन् तर यसमा लामो समय लाग्न सक्छ।"</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"एन्टेना"</item>
- <item msgid="2670079958754180142">"केबल"</item>
- <item msgid="36774059871728525">"निश्चित छैन"</item>
- <item msgid="6881204453182153978">"विकासका लागि मात्र"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"TV ट्युनरको सेटअप"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB च्यानल ट्युनरको सेटअप"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"यसमा धेरै मिनेट लाग्न सक्छ"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ट्युनर अस्थायी रूपले अनुपलब्ध छ वा रेकर्डिङद्वारा पहिले नै प्रयोग गरिएको छ।"</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d च्यानलहरू भेट्टिए</item>
- <item quantity="one">%1$d च्यानल भेट्टियो</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"च्यानल स्क्यान गर्न रोक्नुहोस्"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d च्यानलहरू भेट्टिए</item>
- <item quantity="one">%1$d च्यानल भेट्टियो</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">राम्रो खबर छ! च्यानल स्क्यान गर्दा %1$d च्यानलहरू भेट्टिए। यदि यो सही हो जस्तो लाग्दैन भने एन्टेनाको स्थिति समायोजन गरी हेर्नुहोस् र फेरि स्क्यान गर्नुहोस्।</item>
- <item quantity="one">राम्रो खबर छ! च्यानल स्क्यान गर्दा %1$d च्यानल भेट्टियो। यदि यो सही हो जस्तो लाग्दैन भने एन्टेनाको स्थिति समायोजन गरी हेर्नुहोस् र फेरि स्क्यान गर्नुहोस्।</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"सम्पन्न भयो"</item>
- <item msgid="2480490326672924828">"फेरि स्क्यान गर्नुहोस्"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"कुनै च्यानल भेट्टिएन"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"उक्त स्क्यानले कुनै पनि च्यानल भेट्टाएन। तपाईँको TV कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने त्यसको स्थान वा दिशा समायोजन गर्नुहोस्। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राखी फेरि स्क्यान गर्नुहोस्।"</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"उक्त स्क्यानले कुनै पनि च्यानल भेट्टाएन। USB ट्युनर प्लगइन गरिएको र कुनै TV सिग्नलको स्रोतमा जडान गरिएको छ भनी पुष्टि गर्नुहोस्।\n\nयदि कुनै ओभर-दि-एयर एन्टेनाको प्रयोग भइरहेको छ भने त्यसको स्थान वा दिशा समायोजन गर्नुहोस्। उत्कृष्ट परिणामहरूका लागि त्यसलाई उच्च स्थानमा र कुनै झ्यालको नजिक राखी फेरि स्क्यान गर्नुहोस्।"</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"फेरि स्क्यान गर्नुहोस्"</item>
- <item msgid="2092797862490235174">"सम्पन्न भयो"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"TV च्यानलहरू भेट्टाउन स्क्यान गर्नुहोस्"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV ट्युनरको सेटअप"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV ट्युनरको सेटअप"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV ट्युनरलाई विच्छेद गरियो।"</string>
-</resources>
diff --git a/usbtuner-res/values-nl/strings.xml b/usbtuner-res/values-nl/strings.xml
index b9e18682..34b0d927 100644
--- a/usbtuner-res/values-nl/strings.xml
+++ b/usbtuner-res/values-nl/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Tv-tuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB-tv-tuner"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Aan"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Uit"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Netwerk-tv-tuner (BÈTA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Wacht tot het proces is voltooid"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Selecteer je kanaalbron"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Geen signaal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Kan niet afstemmen op <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Kan niet afstemmen"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"De software van de tuner is recent geüpdatet. Scan de kanalen opnieuw."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Schakel surrond sound in via de geluidsinstellingen van het systeem om audio in te schakelen"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Kan audio niet afspelen. Probeer een andere tv."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configuratie van kanaaltuner"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Tv-tuner instellen"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Kanaalconfiguratie van USB-tuner"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Netwerktuner instellen"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Controleer of je tv is aangesloten op een tv-signaalbron.\n\nAls je een over-the-air-antenne gebruikt, moet je de positie of richting daarvan mogelijk aanpassen om zo veel mogelijk kanalen te ontvangen. Voor de beste resultaten plaats je de antenne op een hoge plek in de buurt van een raam."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Controleer of de USB-tuner is ingeschakeld en aangesloten op een tv-signaalbron.\n\nAls je een over-the-air-antenne gebruikt, moet je de positie of richting daarvan mogelijk aanpassen om zo veel mogelijk kanalen te ontvangen. Voor de beste resultaten plaats je de antenne op een hoge plek in de buurt van een raam."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Controleer of de netwerktuner is ingeschakeld en aangesloten op een tv-signaalbron.\n\nAls je een over-the-air-antenne gebruikt, moet je de positie of richting daarvan mogelijk aanpassen om zo veel mogelijk kanalen te ontvangen. Voor de beste resultaten plaats je de antenne op een hoge plek in de buurt van een raam."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Doorgaan"</item>
<item msgid="727245208787621142">"Niet nu"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Kanaalconfiguratie opnieuw uitvoeren?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Hiermee worden de gevonden kanalen verwijderd van de tv-tuner en wordt opnieuw gezocht naar nieuwe kanalen.\n\nControleer of je tv is aangesloten op een tv-signaalbron.\n\nAls je een over-the-air-antenne gebruikt, moet je de positie of richting daarvan mogelijk aanpassen om zo veel mogelijk kanalen te ontvangen. Voor de beste resultaten plaats je de antenne op een hoge plek in de buurt van een raam."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Hiermee worden de gevonden kanalen verwijderd van de USB-tuner en wordt opnieuw gescand naar nieuwe kanalen.\n\nControleer of de USB-tuner is ingeschakeld en aangesloten op een tv-signaalbron.\n\nAls je een over-the-air-antenne gebruikt, moet je de positie of richting daarvan mogelijk aanpassen om zo veel mogelijk kanalen te ontvangen. Voor de beste resultaten plaats je de antenne op een hoge plek in de buurt van een raam."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Hiermee worden de gevonden kanalen verwijderd van de netwerktuner en wordt opnieuw gezocht naar nieuwe kanalen.\n\nControleer of de netwerktuner is ingeschakeld en aangesloten op een tv-signaalbron.\n\nAls je een over-the-air-antenne gebruikt, moet je de positie of richting daarvan mogelijk aanpassen om zo veel mogelijk kanalen te ontvangen. Voor de beste resultaten plaats je de antenne op een hoge plek in de buurt van een raam."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Doorgaan"</item>
<item msgid="235450158666155406">"Annuleren"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Tv-tuner instellen"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Kanaalconfiguratie van USB-tuner"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Netwerkkanaaltuner instellen"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Dit kan enkele minuten duren"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"De tuner is tijdelijk niet beschikbaar of wordt al gebruikt voor een opname."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Geen kanalen gevonden"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Er zijn geen kanalen gevonden tijdens de scan. Controleer of je tv is aangesloten op een tv-signaalbron.\n\nAls je een over-the-air-antenne gebruikt, pas je de positie of richting daarvan aan. Voor de beste resultaten plaats je de antenne op een hoge plek in de buurt van een raam en voer je de scan opnieuw uit."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Er zijn geen kanalen gevonden tijdens de scan. Controleer of de USB-tuner is ingeschakeld en aangesloten op een tv-signaalbron.\n\nAls je een over-the-air-antenne gebruikt, pas je de positie of richting daarvan aan. Voor de beste resultaten plaats je de antenne op een hoge plek in de buurt van een raam en voer je de scan opnieuw uit."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"De scan heeft geen kanalen gevonden. Controleer of de netwerktuner is ingeschakeld en aangesloten op een tv-signaalbron.\n\nAls je een over-the-air-antenne gebruikt, moet je de positie of richting daarvan mogelijk aanpassen. Voor de beste resultaten plaats je de antenne op een hoge plek in de buurt van een raam en voer je de scan opnieuw uit."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Opnieuw scannen"</item>
<item msgid="2092797862490235174">"Gereed"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Scannen naar tv-kanalen"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Tv-tuner instellen"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB-tv-tuner instellen"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB-tv-tuner ontkoppeld."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Zoeken naar tv-zenders"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Tv-tuner instellen"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB-tv-tuner instellen"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Netwerk-tv-tuner instellen"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-tv-tuner losgekoppeld."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Netwerktuner losgekoppeld."</string>
</resources>
diff --git a/usbtuner-res/values-pl/strings.xml b/usbtuner-res/values-pl/strings.xml
index 0bc7e734..9daa3621 100644
--- a/usbtuner-res/values-pl/strings.xml
+++ b/usbtuner-res/values-pl/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Tuner TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Tuner TV USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Włącz"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Wyłącz"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Sieciowy tuner TV (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Poczekaj na zakończenie przetwarzania"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Wybierz źródło kanału"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Brak sygnału"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Nie udało się dostroić kanału <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Nie udało się dostroić kanału"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Oprogramowanie tunera zostało niedawno zaktualizowane. Przeskanuj ponownie kanały."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Aby włączyć dźwięk, włącz dźwięk przestrzenny w ustawieniach systemowych dźwięku"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Nie można odtworzyć dźwięku. Spróbuj użyć innego telewizora"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Konfiguracja kanałów w tunerze"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Konfiguracja tunera TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Konfiguracja kanałów w tunerze USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Konfiguracja tunera sieciowego"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Upewnij się, że telewizor jest podłączony do źródła sygnału telewizyjnego.\n\nJeśli używasz anteny telewizyjnej, może być konieczne wyregulowanie jej położenia lub kierunku, by można było odbierać jak najwięcej kanałów. Aby uzyskać najlepszy sygnał, umieść antenę na podwyższeniu, w pobliżu okna."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Upewnij się, że tuner USB jest podłączony do telewizora oraz do źródła sygnału telewizyjnego.\n\nJeśli używasz anteny telewizyjnej, może być konieczne wyregulowanie jej położenia lub kierunku, by można było odbierać jak najwięcej kanałów. Aby uzyskać najlepszy sygnał, umieść antenę na podwyższeniu, w pobliżu okna."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Upewnij się, że tuner sieciowy jest włączony i został podłączony do źródła sygnału telewizyjnego.\n\nJeśli używasz anteny telewizyjnej, może być konieczne wyregulowanie jej położenia lub kierunku, by można było odbierać jak najwięcej kanałów. Aby uzyskać najlepszy sygnał, umieść antenę na podwyższeniu, w pobliżu okna."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Kontynuuj"</item>
<item msgid="727245208787621142">"Nie teraz"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Skonfigurować ponownie kanały?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Spowoduje to usunięcie kanałów znalezionych przez tuner TV i ponowne wykonanie skanowania.\n\nUpewnij się, że telewizor jest podłączony do źródła sygnału telewizyjnego.\n\nJeśli używasz anteny telewizyjnej, może być konieczne wyregulowanie jej położenia lub kierunku, by można było odbierać jak najwięcej kanałów. Aby uzyskać najlepszy sygnał, umieść antenę na podwyższeniu, w pobliżu okna."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Spowoduje to usunięcie kanałów znalezionych przez tuner USB i ponowne wykonanie skanowania.\n\nUpewnij się, że tuner USB jest podłączony do telewizora oraz do źródła sygnału telewizyjnego.\n\nJeśli używasz anteny telewizyjnej, może być konieczne wyregulowanie jej położenia lub kierunku, by można było odbierać jak najwięcej kanałów. Aby uzyskać najlepszy sygnał, umieść antenę na podwyższeniu, w pobliżu okna."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Spowoduje to usunięcie kanałów znalezionych przez tuner sieciowy i ponowne wykonanie skanowania.\n\nUpewnij się, że tuner sieciowy jest włączony i został podłączony do źródła sygnału telewizyjnego.\n\nJeśli używasz anteny telewizyjnej, może być konieczne wyregulowanie jej położenia lub kierunku, by można było odbierać jak najwięcej kanałów. Aby uzyskać najlepszy sygnał, umieść antenę na podwyższeniu, w pobliżu okna."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Kontynuuj"</item>
<item msgid="235450158666155406">"Anuluj"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Konfiguracja tunera TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Konfiguracja kanałów w tunerze USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Konfiguracja kanałów w tunerze sieciowym"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Może to potrwać kilka minut"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuner jest czasowo niedostępny lub właśnie nagrywa."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -82,12 +82,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Nie znaleziono kanałów"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Podczas skanowania nie znaleziono żadnych kanałów. Upewnij się, że telewizor jest podłączony do źródła sygnału telewizyjnego.\n\nJeśli używasz anteny telewizyjnej, wyreguluj jej położenie lub kierunek. Aby uzyskać najlepszy sygnał, umieść antenę na podwyższeniu, w pobliżu okna, a następnie ponownie wykonaj skanowanie."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Podczas skanowania nie znaleziono żadnych kanałów. Upewnij się, że tuner USB jest podłączony do telewizora oraz do źródła sygnału telewizyjnego.\n\nJeśli używasz anteny telewizyjnej, wyreguluj jej położenie lub kierunek. Aby uzyskać najlepszy sygnał, umieść antenę na podwyższeniu, w pobliżu okna, a następnie ponownie wykonaj skanowanie."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Podczas skanowania nie znaleziono żadnych kanałów. Upewnij się, że tuner sieciowy jest włączony i został podłączony do źródła sygnału telewizyjnego.\n\nJeśli używasz anteny telewizyjnej, wyreguluj jej położenie lub kierunek. Aby uzyskać najlepszy sygnał, umieść antenę na podwyższeniu, w pobliżu okna, a następnie ponownie wykonaj skanowanie."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Skanuj ponownie"</item>
<item msgid="2092797862490235174">"Gotowe"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Wyszukaj kanały TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Konfiguracja tunera TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Konfiguracja tunera TV USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Tuner TV USB odłączony."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Wyszukaj kanały TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Konfiguracja tunera TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Konfiguracja tunera TV USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Konfiguracja sieciowego tunera TV"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Telewizyjny tuner USB rozłączony."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Tuner sieciowy rozłączony."</string>
</resources>
diff --git a/usbtuner-res/values-pt-rPT/strings.xml b/usbtuner-res/values-pt-rPT/strings.xml
index c78c92c1..02f4dd9d 100644
--- a/usbtuner-res/values-pt-rPT/strings.xml
+++ b/usbtuner-res/values-pt-rPT/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Sintonizador de TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Sintonizador de TV USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Ativar"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Desativar"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Sintonizador de televisão (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Aguarde enquanto o processamento é terminado"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Selecione a origem do canal"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Sem sinal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Falha ao sintonizar <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Falha ao sintonizar"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"O software do sintonizador foi atualizado recentemente. Procure novamente os canais."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Ative o som surround nas definições de som do sistema para ativar o áudio"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Não é possível reproduzir áudio. Experimente outra TV."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configuração do sintonizador de canais"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Configuração do sintonizador de TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Configuração do sintonizador de canais USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Configuração do sintonizador de rede"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Confirme se a sua TV está ligada a uma fonte de sinal da TV.\n\nSe estiver a utilizar uma antena via rede sem fios, pode ter de ajustar a respetiva posição ou a direção para receber a maioria dos canais. Para obter os melhores resultados, coloque-a num ponto alto e junto a uma janela."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Confirme se o sintonizador USB está ativado e ligado a uma fonte de sinal da TV.\n\nSe estiver a utilizar uma antena via rede sem fios, pode ter de ajustar a respetiva posição ou a direção para receber a maioria dos canais. Para obter os melhores resultados, coloque-a num ponto alto e junto a uma janela."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Confirme se o sintonizador de rede está ligado à alimentação e ligado a uma fonte de sinal de TV.\n\nSe estiver a utilizar uma antena via rede sem fios, pode ter de ajustar a respetiva posição ou direção para receber a maioria dos canais. Para obter os melhores resultados, coloque-a num ponto alto e junto a uma janela."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continuar"</item>
<item msgid="727245208787621142">"Agora não"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Pretende executar novamente a configuração do canal?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Esta ação remove os canais encontrados pelo sintonizador de TV e procura novamente canais novos.\n\nConfirme se a sua TV está ligada a uma fonte de sinal da TV.\n\nSe estiver a utilizar uma antena via rede sem fios, pode ter de ajustar a respetiva posição ou a direção para receber a maioria dos canais. Para obter os melhores resultados, coloque-a num ponto alto e junto a uma janela."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Esta ação remove os canais encontrados do sintonizador USB e procura novamente canais novos.\n\nConfirme se o sintonizador USB está ativado e ligado a uma fonte de sinal da TV.\n\nSe estiver a utilizar uma antena via rede sem fios, pode ter de ajustar a respetiva posição ou a direção para receber a maioria dos canais. Para obter os melhores resultados, coloque-a num ponto alto e junto a uma janela."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Esta ação vai remover os canais encontrados do sintonizador de rede e procurar novos canais novamente.\n\nConfirme se o sintonizador de rede está ligado à alimentação e ligado a uma fonte de sinal de TV.\n\nSe estiver a utilizar uma antena via rede sem fios, pode ter de ajustar a respetiva posição ou direção para receber a maioria dos canais. Para obter os melhores resultados, coloque-a num ponto alto e junto a uma janela."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continuar"</item>
<item msgid="235450158666155406">"Cancelar"</item>
@@ -54,20 +53,21 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Configuração do sintonizador de TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Configuração do sintonizador de canais USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Configuração do sintonizador de canais"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Esta operação pode demorar vários minutos"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"O sintonizador está temporariamente indisponível ou já está a ser utilizado pela gravação."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d canais encontrados</item>
<item quantity="one">%1$d canal encontrado</item>
+ <item quantity="other">%1$d canais encontrados</item>
</plurals>
<string name="ut_stop_channel_scan" msgid="566811986747774193">"INTERROMPER A PROCURA DE CANAIS"</string>
<plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d canais encontrados</item>
<item quantity="one">%1$d canal encontrado</item>
+ <item quantity="other">%1$d canais encontrados</item>
</plurals>
<plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="one">Boa! Foi encontrado %1$d canal durante a procura de canais. Se isso não lhe parecer correto, experimente ajustar a posição da antena e procurar novamente.</item>
<item quantity="other">Boa! Foram encontrados %1$d canais durante a procura de canais. Se isto não lhe parecer correto, experimente ajustar a posição da antena e procurar novamente.</item>
- <item quantity="one">Boa! Foi encontrado %1$d canal durante a procura de canais. Se isto não lhe parecer correto, experimente ajustar a posição da antena e procurar novamente.</item>
</plurals>
<string-array name="ut_result_found_choices">
<item msgid="3220617441427115421">"Concluído"</item>
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Não foram encontrados canais"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"A procura não encontrou quaisquer canais. Confirme se a TV está ligada a uma fonte de sinal da TV.\n\nSe estiver a utilizar uma antena via rede sem fios, ajuste a respetiva posição ou a direção. Para obter os melhores resultados, coloque-a num ponto alto e junto a uma janela e procure novamente."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Não foram encontrados quaisquer canais. Verifique se o sintonizador USB está ativado e ligado a uma fonte de sinal da TV.\n\nSe estiver a utilizar uma antena via rede sem fios, ajuste a respetiva posição ou a direção. Para obter os melhores resultados, coloque-a num ponto alto e junto a uma janela e procure novamente."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"A procura não encontrou quaisquer canais. Confirme se o sintonizador de rede está ligado à alimentação e ligado a uma fonte de sinal de TV.\n\nSe estiver a utilizar uma antena via rede sem fios, ajuste a respetiva posição ou direção. Para obter os melhores resultados, coloque-a num ponto alto e junto a uma janela. Em seguida, procure novamente."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Procurar novamente"</item>
<item msgid="2092797862490235174">"Concluído"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Procurar canais de TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Configuração do sintonizador de TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Configuração do sintonizador de TV USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Sintonizador de TV USB desligado."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Procurar canais de TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Configuração do sintonizador de TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Configuração do sintonizador de TV USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Configuração do sintonizador de TV por cabo"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Sintonizador de TV USB desligado."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Sintonizador de rede desligado."</string>
</resources>
diff --git a/usbtuner-res/values-pt/strings.xml b/usbtuner-res/values-pt/strings.xml
index 3dfd30c0..d123306a 100644
--- a/usbtuner-res/values-pt/strings.xml
+++ b/usbtuner-res/values-pt/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Sintonizador de TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Sintonizador de TV USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Ativar"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Desativar"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Sintonizador de rede de TV (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Aguarde a conclusão do processamento"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Selecione a fonte do canal"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Sem sinal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Falha ao sintonizar <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Falha ao sintonizar"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"O software do sintonizador foi atualizado recentemente. Procure os canais mais uma vez."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Ative o som surround nas configurações de som do sistema para ativar o áudio"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Não foi possível reproduzir o áudio. Tente em outra TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configuração do sintonizador de canais"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Configuração do Sintonizador de TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Configuração do sintonizador de canais USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Configuração do sintonizador de rede"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Verifique se sua TV está conecta a uma fonte de sinal de TV.\n\nSe você estiver usando uma antena Over-the-air (OTA), talvez seja necessário ajustar o posicionamento ou a direção dela para receber o máximo de canais. Para ter resultados melhores, coloque-a em um lugar alto e perto de uma janela."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Verifique se o sintonizador USB está conectado a uma fonte de sinal de TV.\n\nSe você usa uma antena Over the air, talvez seja necessário ajustar o posicionamento ou a direção dela para receber o maior número de canais. Para ter resultados melhores, coloque-a em um lugar alto e perto de uma janela."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Verifique se o sintonizador de rede está ligado e conectado a uma fonte de sinal de TV.\n\nSe você estiver usando uma antena OTA (over-the-air), talvez seja necessário ajustar o posicionamento ou a direção dela para receber o máximo de canais. Para ter resultados melhores, coloque-a em um lugar alto e perto de uma janela."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continuar"</item>
<item msgid="727245208787621142">"Agora não"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Executar novamente a configuração de canais?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Isso removerá os canais encontrados do Sintonizador de TV e procurará novos canais mais uma vez.\n\nVerifique se sua TV está conectada a uma fonte de sinal de TV.\n\nSe você estiver usando uma antena Over-the-air (OTA), talvez seja necessário ajustar o posicionamento ou a direção dela para receber o máximo de canais. Para ter resultados melhores, coloque-a em um lugar alto e perto de uma janela."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Essa ação remove os canais encontrados pelo sintonizador USB e procura canais novamente.\n\nVerifique se o sintonizador USB está conectado a uma fonte de sinal de TV.\n\n.Se você usa uma antena Over the air, talvez seja necessário ajustar o posicionamento ou a direção dela para receber o maior número de canais. Para ter resultados melhores, coloque-a em um lugar alto e perto de uma janela."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Essa ação removerá os canais encontrados do sintonizador de rede e procurará novos canais mais uma vez.\n\nVerifique se o sintonizador de rede está ligado e conectado a uma fonte de sinal de TV.\n\nSe você estiver usando uma antena OTA (over-the-air), talvez seja necessário ajustar o posicionamento ou a direção dela para receber o máximo de canais. Para ter resultados melhores, coloque-a em um lugar alto e perto de uma janela."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continuar"</item>
<item msgid="235450158666155406">"Cancelar"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Configuração do Sintonizador de TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Configuração do sintonizador de canais USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Configuração do sintonizador de canais de rede"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Isso pode demorar alguns minutos"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"O sintonizador está temporariamente indisponível ou já está sendo usado pela gravação."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Nenhum canal encontrado"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"A procura não encontrou nenhum canal. Verifique se sua TV está conectada a uma fonte de sinal de TV.\n\nSe você estiver usando uma antena Over-the-air (OTA), ajuste o posicionamento ou a direção dela. Para ter resultados melhores, coloque-a em um lugar alto e perto de uma janela e procure novamente."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Nenhum canal foi encontrado pela procura. Verifique se o sintonizador USB está conectado a uma fonte de sinal de TV.\n\nSe você estiver usando uma antena Over the air, ajuste o posicionamento ou a direção dela. Para ter resultados melhores, coloque-a em um lugar alto e perto de uma janela e procure novamente."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Nenhum canal foi encontrado pela procura. Verifique se o sintonizador de rede está ligado e conectado a uma fonte de sinal de TV.\n\nSe você estiver usando uma antena OTA (over-the-air), ajuste o posicionamento ou a direção dela. Para ter resultados melhores, coloque-a em um lugar alto e perto de uma janela, depois procure novamente."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Procurar novamente"</item>
<item msgid="2092797862490235174">"Concluído"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Procurar canais de TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Configuração do Sintonizador de TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Configuração do Sintonizador de TV USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Sintonizador de TV USB desconectado."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Procurar canais de TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Configuração do Sintonizador de TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Configuração do Sintonizador de TV USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Configuração do sintonizador de rede de TV"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Sintonizador de TV USB desconectado."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Sintonizador de rede desconectado."</string>
</resources>
diff --git a/usbtuner-res/values-ro/strings.xml b/usbtuner-res/values-ro/strings.xml
index 57f1ca48..d30101a4 100644
--- a/usbtuner-res/values-ro/strings.xml
+++ b/usbtuner-res/values-ro/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Tuner TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Tuner TV USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Activați"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Dezactivați"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Tuner de rețea TV (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Așteptați ca procesarea să fie finalizată"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Selectați sursa canalului"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Fără semnal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Canalul <xliff:g id="CHANNEL_NAME">%s</xliff:g> nu a putut fi selectat"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Canalul nu a putut fi selectat"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Software-ul tunerului a fost actualizat recent. Scanați din nou canalele."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Pentru a activa conținutul audio, activați sunetul surround din setările de sunet ale sistemului"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Conținutul audio nu poate fi redat. Încercați pe un alt televizor."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Configurarea tunerului de canale"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Configurarea tunerului TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Configurarea tunerului de canale USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Configurarea tunerului de rețea"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Asigurați-vă că televizorul este conectat la o sursă de semnal TV.\n\nDacă folosiți o antenă over the air, poate fi necesar să-i ajustați amplasarea sau direcția astfel încât să capteze majoritatea canalelor. Pentru cele mai bune rezultate, amplasați-o la înălțime și în apropierea unei ferestre."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Asigurați-vă că tunerul USB este conectat la o sursă de alimentare și la o sursă de semnal TV.\n\nDacă folosiți o antenă over the air, poate fi necesar să-i ajustați amplasarea sau direcția astfel încât să capteze majoritatea canalelor. Pentru cele mai bune rezultate, amplasați-o la înălțime și în apropierea unei ferestre."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Verificați dacă tunerul de rețea este pornit și conectat la o sursă de semnal TV.\n\nDacă folosiți o antenă over-the-air, ar putea fi necesar să-i ajustați poziția sau direcția pentru a recepționa cât mai multe canale. Pentru rezultate optime, plasați-o sus și lângă o fereastră."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Continuați"</item>
<item msgid="727245208787621142">"Nu acum"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Configurați din nou canalul?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Astfel, vor fi eliminate canalele găsite de tunerul TV și se vor căuta din nou canale.\n\nAsigurați-vă că televizorul este conectat la o sursă de semnal TV.\n\nDacă folosiți o antenă over the air, poate fi necesar să-i ajustați amplasarea sau direcția astfel încât să capteze majoritatea canalelor. Pentru cele mai bune rezultate, amplasați-o la înălțime și în apropierea unei ferestre."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Astfel, vor fi eliminate canalele găsite de pe tunerul USB și se vor căuta din nou canale.\n\nAsigurați-vă că tunerul USB este conectat la o sursă de alimentare și la o sursă de semnal TV.\n\nDacă folosiți o antenă over the air, poate fi necesar să-i ajustați amplasarea sau direcția pentru a capta majoritatea canalelor. Pentru cele mai bune rezultate, amplasați-o la înălțime și în apropierea unei ferestre."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Astfel veți elimina canalele găsite din tunerul de rețea și veți scana iar pentru a găsi canale noi.\n\nVerificați dacă tunerul de rețea este pornit și conectat la o sursă de semnal TV.\n\nDacă folosiți o antenă over-the-air, ar putea fi necesar să-i ajustați poziția sau direcția pentru a recepționa cât mai multe canale. Pentru rezultate optime, plasați-o sus și lângă o fereastră."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Continuați"</item>
<item msgid="235450158666155406">"Anulați"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Configurarea tunerului TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Configurarea tunerului de canale USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Configurarea tunerului de canale de rețea"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Poate dura câteva minute"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tunerul nu este disponibil temporar sau este folosit deja de înregistrare."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -79,12 +79,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Nu s-au găsit canale"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Scanarea nu a găsit niciun canal. Asigurați-vă că televizorul este conectat la o sursă de semnal TV.\n\nDacă folosiți o antenă over the air, ajustați-i amplasarea sau direcția. Pentru cele mai bune rezultate, amplasați-o la înălțime și în apropierea unei ferestre, apoi repetați scanarea."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Nu s-a găsit niciun canal la scanare. Asigurați-vă că tunerul USB este conectat la o sursă de alimentare și la o sursă de semnal TV. \n\nDacă folosiți o antenă over the air, ajustați-i amplasarea sau direcția. Pentru cele mai bune rezultate, amplasați-o la înălțime și în apropierea unei ferestre, apoi repetați scanarea."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Scanarea nu a găsit niciun canal. Verificați dacă tunerul de rețea este pornit și conectat la o sursă de semnal TV.\n\nDacă folosiți o antenă over-the-air, ajustați poziția sau direcția. Pentru rezultate optime, plasați-o sus și lângă o fereastră și scanați din nou."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Scanați din nou"</item>
<item msgid="2092797862490235174">"Terminat"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Căutați canale TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Configurarea tunerului TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Configurarea tunerului TV USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Tunerul TV USB a fost deconectat."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Căutați canale TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Configurarea tunerului TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Configurarea tunerului TV USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Configurarea tunerului de rețea TV"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Tunerul TV USB este deconectat."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Tunerul de rețea este deconectat."</string>
</resources>
diff --git a/usbtuner-res/values-ru/strings.xml b/usbtuner-res/values-ru/strings.xml
index 7509ff19..33f97db0 100644
--- a/usbtuner-res/values-ru/strings.xml
+++ b/usbtuner-res/values-ru/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"ТВ-тюнер"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB-тюнер"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Вкл."</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Выкл."</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Сетевой ТВ-тюнер (бета)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Дождитесь окончания обработки"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Выберите источник каналов"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Нет сигнала"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Не удалось настроиться на канал \"<xliff:g id="CHANNEL_NAME">%s</xliff:g>\""</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Не удалось настроиться на канал"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Программное обеспечение тюнера было обновлено. Повторите сканирование."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Включите объемный звук в системных настройках"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Не удается воспроизвести аудио. Выберите другой канал."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Настройка тюнера"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Настройка ТВ-тюнера"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Настройка USB-тюнера"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Настройка сетевого тюнера"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Убедитесь, что телевизор подключен к источнику сигнала.\n\nЕсли вы используете телеантенну, переместите или перенаправьте ее. Рекомендуем расположить ее высоко и рядом с окном."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Убедитесь, что USB-тюнер включен в сеть и подсоединен к источнику сигнала.\n\nЕсли вы используете телеантенну, переместите или перенаправьте ее. Рекомендуем расположить ее высоко и рядом с окном."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Убедитесь, что сетевой тюнер включен в сеть и подсоединен к источнику ТВ-сигнала.\n\nЕсли вы используете телеантенну, поместите и направьте ее так, чтобы она принимала большинство каналов. Рекомендуем расположить антенну высоко и рядом с окном."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Продолжить"</item>
<item msgid="727245208787621142">"Не сейчас"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Настроить каналы заново?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Все каналы, найденные с помощью ТВ-тюнера, будут удалены, и поиск начнется заново.\n\nУбедитесь, что телевизор подключен к источнику сигнала.\n\nЕсли вы используете телеантенну, переместите или перенаправьте ее. Рекомендуем расположить ее высоко и рядом с окном."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Все каналы, найденные с помощью USB-тюнера, будут удалены, и сканирование начнется заново.\n\nУбедитесь, что USB-тюнер включен в сеть и подсоединен к источнику сигнала.\n\nЕсли вы используете телеантенну, переместите или перенаправьте ее. Рекомендуем расположить ее высоко и рядом с окном."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Все каналы, найденные с помощью сетевого тюнера, будут удалены, и сканирование начнется заново.\n\nУбедитесь, что сетевой тюнер включен в сеть и подсоединен к источнику ТВ-сигнала.\n\nЕсли вы используете телеантенну, поместите и направьте ее так, чтобы она принимала большинство каналов. Рекомендуем расположить антенну высоко и рядом с окном."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Продолжить"</item>
<item msgid="235450158666155406">"Отмена"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Настройка ТВ-тюнера"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Настройка USB-тюнера"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Настройка каналов сетевого тюнера"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Это может занять несколько минут"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Тюнер временно недоступен или уже используется для записи."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -78,12 +78,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Каналы не найдены"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Каналы не найдены. Убедитесь, что телевизор подключен к источнику сигнала.\n\nЕсли вы используете телеантенну, переместите или перенаправьте ее. Рекомендуем расположить ее высоко и рядом с окном."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Каналы не найдены. Убедитесь, что USB-тюнер включен в сеть и подсоединен к источнику сигнала.\n\nЕсли вы используете телеантенну, переместите или перенаправьте ее. Рекомендуем расположить ее высоко и рядом с окном."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Каналы не найдены. Убедитесь, что сетевой тюнер включен в сеть и подсоединен к источнику ТВ-сигнала.\n\nЕсли вы используете телеантенну, переместите или перенаправьте ее (рекомендуем расположить антенну высоко и рядом с окном). Затем повторите сканирование."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Искать повторно"</item>
<item msgid="2092797862490235174">"Готово"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Сканирование телеканалов"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Настройка ТВ-тюнера"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Настройка USB-тюнера"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB-тюнер отключен."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Сканируйте телеканалы"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Настройка ТВ-тюнера"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Настройка USB-тюнера"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Настройка сетевого ТВ-тюнера"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-тюнер отключен."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Сетевой тюнер отключен."</string>
</resources>
diff --git a/usbtuner-res/values-si-rLK/strings.xml b/usbtuner-res/values-si-rLK/strings.xml
new file mode 100644
index 00000000..577015b6
--- /dev/null
+++ b/usbtuner-res/values-si-rLK/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"TV සුසරකය"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB TV සුසරකය"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Network TV Tuner (BETA)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"සැකසීම අවසන් කිරීමට කරුණාකර රැඳී සිටින්න"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"සුසරක මෘදුකාංගය පසුගියදා යාවත්කාලීන කර ඇත. කරුණාකර නාලිකා නැවත ස්කෑන් කරන්න."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ශ්‍රව්‍ය සබල කිරීමට හඬ සැකසීම් තුළ අවට හඬ සබල කරන්න"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"ශ්‍රව්‍යය ධාවනය කළ නොහැකිය. කරුණාකර වෙනත් TV එකක් උත්සාහ කරන්න"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"නාලිකා සුසරක පිහිටුවීම"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"TV සුසරක පිහිටුවීම"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB නාලිකා සුසරක පිහිටුවීම"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"ජාල සුසරකය පිහිටුවීම"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"ඔබේ TV, TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, ඔබට බොහොමයක් නාලිකා ලබා ගැනීමට පිහිටීම හෝ දිශාව සීරුමාරු කිරීමට අවශ්‍ය විය හැකිය. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබන්න."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"සුසරකය පේනුගත කර ඇති බව සහ TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, ඔබට බොහොමයක් නාලිකා ලබා ගැනීමට පිහිටීම හෝ දිශාව සීරුමාරු කිරීමට අවශ්‍ය විය හැකිය. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබන්න."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"ජාල සුසරකය බලයට සම්බන්ධ කර ඇති බව සහ TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, ඔබට බොහොමයක් නාලිකා ලබා ගැනීමට පිහිටීම හෝ දිශාව සීරුමාරු කිරීමට අවශ්‍ය විය හැකිය. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබන්න."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"දිගටම කර ගෙන යන්න"</item>
+ <item msgid="727245208787621142">"දැන් නොවේ"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"නාලිකා පිහිටුවීම නැවත ධාවනය කරන්නද?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"මෙය TV සුසරකය වෙතින් සොයා ගත් නාලිකා ඉවත් කරනු ඇති අතර නව නාලිකා සඳහා නැවත ස්කෑන් කරනු ඇත.\n\nඔබේ TV, TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, ඔබට බොහොමයක් නාලිකා ලබා ගැනීමට පිහිටීම හෝ දිශාව සීරුමාරු කිරීමට අවශ්‍ය විය හැකිය. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබන්න."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"මෙය USB සුසරකය වෙතින් සොයා ගත් නාලිකා ඉවත් කරනු ඇති අතර නව නාලිකා සඳහා නැවත ස්කෑන් කරනු ඇත.\n\nUSB සුසරකය පේනුගත කර ඇති බව සහ TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, ඔබට බොහොමයක් නාලිකා ලබා ගැනීමට පිහිටීම හෝ දිශාව සීරුමාරු කිරීමට අවශ්‍ය විය හැකිය. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබන්න."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"මෙය ජාල සුසරකය වෙතින් සොයා ගත් නාලිකා ඉවත් කරනු ඇති අතර නව නාලිකා සඳහා නැවත ස්කෑන් කරනු ඇත.\n\nජාල සුසරකය බලයට සම්බන්ධ කර ඇති බව සහ TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, ඔබට බොහොමයක් නාලිකා ලබා ගැනීමට පිහිටීම හෝ දිශාව සීරුමාරු කිරීමට අවශ්‍ය විය හැකිය. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබන්න."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"දිගටම කර ගෙන යන්න"</item>
+ <item msgid="235450158666155406">"අවලංගු කරන්න"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"සබැඳුම් ආකාරය තෝරන්න"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"සුසරකයට බාහිර අැන්ටනාවක් සම්බන්ධ කර ඇත්නම්, ඇන්ටනාව තෝරන්න. ඔබේ නාලිකා කේබල් සැපයුම්කරුවෙකු වෙතින් පැමිණෙන්නේ නම් කේබලය තෝරන්න. ඔබට ස්ථිර නැත්නම්, ආකාර දෙකම ස්කෑන් කරනු ඇත, නමුත් මෙයට වැඩි කාලයක් ගත විය හැකිය."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"ඇන්ටනාව"</item>
+ <item msgid="2670079958754180142">"කේබලය"</item>
+ <item msgid="36774059871728525">"ස්ථිර නැත"</item>
+ <item msgid="6881204453182153978">"සංවර්ධනයට පමණි"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"TV සුසරක පිහිටුවීම"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB නාලිකා සුසරක පිහිටුවීම"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"ජාල නාලිකා සුසරකය පිහිටුවීම"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"මෙය මිනිත්තු කිහිපයක් ගත හැකිය"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"සුසරකය තාවකාලිකව ලබා ගත නොහැකිය නැතහොත් දැනටමත් පටිගත කිරීම මගින් භාවිත කරනු ලැබේ."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="one">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
+ <item quantity="other">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"නාලිකා ස්කෑන් කිරීම නවත්වන්න"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="one">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
+ <item quantity="other">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="one">කදිමයි! නාලිකා ස්කෑන් කිරීම අතරතුර නාලිකා %1$dක් සොයා ගන්නා ලදී. මෙය නිවැරදි බව නොපෙනේ නම්, ඇන්ටනාවේ පිහිටීම සීරුමාරු කිරීම උත්සාහ කර නැවත ස්කෑන් කරන්න.</item>
+ <item quantity="other">කදිමයි! නාලිකා ස්කෑන් කිරීම අතරතුර නාලිකා %1$dක් සොයා ගන්නා ලදී. මෙය නිවැරදි බව නොපෙනේ නම්, ඇන්ටනාවේ පිහිටීම සීරුමාරු කිරීම උත්සාහ කර නැවත ස්කෑන් කරන්න.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"නිමයි"</item>
+ <item msgid="2480490326672924828">"නැවත ස්කෑන් කරන්න"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"නාලිකා හමු නොවීය"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"ස්කෑන් කිරීමට නාලිකා කිසිවක් හමු නොවීය. ඔබේ TV, TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, එහි පිහිටීම හෝ දිශාව සීරුමාරු කරන්න. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබා නැවත ස්කෑන් කරන්න."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"ස්කෑන් කිරීමට නාලිකා කිසිවක් හමු නොවීය. USB සුසරකය පේනුගත කර ඇති බව සහ TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, පිහිටීම හෝ දිශාව සීරුමාරු කරන්න. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබා නැවත ස්කෑන් කරන්න."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"ස්කෑන් කිරීමට නාලිකා කිසිවක් හමු නොවීය. ජාල සුසරකය බලයට සම්බන්ධ කර ඇති බව සහ TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, පිහිටීම හෝ දිශාව සීරුමාරු කරන්න. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබා නැවත ස්කෑන් කරන්න."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"නැවත ස්කෑන් කරන්න"</item>
+ <item msgid="2092797862490235174">"නිමයි"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"TV නාලිකා සඳහා ස්කෑන් කරන්න"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV සුසරක පිහිටුවීම"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV සුසරක පිහිටුවීම"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"ජාල TV සුසරක පිහිටුවීම"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV සුසරකය විසන්ධි වුණි."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"ජාල සුසරකය විසන්ධි වුණි."</string>
+</resources>
diff --git a/usbtuner-res/values-si/strings.xml b/usbtuner-res/values-si/strings.xml
deleted file mode 100644
index a792b2c0..00000000
--- a/usbtuner-res/values-si/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"TV සුසරකය"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB TV සුසරකය"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"ක්‍රියාත්මක කරන්න"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"ක්‍රියාවිරහිත කරන්න"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"සැකසීම අවසන් කිරීමට කරුණාකර රැඳී සිටින්න"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"ඔබගේ නාලිකා මූලාශ්‍රය තෝරන්න"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"සංඥාවක් නැත"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> වෙත සුසර කිරීම අසාර්ථක විය"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"සුසර කිරීම අසාර්ථක විය"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"සුසරක මෘදුකාංගය පසුගියදා යාවත්කාලීන කර ඇත. කරුණාකර නාලිකා නැවත ස්කෑන් කරන්න."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ශ්‍රව්‍ය සබල කිරීමට හඬ සැකසීම් තුළ අවට හඬ සබල කරන්න"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"නාලිකා සුසරක පිහිටුවීම"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"TV සුසරක පිහිටුවීම"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB නාලිකා සුසරක පිහිටුවීම"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"ඔබේ TV, TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, ඔබට බොහොමයක් නාලිකා ලබා ගැනීමට පිහිටීම හෝ දිශාව සීරුමාරු කිරීමට අවශ්‍ය විය හැකිය. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබන්න."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"සුසරකය පේනුගත කර ඇති බව සහ TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, ඔබට බොහොමයක් නාලිකා ලබා ගැනීමට පිහිටීම හෝ දිශාව සීරුමාරු කිරීමට අවශ්‍ය විය හැකිය. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබන්න."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"දිගටම කර ගෙන යන්න"</item>
- <item msgid="727245208787621142">"දැන් නොවේ"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"නාලිකා පිහිටුවීම නැවත ධාවනය කරන්නද?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"මෙය TV සුසරකය වෙතින් සොයා ගත් නාලිකා ඉවත් කරනු ඇති අතර නව නාලිකා සඳහා නැවත ස්කෑන් කරනු ඇත.\n\nඔබේ TV, TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, ඔබට බොහොමයක් නාලිකා ලබා ගැනීමට පිහිටීම හෝ දිශාව සීරුමාරු කිරීමට අවශ්‍ය විය හැකිය. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබන්න."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"මෙය USB සුසරකය වෙතින් සොයා ගත් නාලිකා ඉවත් කරනු ඇති අතර නව නාලිකා සඳහා නැවත ස්කෑන් කරනු ඇත.\n\nUSB සුසරකය පේනුගත කර ඇති බව සහ TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, ඔබට බොහොමයක් නාලිකා ලබා ගැනීමට පිහිටීම හෝ දිශාව සීරුමාරු කිරීමට අවශ්‍ය විය හැකිය. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබන්න."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"දිගටම කර ගෙන යන්න"</item>
- <item msgid="235450158666155406">"අවලංගු කරන්න"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"සබැඳුම් ආකාරය තෝරන්න"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"සුසරකයට බාහිර අැන්ටනාවක් සම්බන්ධ කර ඇත්නම්, ඇන්ටනාව තෝරන්න. ඔබේ නාලිකා කේබල් සැපයුම්කරුවෙකු වෙතින් පැමිණෙන්නේ නම් කේබලය තෝරන්න. ඔබට ස්ථිර නැත්නම්, ආකාර දෙකම ස්කෑන් කරනු ඇත, නමුත් මෙයට වැඩි කාලයක් ගත විය හැකිය."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"ඇන්ටනාව"</item>
- <item msgid="2670079958754180142">"කේබලය"</item>
- <item msgid="36774059871728525">"ස්ථිර නැත"</item>
- <item msgid="6881204453182153978">"සංවර්ධනයට පමණි"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"TV සුසරක පිහිටුවීම"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB නාලිකා සුසරක පිහිටුවීම"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"මෙය මිනිත්තු කිහිපයක් ගත හැකිය"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"සුසරකය තාවකාලිකව ලබා ගත නොහැකිය නැතහොත් දැනටමත් පටිගත කිරීම මගින් භාවිත කරනු ලැබේ."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="one">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
- <item quantity="other">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"නාලිකා ස්කෑන් කිරීම නවත්වන්න"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="one">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
- <item quantity="other">නාලිකා %1$dක් සොයා ගන්නා ලදී</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="one">කදිමයි! නාලිකා ස්කෑන් කිරීම අතරතුර නාලිකා %1$dක් සොයා ගන්නා ලදී. මෙය නිවැරදි බව නොපෙනේ නම්, ඇන්ටනාවේ පිහිටීම සීරුමාරු කිරීම උත්සාහ කර නැවත ස්කෑන් කරන්න.</item>
- <item quantity="other">කදිමයි! නාලිකා ස්කෑන් කිරීම අතරතුර නාලිකා %1$dක් සොයා ගන්නා ලදී. මෙය නිවැරදි බව නොපෙනේ නම්, ඇන්ටනාවේ පිහිටීම සීරුමාරු කිරීම උත්සාහ කර නැවත ස්කෑන් කරන්න.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"නිමයි"</item>
- <item msgid="2480490326672924828">"නැවත ස්කෑන් කරන්න"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"නාලිකා හමු නොවීය"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"ස්කෑන් කිරීමට නාලිකා කිසිවක් හමු නොවීය. ඔබේ TV, TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, එහි පිහිටීම හෝ දිශාව සීරුමාරු කරන්න. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබා නැවත ස්කෑන් කරන්න."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"ස්කෑන් කිරීමට නාලිකා කිසිවක් හමු නොවීය. USB සුසරකය පේනුගත කර ඇති බව සහ TV සංඥා මූලාශ්‍රයකට සම්බන්ධ කර ඇති බව තහවුරු කර ගන්න.\n\nගුවන-ඔස්සේ ඇන්ටනාවක් භාවිත කරන්නේ නම්, පිහිටීම හෝ දිශාව සීරුමාරු කරන්න. හොඳම ප්‍රතිඵල සඳහා, එය ඉහළින් සහ කවුළුවක් ආසන්නයේ තබා නැවත ස්කෑන් කරන්න."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"නැවත ස්කෑන් කරන්න"</item>
- <item msgid="2092797862490235174">"නිමයි"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"TV නාලිකා සඳහා ස්කෑන් කරන්න"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV සුසරක පිහිටුවීම"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV සුසරක පිහිටුවීම"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV සුසරකය විසන්ධි කරන ලදී."</string>
-</resources>
diff --git a/usbtuner-res/values-sk/strings.xml b/usbtuner-res/values-sk/strings.xml
index 67f9829e..60448b2b 100644
--- a/usbtuner-res/values-sk/strings.xml
+++ b/usbtuner-res/values-sk/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Televízny tuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Televízny tuner s rozhraním USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Zapnúť"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Vypnúť"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Televízny sieťový tuner (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Počkajte, kým bude spracovanie dokončené"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Vyberte zdroj kanála"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Žiadny signál"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Nepodarilo sa naladiť kanál <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Ladenie zlyhalo"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Softvér tunera bol nedávno aktualizovaný. Znova vyhľadajte kanály."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Ak chcete zapnúť zvuk, v nastaveniach systémového zvuku povoľte priestorový zvuk"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Zvuk nie je možné prehrať. Skúste použiť iný televízor."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Nastavenie tunera kanálov"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Nastavenie televízneho tunera"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Nastavenie kanálov tunera USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Nastavenie sieťového tunera"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Skontrolujte, či je televízor pripojený k zdroju televízneho signálu.\n\nAk používate vzdušnú anténu, upravte jej umiestnenie alebo orientáciu, aby ste získali čo najviac kanálov. Najlepšie výsledky dosiahnete umiestnením antény dostatočne vysoko a do blízkosti okna."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Skontrolujte, či je tuner USB zapojený a pripojený k zdroju televízneho signálu.\n\nAk používate vzdušnú anténu, upravte jej umiestnenie alebo orientáciu, aby ste získali čo najviac kanálov. Najlepšie výsledky dosiahnete umiestnením antény dostatočne vysoko a do blízkosti okna."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Skontrolujte, či je sieťový tuner zapnutý a pripojený k zdroju televízneho signálu.\n\nAk používate bezdrôtovú anténu, upravte jej umiestnenie alebo orientáciu tak, aby ste získali čo najviac kanálov. Najlepšie výsledky dosiahnete umiestnením antény dostatočne vysoko a do blízkosti okna."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Pokračovať"</item>
<item msgid="727245208787621142">"Teraz nie"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Znova spustiť nastavenie kanálov?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Táto akcia odstráni nájdené kanály z televízneho tunera a opätovne spustí vyhľadávanie nových kanálov.\n\nSkontrolujte, či je televízor pripojený k zdroju televízneho signálu.\n\nAk používate vzdušnú anténu, upravte jej umiestnenie alebo orientáciu, aby ste získali čo najviac kanálov. Najlepšie výsledky dosiahnete umiestnením antény dostatočne vysoko a do blízkosti okna."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Táto akcia odstráni nájdené kanály z tunera USB a opätovne spustí vyhľadávanie nových kanálov.\n\nSkontrolujte, či je tuner USB zapojený a pripojený k zdroju televízneho signálu.\n\nAk používate vzdušnú anténu, upravte jej umiestnenie alebo orientáciu, aby ste získali čo najviac kanálov. Najlepšie výsledky dosiahnete umiestnením antény dostatočne vysoko a do blízkosti okna."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Táto akcia odstráni nájdené kanály zo sieťového tunera a opätovne spustí vyhľadávanie nových kanálov.\n\nSkontrolujte, či je sieťový tuner zapnutý a pripojený k zdroju televízneho signálu.\n\nAk používate bezdrôtovú anténu, upravte jej umiestnenie alebo orientáciu tak, aby ste získali čo najviac kanálov. Najlepšie výsledky dosiahnete umiestnením antény dostatočne vysoko a do blízkosti okna."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Pokračovať"</item>
<item msgid="235450158666155406">"Zrušiť"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Nastavenie televízneho tunera"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Nastavenie kanálov tunera USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Nastavenie kanálov sieťového tunera"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Môže to trvať niekoľko minút"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tuner nie je dočasne kˆ dispozícii alebo sa práve používa na nahrávanie."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -82,12 +82,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Nenašli sa žiadne kanály"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Nenašli sa žiadne kanály. Skontrolujte, či je televízor pripojený k zdroju televízneho signálu.\n\nAk používate vzdušnú anténu, upravte jej umiestnenie alebo orientáciu. Najlepšie výsledky dosiahnete umiestnením antény dostatočne vysoko a do blízkosti okna. Potom znova spustite hľadanie."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Nenašli sa žiadne kanály. Skontrolujte, či je tuner USB zapojený a pripojený k zdroju televízneho signálu.\n\nAk používate vzdušnú anténu, upravte jej umiestnenie alebo orientáciu. Najlepšie výsledky dosiahnete umiestnením antény dostatočne vysoko a do blízkosti okna. Potom znova spustite hľadanie."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Nenašli sa žiadne kanály. Skontrolujte, či je sieťový tuner zapnutý a pripojený k zdroju televízneho signálu.\n\nAk používate bezdrôtovú anténu, upravte jej umiestnenie alebo orientáciu. Najlepšie výsledky dosiahnete umiestnením antény dostatočne vysoko a do blízkosti okna. Potom znova spustite hľadanie."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Hľadať znova"</item>
<item msgid="2092797862490235174">"Hotovo"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Vyhľadajte televízne kanály"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Nastavenie televízneho tunera"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Nastavenie televízneho tunera s rozhraním USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"TV tuner s rozhraním USB je odpojený."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Vyhľadajte televízne kanály"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Nastavenie televízneho tunera"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Nastavenie televízneho tunera s rozhraním USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Nastavenie televízneho sieťového tunera"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"TV tuner s rozhraním USB bol odpojený."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Sieťový tuner bol odpojený."</string>
</resources>
diff --git a/usbtuner-res/values-sl/strings.xml b/usbtuner-res/values-sl/strings.xml
index e454e971..2f0812bb 100644
--- a/usbtuner-res/values-sl/strings.xml
+++ b/usbtuner-res/values-sl/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Sprejemnik TV-kanalov"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Sprejemnik TV-kanalov USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Vklop"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Izklop"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Omrežni sprejemnik TV-kanalov (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Počakajte, da se dokonča obdelava"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Izberite vir kanalov"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Ni signala"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Iskanje kanala <xliff:g id="CHANNEL_NAME">%s</xliff:g> ni uspelo"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Iskanje kanala ni uspelo"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Programska oprema sprejemnika je bila nedavno posodobljena. Znova poiščite kanale."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"V sistemskih nastavitvah zvoka omogočite prostorski zvok, če želite omogočiti zvok"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Zvoka ni mogoče predvajati. Poskusite na drugem televizorju."</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Nastavitev sprejemnika kanalov"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Nastavitev sprejemnika TV-kanalov"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Nastavitev sprejemnika kanalov USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Nastavitev omrežnega sprejemnika"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Preverite, ali je televizor povezan z virom TV-signala.\n\nČe uporabljate anteno za prizemno televizijo, prilagodite njen položaj oziroma njeno usmerjenost. Če želite najboljši rezultat, jo postavite na visok položaj in blizu okna ter iščite kanale znova."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Preverite, ali je sprejemnik USB priključen in povezan z virom TV-signala.\n\nČe uporabljate anteno za prizemno televizijo, morate morda prilagoditi njen položaj oziroma njeno usmerjenost, če želite prejemati največ kanalov. Če želite najboljši rezultat, jo postavite na visok položaj in blizu okna."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Preverite, ali je omrežni sprejemnik vklopljen in povezan z virom TV-signala.\n\nČe uporabljate anteno za prizemno televizijo, prilagodite njen položaj oziroma njeno usmerjenost. Če želite najboljši rezultat, jo postavite na visok položaj in blizu okna."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Naprej"</item>
<item msgid="727245208787621142">"Ne zdaj"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Ali želite znova zagnati namestitev kanalov?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"S tem bodo odstranjeni kanali, najdeni prek sprejemnika TV-kanalov, in iskanje kanalov se bo začelo znova.\n\nPreverite, ali je televizor povezan z virom TV-signala.\n\nČe uporabljate anteno za prizemno televizijo, prilagodite njen položaj oziroma njeno usmerjenost. Če želite najboljši rezultat, jo postavite na visok položaj in blizu okna ter iščite kanale znova."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"S tem bodo odstranjeni kanali, najdeni prek sprejemnika USB, in iskanje kanalov se bo začelo znova.\n\nPreverite, ali je sprejemnik USB priključen in povezan z virom TV-signala.\n\nČe uporabljate anteno za prizemno televizijo, morate morda prilagoditi njen položaj oziroma njeno usmerjenost, če želite prejemati največ kanalov. Če želite najboljši rezultat, jo postavite na visok položaj in blizu okna."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"S tem bodo odstranjeni kanali, najdeni z omrežnim sprejemnikom kanalov, in vnovič se bo začelo iskanje novih kanalov.\n\nPreverite, ali je omrežni sprejemnik vklopljen in povezan z virom TV-signala.\n\nČe uporabljate anteno za prizemno televizijo, prilagodite njen položaj oziroma njeno usmerjenost. Če želite najboljši rezultat, jo postavite na visok položaj in blizu okna."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Naprej"</item>
<item msgid="235450158666155406">"Prekliči"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Nastavitev sprejemnika TV-kanalov"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Nastavitev sprejemnika kanalov USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Nastavitev omrežnega sprejemnika kanalov"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"To lahko traja nekaj minut"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Sprejemnik začasno ni na voljo ali se že uporablja za snemanje."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -82,12 +82,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Ni najdenih kanalov"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Pri iskanju kanali niso bili najdeni. Preverite, ali je televizor povezan z virom TV-signala.\n\nČe uporabljate anteno za prizemno televizijo, prilagodite njen položaj oziroma njeno usmerjenost. Če želite najboljši rezultat, jo postavite na visok položaj in blizu okna ter iščite kanale znova."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Pri iskanju kanali niso bili najdeni. Preverite, ali je sprejemnik USB priključen in povezan z virom TV-signala.\n\nČe uporabljate anteno za prizemno televizijo, prilagodite njen položaj oziroma njeno usmerjenost. Če želite najboljši rezultat, jo postavite na visok položaj in blizu okna ter iščite kanale znova."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Pri iskanju ni bil najden noben kanal. Preverite, ali je omrežni sprejemnik vklopljen in povezan z virom TV-signala.\n\nČe uporabljate anteno za prizemno televizijo, prilagodite njen položaj oziroma njeno usmerjenost. Če želite najboljši rezultat, jo postavite na visok položaj in blizu okna ter iščite kanale znova."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Znova išči"</item>
<item msgid="2092797862490235174">"Končano"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Iskanje TV-kanalov"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Nastavitev sprejemnika TV-kanalov"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Nastavitev sprejemnika TV-kanalov USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Povezava s sprejemnikom za TV-kanale USB je prekinjena."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Iskanje TV-kanalov"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Nastavitev sprejemnika TV-kanalov"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Nastavitev sprejemnika TV-kanalov USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Nastavitev omrežnega sprejemnika TV-kanalov"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Povezava s sprejemnikom za TV-kanale USB je prekinjena."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Povezava z omrežnim sprejemnikom je prekinjena."</string>
</resources>
diff --git a/usbtuner-res/values-sr/strings.xml b/usbtuner-res/values-sr/strings.xml
index 6c1fa1bf..ce7c4d53 100644
--- a/usbtuner-res/values-sr/strings.xml
+++ b/usbtuner-res/values-sr/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Тјунер за ТВ"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB тјунер за ТВ"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Укључи"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Искључи"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Мрежни тјунер за ТВ (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Сачекајте да се заврши обрада"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Изаберите извор канала"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Нема сигнала"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Укључивање канала <xliff:g id="CHANNEL_NAME">%s</xliff:g> није успело"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Укључивање канала није успело"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Софтвер тјунера је недавно ажуриран. Претражите канале поново."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Омогући звучни систем у подешавањима звука да бисте омогућили аудио"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Звук не може да се пусти. Испробајте други ТВ уређај"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Подешавање тјунера за канале"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Подешавање тјунера за ТВ"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Подешавање USB тјунера за канале"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Подешавање мрежног тјунера"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Проверите да ли је ТВ повезан са извором ТВ сигнала.\n\nАко користите антену за сигнал преко мреже, можда треба да прилагодите њен положај или смер да бисте имали највише канала. Ако желите најбоље резултате, поставите је високо и близу прозора."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Проверите да ли је USB тјунер прикључен и повезан са извором ТВ сигнала.\n\nАко користите антену за сигнал преко мреже, можда треба да прилагодите њен положај или смер да бисте имали највише канала. Ако желите најбоље резултате, поставите је високо и близу прозора."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Проверите да ли је мрежни тјунер укључен и повезан са извором ТВ сигнала.\n\nАко користите антену за сигнал преко мреже, можда треба да прилагодите њен положај или смер да бисте имали највише канала. Ако желите најбоље резултате, поставите је високо и близу прозора."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Настави"</item>
<item msgid="727245208787621142">"Не сада"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Желите ли да поново покренете подешавање канала?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"На овај начин уклањате канале пронађене помоћу тјунера за ТВ и поново тражите нове канале.\n\nПроверите да ли је ТВ повезан са извором ТВ сигнала.\n\nАко користите антену за сигнал преко мреже, можда треба да прилагодите њен положај или смер да бисте имали највише канала. Ако желите најбоље резултате, поставите је високо и близу прозора."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"На овај начин уклањате канале пронађене помоћу USB тјунера и поново тражите нове канале.\n\nПроверите да ли је USB тјунер прикључен и повезан са извором ТВ сигнала.\n\nАко користите антену за сигнал преко мреже, можда треба да прилагодите њен положај или смер да бисте имали највише канала. Ако желите најбоље резултате, поставите је високо и близу прозора."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"На овај начин уклањате канале пронађене помоћу мрежног тјунера и поново скенирате нове канале.\n\nПроверите да ли је мрежни тјунер укључен и повезан са извором ТВ сигнала.\n\nАко користите антену за сигнал преко мреже, можда треба да прилагодите њен положај или смер да бисте имали највише канала. Ако желите најбоље резултате, поставите је високо и близу прозора."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Настави"</item>
<item msgid="235450158666155406">"Откажи"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Подешавање тјунера за ТВ"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Подешавање USB тјунера за канале"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Подешавање мрежног тјунера за канале"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Ово може да потраје неколико минута"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Тјунер привремено није доступан или се већ користи за снимање."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -79,12 +79,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Није пронађен ниједан канал"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Претрагом није пронађен ниједан канал. Проверите да ли је ТВ повезан са извором ТВ сигнала.\n\nАко користите антену за сигнал преко мреже, прилагодите њен положај или смер. Ако желите најбоље резултате, поставите је високо и близу прозора, па поново обавите претрагу."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Претрагом није пронађен ниједан канал. Проверите да ли је USB тјунер прикључен и повезан са извором ТВ сигнала.\n\nАко користите антену за сигнал преко мреже, прилагодите њен положај или смер. Ако желите најбоље резултате, поставите је високо и близу прозора, па поново обавите претрагу."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Скенирањем није пронађен ниједан канал. Проверите да ли је мрежни тјунер укључен и повезан са извором ТВ сигнала.\n\nАко користите антену за сигнал преко мреже, прилагодите њен положај или смер. Ако желите најбоље резултате, поставите је високо и близу прозора, па поново обавите скенирање."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Претражи поново"</item>
<item msgid="2092797862490235174">"Готово"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Потражите ТВ канале"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Подешавање тјунера за ТВ"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Подешавање USB тјунера за ТВ"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB тјунер за ТВ није прикључен."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Потражите ТВ канале"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Подешавање тјунера за ТВ"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Подешавање USB тјунера за ТВ"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Подешавање мрежног тјунера за ТВ"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB тјунер за ТВ није прикључен."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Мрежни тјунер није прикључен."</string>
</resources>
diff --git a/usbtuner-res/values-sv/strings.xml b/usbtuner-res/values-sv/strings.xml
index dea421bb..81c37921 100644
--- a/usbtuner-res/values-sv/strings.xml
+++ b/usbtuner-res/values-sv/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV-mottagare"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB-TV-mottagare"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"På"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Av"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Mottagare för TV över nätverket (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Vänta tills sökningen är klar"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Välj kanalkälla"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Ingen signal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Det gick inte att ställa in <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Det gick inte att ställa in kanalen"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Programvaran för mottagaren har nyligen uppdaterats. Sök igenom kanalerna igen."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Aktivera surroundljud under inställningarna för systemljud om du vill aktivera ljud"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Det går inte att spela upp ljud. Testa en annan TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Inställning av kanalmottagare"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Konfiguration av TV-mottagare"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Kanalinställning för USB-mottagare"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Konfiguration av nätverksmottagare"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Verifiera att TV:n är ansluten till en signalkälla på TV:n.\n\nOm du använder en antenn för over the air-uppdateringar justerar du dess placering eller riktning. Placera den högt upp och nära ett fönster och sök på nytt för bästa resultat."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Verifiera att USB-mottagaren är ansluten till en signalkälla på TV:n.\n\nOm du använder en antenn för over the air-uppdateringar kan du behöva justera dess placering eller riktning för att hitta så många kanaler som möjligt. Placera den högt upp och nära ett fönster för bästa resultat."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Verifiera att nätverksmottagaren är på och ansluten till en signalkälla på TV:n.\n\nOm du använder en antenn för over the air-uppdateringar justerar du dess placering eller riktning. Placera den högt upp och nära ett fönster och sök på nytt för bästa resultat."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Fortsätt"</item>
<item msgid="727245208787621142">"Inte nu"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Vill du göra om kanalinställningen?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Kanalerna som hittats via TV-mottagaren tas bort och en ny kanalsökning startas.\n\nVerifiera att TV:n är ansluten till en signalkälla på TV:n.\n\nOm du använder en antenn för over the air-uppdateringar justerar du dess placering eller riktning. Placera den högt upp och nära ett fönster och sök på nytt för bästa resultat."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Kanalerna som hittats via USB-mottagaren tas bort och en ny kanalsökning startas.\n\nVerifiera att USB-mottagaren är ansluten till en signalkälla på TV:n.\n\nOm du använder en antenn för over the air-uppdateringar kan du behöva justera dess placering eller riktning för att hitta så många kanaler som möjligt. Placera den högt upp och nära ett fönster för bästa resultat."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Åtgärden tar bort alla kanaler som hittades av nätverksmottagaren och söker efter nya kanaler igen.\n\nVerifiera att nätverksmottagaren är på och ansluten till en signalkälla på TV:n.\n\nOm du använder en antenn för over the air-uppdateringar justerar du dess placering eller riktning. Placera den högt upp och nära ett fönster och sök på nytt för bästa resultat."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Fortsätt"</item>
<item msgid="235450158666155406">"Avbryt"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Konfiguration av TV-mottagare"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Kanalinställning för USB-mottagare"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Konfiguration av mottagare för nätverkskanaler"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Det här kan ta flera minuter"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Mottagaren är inte tillgänglig just nu eller så spelas andra program in med den."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Inga kanaler hittades"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Inga kanaler hittades vid sökningen. Verifiera att TV:n är ansluten till en signalkälla på TV:n.\n\nOm du använder en antenn för over the air-uppdateringar justerar du dess placering eller riktning. Placera den högt upp och nära ett fönster och sök på nytt för bästa resultat."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Inga kanaler hittades vid sökningen. Verifiera att USB-mottagaren är ansluten till en signalkälla på TV:n.\n\nOm du använder en antenn för over the air-uppdateringar justerar du dess placering eller riktning. Placera den högt upp och nära ett fönster och sök på nytt för bästa resultat."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Inga kanaler hittades under genomsökningen. Verifiera att nätverksmottagaren är på och ansluten till en signalkälla på TV:n.\n\nOm du använder en antenn för over the air-uppdateringar justerar du dess placering eller riktning. Placera den högt upp och nära ett fönster och sök på nytt för bästa resultat."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Sök igen"</item>
<item msgid="2092797862490235174">"Klar"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Sök efter TV-kanaler"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Konfiguration av TV-mottagare"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Konfiguration av USB-TV-mottagare"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB-TV-mottagaren har kopplats från"</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Sök efter TV-kanaler"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Konfiguration av TV-mottagare"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Konfiguration av USB-ansluten TV-mottagare"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Konfiguration av nätverksansluten TV-mottagare"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-TV-mottagaren har kopplats från."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Nätverksmottagaren har kopplats från."</string>
</resources>
diff --git a/usbtuner-res/values-sw/strings.xml b/usbtuner-res/values-sw/strings.xml
index 1ade7516..c81614c0 100644
--- a/usbtuner-res/values-sw/strings.xml
+++ b/usbtuner-res/values-sw/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Kitafutaji cha vituo vya TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Kitafutaji cha Vituo vya TV cha USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Washa"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Zima"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Kitafuta Vituo vya TV ya Mtandao (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Tafadhali subiri ili shughuli imalizike"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Chagua chanzo cha kituo"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Hakuna Mawimbi"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Imeshindwa kupata kituo cha <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Imeshindwa kupata kituo"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Programu ya kitafutaji cha vituo cha USB ilisasishwa hivi majuzi. Tafadhali tafuta vituo tena."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Washa sauti ya mzunguko katika mipangilio ya mfumo wa sauti ili uruhusu sauti"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Haiwezi kucheza sauti. Tafadhali jaribu TV nyingine"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kuweka mipangilio ya kitafutaji cha vituo"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Kuweka mipangilio ya kitafutaji cha vituo vya TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Kuweka mipangilio ya kitafutaji cha vituo cha USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Kuweka mipangilio ya kitafuta vituo vya TV"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Hakikisha TV yako imeunganishwa kwenye chanzo cha TV.\n\nIkiwa unatumia antena ya hewani, rekebisha jinsi ilivyowekwa au mwelekeo wake. Ili kupata matokeo bora zaidi, ipandishe juu na uiweke karibu na dirisha."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Thibitisha kuwa kitafutaji cha vituo cha USB kimechomekwa katika chanzo cha umeme na kuunganishwa katika chanzo cha mawimbi ya TV.\n\nKama unatumia antena ya hewani, rekebisha mkao wake au kule inakoelekea. Kwa matokeo bora zaidi, iweke juu , karibu na dirisha."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Thibitisha kuwa kitafuta vituo kimewashwa na kuunganishwa kwenye chanzo cha mawimbi ya TV. \n\nIkiwa unatumia antena ya hewani, huenda ukahitaji kurekebisha jinsi ilivyowekwa au inakoelekea, ili upate vituo vingi. Kwa matokeo bora zaidi, ipandishe juu na iwe karibu na dirisha."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Endelea"</item>
<item msgid="727245208787621142">"Si sasa"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Ungependa kuweka mipangilio ya vituo upya?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Hatua hii itaondoa vituo vilivyopatikana kwenye kitafutaji cha vituo vya TV na kutafuta vituo vipya tena.\n\nHakikisha TV yako imeunganishwa kwenye chanzo cha mawimbi ya TV.\n\nIkiwa unatumia antena ya hewani, rekebisha jinsi ilivyowekwa au mwelekeo wake. Ili kupata matokeo bora zaidi, ipandishe juu na uiweke karibu na dirisha kisha utafute tena."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Hatua hii itaondoa vituo vilivyopatikana kwenye kitafutaji cha vituo cha USB na kutafuta vituo tena. \n\nThibitisha kuwa kitafutaji cha vituo cha USB kimechomekwa kwenye chanzo cha umeme na kuunganishwa katika chanzo cha mawimbi ya TV.\n\nKama unatumia antena ya hewani, rekebisha mkao wake au kule inakoelekea. Kwa matokeo bora zaidi, iweke juu, karibu na dirisha."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Hatua hii itaondoa vituo ulivyopata kwenye kitafuta vituo na kutafuta vituo vipya tena.\n\nThibitisha kwamba kitafuta vituo kimewashwa na kuunganishwa kwenye chanzo cha mawimbi ya TV.\n\nIkiwa unatumia antena ya hewani, rekebisha jinsi ilivyowekwa au inakoelekea, ili upate vituo vingi. Kwa matokeo bora zaidi, ipandishe juu na iwe karibu na dirisha."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Endelea"</item>
<item msgid="235450158666155406">"Ghairi"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Kuweka mipangilio ya kitafutaji cha vituo vya TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Kuweka mipangilio ya kitafutaji cha vituo cha USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Kuweka mipangilio ya kitafuta vituo"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Shughuli hii inaweza kuchukua dakika kadhaa"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Kitafuta vituo hakipatikani kwa sasa au tayari kinatumiwa kurekodi."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Hakuna Vituo vilivyopatikana"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Hakuna vituo vilivyopatikana baada ya kutafuta. Hakikisha TV yako imeunganishwa kwenye chanzo cha mawimbi ya TV.\n\nIkiwa unatumia antena ya hewani, rekebisha jinsi ilivyowekwa au mwelekeo wake. Ili kupata matokeo bora zaidi, ipandishe juu na uiweke karibu na dirisha kisha utafute tena."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Utafutaji haukupata vituo vyovyote. Thibitisha kuwa kitafutaji cha vituo cha USB kimechomekwa kwenye chanzo cha umeme na kuunganishwa katika chanzo cha mawimbi ya TV.\n\nKama unatumia antena ya hewani, rekebisha mkao wake au kule inakoelekea. Kwa matokeo bora zaidi, iweke juu, karibu na dirisha na utafute tena."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Haikupata vituo vyovyote. Thibitisha kwamba kitafuta vituo kimewashwa na kuunganishwa kwenye chanzo cha mawimbi ya TV.\n\nIkiwa unatumia antena ya hewani, rekebisha jinsi ilivyowekwa au inakoelekea. Ili upate matokeo bora zaidi, ipandishe juu na karibu na dirisha kisha utafute tena."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Tafuta tena"</item>
<item msgid="2092797862490235174">"Nimemaliza"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Tafuta vituo vya TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Kuweka mipangilio ya kitafutaji cha vituo vya TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Kuweka mipangilio ya Kitafutaji cha Vituo cha USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Umeondoa kichagua programu cha USB cha TV."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Tafuta vituo vya TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Kuweka mipangilio ya kitafutaji cha vituo vya TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Kuweka mipangilio ya Kitafutaji cha Vituo vya TV kupitia USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Kuweka mipangilio ya Kitafutaji cha Vituo vya TV kupitia Mtandao"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Umeondoa kichagua programu cha USB cha TV."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Umeondoa kitafuta mitandao."</string>
</resources>
diff --git a/usbtuner-res/values-ta-rIN/strings.xml b/usbtuner-res/values-ta-rIN/strings.xml
new file mode 100644
index 00000000..1c71722e
--- /dev/null
+++ b/usbtuner-res/values-ta-rIN/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"டிவி ட்யூனர்"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB டிவி ட்யூனர்"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"நெட்வொர்க் டிவி டியூனர் (பீட்டா)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"செயலாக்கம் முடியும் வரை காத்திருக்கவும்"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"ட்யூனர் மென்பொருள் சமீபத்தில் புதுப்பிக்கப்பட்டது. சேனல்களை மீண்டும் ஸ்கேன் செய்யவும்."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ஆடியோவை இயக்க, சாதன ஒலி அமைப்புகளில் \"சரவுண்ட் சவுண்ட்\" என்பதை இயக்கவும்"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"ஆடியோவை இயக்க முடியவில்லை. வேறு டிவியைப் பயன்படுத்தவும்"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"சேனல் ட்யூனர் அமைவு"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"டிவி ட்யூனர் அமைவு"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB சேனல் ட்யூனர் அமைவு"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"நெட்வொர்க் டியூனர் அமைவு"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"டிவி சிக்னல் மூலத்துடன் உங்கள் டிவி இணைக்கப்பட்டுள்ளதைச் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதிகமான சேனல்களைப் பெறுவதற்காக அதன் இடம் அல்லது திசையைச் சரிசெய்ய வேண்டியிருக்கலாம். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைக்கவும்."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ட்யூனர் செருகப்பட்டுள்ளதையும் டிவி சிக்னல் மூலத்துடன் இணைக்கப்பட்டுள்ளதையும் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதிகமான சேனல்களைப் பெறுவதற்காக அதன் இடம் அல்லது திசையைச் சரிசெய்ய வேண்டியிருக்கலாம். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைக்கவும்."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"நெட்வொர்க் டியூனர் ஆன் செய்யப்பட்டுள்ளதையும் டிவி சிக்னல் மூலத்துடன் இணைக்கப்பட்டுள்ளதையும் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதிகமான சேனல்களைப் பெறுவதற்காக அதன் இடம் அல்லது திசையைச் சரிசெய்ய வேண்டியிருக்கலாம். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைக்கவும்."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"தொடர்க"</item>
+ <item msgid="727245208787621142">"இப்போது வேண்டாம்"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"சேனல் அமைவை மீண்டும் இயக்கவா?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"இவ்வாறு செய்வதால் டிவி ட்யூனர் மூலம் கண்டறிந்த சேனல்கள் அகற்றப்படுவதுடன், புதிய சேனல்களுக்காக மீண்டும் ஸ்கேன் செய்யும்.\n\nடிவி சிக்னல் மூலத்துடன் உங்கள் டிவி இணைக்கப்பட்டுள்ளதைச் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதிகமான சேனல்களைப் பெறுவதற்காக அதன் இடம் அல்லது திசையைச் சரிசெய்ய வேண்டியிருக்கலாம். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைக்கவும்."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"இவ்வாறு செய்வதால் USB ட்யூனர் மூலம் கண்டறிந்த சேனல்கள் அகற்றப்படுவதுடன், புதிய சேனல்களுக்காக மீண்டும் ஸ்கேன் செய்யும்.\n\nUSB ட்யூனர் செருகப்பட்டுள்ளதையும் டிவி சிக்னல் மூலத்துடன் இணைக்கப்பட்டுள்ளதையும் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதிகமான சேனல்களைப் பெறுவதற்காக அதன் இடம் அல்லது திசையைச் சரிசெய்ய வேண்டியிருக்கலாம். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைக்கவும்."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"இது நெட்வொர்க் டியூனரிலிருந்து கண்டறிந்த சேனல்களை அகற்றும் மற்றும் புதிய சேனல்களுக்காக மீண்டும் ஸ்கேன் செய்யும்.\n\nநெட்வொர்க் டியூனர் ஆன் செய்யப்பட்டுள்ளதையும் டிவி சிக்னல் மூலத்துடன் இணைக்கப்பட்டுள்ளதையும் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதிகமான சேனல்களைப் பெறுவதற்காக, அதன் இடம் அல்லது திசையைச் சரிசெய்ய வேண்டியிருக்கலாம். இன்னும் சிறப்பான முடிவுகளுக்கு, உயரமான இடத்தில், ஜன்னலுக்கு அருகில் வைக்கவும்."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"தொடர்க"</item>
+ <item msgid="235450158666155406">"ரத்துசெய்"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"இணைப்பு வகையைத் தேர்ந்தெடுக்கவும்"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"ட்யூனருடன் வெளிப்புற ஆன்டெனா இணைக்கப்பட்டிருந்தால், ஆன்டெனாவைத் தேர்வுசெய்யவும். கேபிள் சேவை வழங்குநரிடமிருந்து சேனல்கள் கிடைக்கின்றன என்றால், கேபிளைத் தேர்வுசெய்யவும். எதையும் தேர்வுசெய்யவில்லை எனில், இரு வகைகளிலும் ஸ்கேன் செய்யப்படும். ஆனால் இதற்கு அதிக நேரம் ஆகலாம்."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"ஆன்டெனா"</item>
+ <item msgid="2670079958754180142">"கேபிள்"</item>
+ <item msgid="36774059871728525">"நிச்சயமாகத் தெரியவில்லை"</item>
+ <item msgid="6881204453182153978">"டெவெலப்மென்ட் மட்டும்"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"டிவி ட்யூனர் அமைவு"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB சேனல் ட்யூனர் அமைவு"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"நெட்வொர்க் சேனல் டியூனர் அமைவு"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"இதற்குச் சில நிமிடங்கள் ஆகலாம்"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ட்யூனர் தற்காலிகமாகக் கிடைக்கவில்லை அல்லது ரெக்கார்டு செய்வதற்காக ஏற்கனவே பயன்படுத்தப்படுகிறது."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d சேனல்கள் கண்டறியப்பட்டன</item>
+ <item quantity="one">%1$d சேனல் கண்டறியப்பட்டது</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"சேனலை ஸ்கேன் செய்வதை நிறுத்து"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d சேனல்கள் கண்டறியப்பட்டன</item>
+ <item quantity="one">%1$d சேனல் கண்டறியப்பட்டது</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">அருமை! சேனலை ஸ்கேன் செய்யும் போது, %1$d சேனல்கள் கண்டறியப்பட்டன. இவை சரியாகத் தெரியவில்லை என்றால், ஆன்டெனாவின் நிலையை மாற்றி, மீண்டும் ஸ்கேன் செய்யவும்.</item>
+ <item quantity="one">அருமை! சேனலை ஸ்கேன் செய்யும் போது, %1$d சேனல் கண்டறியப்பட்டது. இது சரியாகத் தெரியவில்லை என்றால், ஆன்டெனாவின் நிலையை மாற்றி, மீண்டும் ஸ்கேன் செய்யவும்.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"முடிந்தது"</item>
+ <item msgid="2480490326672924828">"மீண்டும் ஸ்கேன் செய்"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"சேனல்கள் இல்லை"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"ஸ்கேன் செய்ததில் சேனல்கள் எவையும் கண்டறியப்படவில்லை. டிவி சிக்னல் மூலத்துடன் உங்கள் டிவி இணைக்கப்பட்டுள்ளதைச் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதன் இடம் அல்லது திசையைச் சரிசெய்யவும். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைத்து, மீண்டும் ஸ்கேன் செய்யவும்."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"ஸ்கேன் செய்ததில் சேனல்கள் எவையும் கண்டறியப்படவில்லை. USB ட்யூனர் செருகப்பட்டுள்ளதையும் டிவி சிக்னல் மூலத்துடன் இணைக்கப்பட்டுள்ளதையும் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதன் இடம் அல்லது திசையைச் சரிசெய்யவும். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைத்து, மீண்டும் ஸ்கேன் செய்யவும்."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"ஸ்கேன் செய்ததில் சேனல்கள் எதுவும் கண்டறியப்படவில்லை. நெட்வொர்க் டியூனர் ஆன் செய்யப்பட்டுள்ளதையும் டிவி சிக்னல் மூலத்துடன் இணைக்கப்பட்டுள்ளதையும் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதன் இடம் அல்லது திசையைச் சரிசெய்யவும். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைத்து, மீண்டும் ஸ்கேன் செய்யவும்."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"மீண்டும் ஸ்கேன் செய்"</item>
+ <item msgid="2092797862490235174">"முடிந்தது"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"டிவி சேனல்களைத் தேடுக"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"டிவி டியூனர் அமைவு"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB டிவி டியூனர் அமைவு"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"நெட்வொர்க் டிவி டியூனர் அமைவு"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB டிவி ட்யூனர் துண்டிக்கப்பட்டது."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"நெட்வொர்க் ட்யூனர் துண்டிக்கப்பட்டது."</string>
+</resources>
diff --git a/usbtuner-res/values-ta/strings.xml b/usbtuner-res/values-ta/strings.xml
deleted file mode 100644
index dd09420d..00000000
--- a/usbtuner-res/values-ta/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"டிவி ட்யூனர்"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB டிவி ட்யூனர்"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"இயக்கு"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"முடக்கு"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"செயலாக்கம் முடியும் வரை காத்திருக்கவும்"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"சேனல் மூலத்தைத் தேர்ந்தெடுக்கவும்"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"சிக்னல் இல்லை"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g>க்கு ட்யூன் செய்ய முடியவில்லை"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ட்யூன் செய்ய முடியவில்லை"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"ட்யூனர் மென்பொருள் சமீபத்தில் புதுப்பிக்கப்பட்டது. சேனல்களை மீண்டும் ஸ்கேன் செய்யவும்."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ஆடியோவை இயக்க, சாதன ஒலி அமைப்புகளில் \"சரவுண்ட் சவுண்ட்\" என்பதை இயக்கவும்"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"சேனல் ட்யூனர் அமைவு"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"டிவி ட்யூனர் அமைவு"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB சேனல் ட்யூனர் அமைவு"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"டிவி சிக்னல் மூலத்துடன் உங்கள் டிவி இணைக்கப்பட்டுள்ளதைச் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதிகமான சேனல்களைப் பெறுவதற்காக அதன் இடம் அல்லது திசையைச் சரிசெய்ய வேண்டியிருக்கலாம். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைக்கவும்."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ட்யூனர் செருகப்பட்டுள்ளதையும் டிவி சிக்னல் மூலத்துடன் இணைக்கப்பட்டுள்ளதையும் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதிகமான சேனல்களைப் பெறுவதற்காக அதன் இடம் அல்லது திசையைச் சரிசெய்ய வேண்டியிருக்கலாம். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைக்கவும்."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"தொடர்க"</item>
- <item msgid="727245208787621142">"இப்போது வேண்டாம்"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"சேனல் அமைவை மீண்டும் இயக்கவா?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"இவ்வாறு செய்வதால் டிவி ட்யூனர் மூலம் கண்டறிந்த சேனல்கள் அகற்றப்படுவதுடன், புதிய சேனல்களுக்காக மீண்டும் ஸ்கேன் செய்யும்.\n\nடிவி சிக்னல் மூலத்துடன் உங்கள் டிவி இணைக்கப்பட்டுள்ளதைச் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதிகமான சேனல்களைப் பெறுவதற்காக அதன் இடம் அல்லது திசையைச் சரிசெய்ய வேண்டியிருக்கலாம். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைக்கவும்."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"இவ்வாறு செய்வதால் USB ட்யூனர் மூலம் கண்டறிந்த சேனல்கள் அகற்றப்படுவதுடன், புதிய சேனல்களுக்காக மீண்டும் ஸ்கேன் செய்யும்.\n\nUSB ட்யூனர் செருகப்பட்டுள்ளதையும் டிவி சிக்னல் மூலத்துடன் இணைக்கப்பட்டுள்ளதையும் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதிகமான சேனல்களைப் பெறுவதற்காக அதன் இடம் அல்லது திசையைச் சரிசெய்ய வேண்டியிருக்கலாம். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைக்கவும்."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"தொடர்க"</item>
- <item msgid="235450158666155406">"ரத்துசெய்"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"இணைப்பு வகையைத் தேர்ந்தெடுக்கவும்"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"ட்யூனருடன் வெளிப்புற ஆன்டெனா இணைக்கப்பட்டிருந்தால், ஆன்டெனாவைத் தேர்வுசெய்யவும். கேபிள் சேவை வழங்குநரிடமிருந்து சேனல்கள் கிடைக்கின்றன என்றால், கேபிளைத் தேர்வுசெய்யவும். எதையும் தேர்வுசெய்யவில்லை எனில், இரு வகைகளிலும் ஸ்கேன் செய்யப்படும். ஆனால் இதற்கு அதிக நேரம் ஆகலாம்."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"ஆன்டெனா"</item>
- <item msgid="2670079958754180142">"கேபிள்"</item>
- <item msgid="36774059871728525">"நிச்சயமாகத் தெரியவில்லை"</item>
- <item msgid="6881204453182153978">"டெவெலப்மென்ட் மட்டும்"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"டிவி ட்யூனர் அமைவு"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB சேனல் ட்யூனர் அமைவு"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"இதற்குச் சில நிமிடங்கள் ஆகலாம்"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ட்யூனர் தற்காலிகமாகக் கிடைக்கவில்லை அல்லது ரெக்கார்டு செய்வதற்காக ஏற்கனவே பயன்படுத்தப்படுகிறது."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d சேனல்கள் கண்டறியப்பட்டன</item>
- <item quantity="one">%1$d சேனல் கண்டறியப்பட்டது</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"சேனலை ஸ்கேன் செய்வதை நிறுத்து"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d சேனல்கள் கண்டறியப்பட்டன</item>
- <item quantity="one">%1$d சேனல் கண்டறியப்பட்டது</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">அருமை! சேனலை ஸ்கேன் செய்யும் போது, %1$d சேனல்கள் கண்டறியப்பட்டன. இவை சரியாகத் தெரியவில்லை என்றால், ஆன்டெனாவின் நிலையை மாற்றி, மீண்டும் ஸ்கேன் செய்யவும்.</item>
- <item quantity="one">அருமை! சேனலை ஸ்கேன் செய்யும் போது, %1$d சேனல் கண்டறியப்பட்டது. இது சரியாகத் தெரியவில்லை என்றால், ஆன்டெனாவின் நிலையை மாற்றி, மீண்டும் ஸ்கேன் செய்யவும்.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"முடிந்தது"</item>
- <item msgid="2480490326672924828">"மீண்டும் ஸ்கேன் செய்"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"சேனல்கள் இல்லை"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"ஸ்கேன் செய்ததில் சேனல்கள் எவையும் கண்டறியப்படவில்லை. டிவி சிக்னல் மூலத்துடன் உங்கள் டிவி இணைக்கப்பட்டுள்ளதைச் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதன் இடம் அல்லது திசையைச் சரிசெய்யவும். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைத்து, மீண்டும் ஸ்கேன் செய்யவும்."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"ஸ்கேன் செய்ததில் சேனல்கள் எவையும் கண்டறியப்படவில்லை. USB ட்யூனர் செருகப்பட்டுள்ளதையும் டிவி சிக்னல் மூலத்துடன் இணைக்கப்பட்டுள்ளதையும் சரிபார்க்கவும்.\n\nஆன்டெனாவைப் பயன்படுத்தினால், அதன் இடம் அல்லது திசையைச் சரிசெய்யவும். இன்னும் சிறப்பான முடிவுகளுக்கு, அதை உயரமான இடத்தில் ஜன்னலுக்கு அருகே வைத்து, மீண்டும் ஸ்கேன் செய்யவும்."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"மீண்டும் ஸ்கேன் செய்"</item>
- <item msgid="2092797862490235174">"முடிந்தது"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"டிவி சேனல்களை ஸ்கேன் செய்"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"டிவி ட்யூனர் அமைவு"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB டிவி ட்யூனர் அமைவு"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB டிவி ட்யூனர் வெளியே எடுக்கப்பட்டது."</string>
-</resources>
diff --git a/usbtuner-res/values-te-rIN/strings.xml b/usbtuner-res/values-te-rIN/strings.xml
new file mode 100644
index 00000000..fb6bcf37
--- /dev/null
+++ b/usbtuner-res/values-te-rIN/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"టీవీ ట్యూనర్"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB టీవీ ట్యూనర్"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"నెట్‌వర్క్ టీవీ ట్యూనర్ (బీటా)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"దయచేసి ప్రాసెస్ చేయడం పూర్తయ్యే వరకు వేచి ఉండండి"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"ట్యూనర్ సాఫ్ట్‌వేర్ ఇటీవల నవీకరించబడింది. దయచేసి ఛానెల్‌లను మళ్లీ స్కాన్ చేయండి."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ఆడియోను ప్రారంభించడానికి సిస్టమ్ శబ్ద సెట్టింగ్‌ల్లో పరిసర వ్యాప్త శబ్దాన్ని ప్రారంభించండి"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"ఆడియోను ప్లే చేయడం సాధ్యపడదు. దయచేసి మరో టీవీలో ప్రయత్నించండి"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ఛానెల్ ట్యూనర్ సెటప్"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"టీవీ ట్యూనర్ సెటప్"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB ఛానెల్ ట్యూనర్ సెటప్"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"నెట్‍వర్క్ ట్యూనర్ సెటప్"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"టీవీ.సిగ్నల్ సోర్స్‌కు మీ టీవీ కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, మీరు మరిన్ని ఛానెల్‌లను స్వీకరించడానికి దాని స్థానాన్ని లేదా దిశను మార్చాల్సి రావచ్చు. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచండి."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ట్యూనర్ ప్లగిన్ చేయబడి, టీవీ సిగ్నల్ సోర్స్‌కు కనెక్ట్ చేయబడినట్లు ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, మీరు మరిన్ని ఛానెల్‌లను స్వీకరించడానికి దాని స్థానాన్ని లేదా దిశను మార్చాల్సి రావచ్చు. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచండి."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"నెట్‍వర్క్ ట్యూనర్ పవర్ ఆన్ చేయబడి, టీవీ సిగ్నల్ సోర్స్‌కు కనెక్ట్ చేయబడినట్లు ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, మీరు మరిన్ని ఛానెల్‌లను స్వీకరించడానికి దాని స్థానాన్ని లేదా దిశను మార్చాల్సి రావచ్చు. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచండి."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"కొనసాగించు"</item>
+ <item msgid="727245208787621142">"ఇప్పుడు కాదు"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"ఛానెల్ సెటప్‌ను మళ్లీ అమలు చేయాలా?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"ఇది టీవీ ట్యూనర్ నుండి కనుగొన్న ఛానెల్‌లను తీసివేస్తుంది మరియు మళ్లీ కొత్త ఛానెల్‌ల కోసం స్కాన్ చేస్తుంది.\n\nటీవీ సిగ్నల్ సోర్స్‌కు మీ టీవీ కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, మీరు మరిన్ని ఛానెల్‌లను స్వీకరించడానికి దాని స్థానాన్ని లేదా దిశను మార్చాల్సి రావచ్చు. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచండి."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"ఇది USB ట్యూనర్ నుండి కనుగొన్న ఛానెల్‌లను తీసివేస్తుంది మరియు మళ్లీ కొత్త ఛానెల్‌ల కోసం స్కాన్ చేస్తుంది.\n\nUSB ట్యూనర్ ప్లగిన్ చేయబడి, టీవీ సిగ్నల్ సోర్స్‌కు కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, మీరు మరిన్ని ఛానెల్‌లను స్వీకరించడానికి దాని స్థానాన్ని లేదా దిశను మార్చాల్సి రావచ్చు. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచండి."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"ఇది నెట్‍వర్క్ ట్యూనర్ నుండి కనుగొన్న ఛానెల్‌లను తీసివేస్తుంది మరియు మళ్లీ కొత్త ఛానెల్‌ల కోసం స్కాన్ చేస్తుంది.\n\nనెట్‍వర్క్ ట్యూనర్ పవర్ ఆన్ చేయబడి, టీవీ సిగ్నల్ సోర్స్‌కు కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, మీరు మరిన్ని ఛానెల్‌లను స్వీకరించడానికి దాని స్థానాన్ని లేదా దిశను మార్చాలి. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచండి."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"కొనసాగించు"</item>
+ <item msgid="235450158666155406">"రద్దు చేయి"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"కనెక్షన్ రకాన్ని ఎంచుకోండి"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"ట్యూనర్‌కు బాహ్య యాంటెన్నా కనెక్ట్ చేసి ఉంటే యాంటెన్నాను ఎంచుకోండి. మీ ఛానెల్‌‍‍లను కేబుల్ సేవా ప్రదాత అందిస్తుంటే, కేబుల్‌ను ఎంచుకోండి. మీకు ఏ సంగతి ఖచ్చితంగా తెలియకుంటే, రెండు రకాలు స్కాన్ చేయబడతాయి, కానీ దీనికి ఎక్కువ సమయం పట్టవచ్చు."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"యాంటెన్నా"</item>
+ <item msgid="2670079958754180142">"కేబుల్"</item>
+ <item msgid="36774059871728525">"అంత ఖచ్చితంగా తెలియదు"</item>
+ <item msgid="6881204453182153978">"అభివృద్ధి మాత్రమే"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"టీవీ ట్యూనర్ సెటప్"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB ఛానెల్ ట్యూనర్ సెటప్"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"నెట్‍వర్క్ ఛానెల్ ట్యూనర్ సెటప్"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"దీనికి కొన్ని నిమిషాలు పట్టవచ్చు"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ట్యూనర్ తాత్కాలికంగా అందుబాటులో లేదు లేదా ఇప్పటికే రికార్డింగ్ ద్వారా ఉపయోగించబడుతోంది."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d ఛానెల్‌లు కనుగొనబడ్డాయి</item>
+ <item quantity="one">%1$d ఛానెల్ కనుగొనబడింది</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"ఛానెల్ స్కాన్‌ను ఆపివేయి"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d ఛానెల్‌లు కనుగొనబడ్డాయి</item>
+ <item quantity="one">%1$d ఛానెల్ కనుగొనబడింది</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">మంచిది! ఛానెల్ స్కాన్‌లో %1$d ఛానెల్‌లు కనుగొనబడ్డాయి. ఇది సరైనదిగా అనిపించకుంటే, యాంటెన్నా స్థానం సర్దుబాటు చేసి, ఆపై మళ్లీ స్కాన్ చేయడం ప్రయత్నించండి.</item>
+ <item quantity="one">మంచిది! ఛానెల్ స్కాన్‌లో %1$d ఛానెల్ కనుగొనబడింది. ఇది సరైనదిగా అనిపించకుంటే, యాంటెన్నా స్థానం సర్దుబాటు చేసి, ఆపై మళ్లీ స్కాన్ చేయడం ప్రయత్నించండి.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"పూర్తయింది"</item>
+ <item msgid="2480490326672924828">"మళ్లీ స్కాన్ చేయి"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"ఛానెల్‌లు ఏవీ కనుగొనబడలేదు"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"స్కాన్‌లో ఏ ఛానెల్ కనుగొనబడలేదు. టీవీ సిగ్నల్ సోర్స్‌కి మీ టీవీ కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి. \n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, దాని స్థానాన్ని లేదా దిశను సర్దుబాటు చేయండి. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచి, ఆపై మళ్లీ స్కాన్ చేయండి."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"స్కాన్‌లో ఛానెల్‌లు ఏవీ కనుగొనబడలేదు. USB ట్యూనర్ ప్లగిన్ చేయబడి, టీవీ సిగ్నల్ సోర్స్‌కు కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, దాని స్థానాన్ని లేదా దిశను సర్దుబాటు చేయండి. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచి, ఆపై మళ్లీ స్కాన్ చేయండి."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"స్కాన్‌లో ఛానెల్‌లు ఏవీ కనుగొనబడలేదు. నెట్‍వర్క్ ట్యూనర్ పవర్ ఆన్ చేయబడి, టీవీ సిగ్నల్ సోర్స్‌కు కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, దాని స్థానాన్ని లేదా దిశను సర్దుబాటు చేయండి. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచి, ఆపై మళ్లీ స్కాన్ చేయండి."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"మళ్లీ స్కాన్ చేయి"</item>
+ <item msgid="2092797862490235174">"పూర్తయింది"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"టీవీ ఛానెల్‌ల కోసం స్కాన్ చేయండి"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"టీవీ ట్యూనర్ సెటప్"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB టీవీ ట్యూనర్ సెటప్"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"నెట్‍వర్క్ టీవీ ట్యూనర్ సెటప్"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB టీవీ ట్యూనర్ డిస్‌కనెక్ట్ చేయబడింది."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"నెట్‌వర్క్ ట్యూనర్ డిస్‌కనెక్ట్ చేయబడింది."</string>
+</resources>
diff --git a/usbtuner-res/values-te/strings.xml b/usbtuner-res/values-te/strings.xml
deleted file mode 100644
index a80bd1c7..00000000
--- a/usbtuner-res/values-te/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"టీవీ ట్యూనర్"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB టీవీ ట్యూనర్"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"ఆన్ చేయి"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"ఆఫ్ చేయి"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"దయచేసి ప్రాసెస్ చేయడం పూర్తయ్యే వరకు వేచి ఉండండి"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"మీ ఛానెల్ మూలాన్ని ఎంచుకోండి"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"సిగ్నల్ లేదు"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g>కి ట్యూన్ చేయడంలో విఫలమైంది"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ట్యూన్ చేయడంలో విఫలమైంది"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"ట్యూనర్ సాఫ్ట్‌వేర్ ఇటీవల నవీకరించబడింది. దయచేసి ఛానెల్‌లను మళ్లీ స్కాన్ చేయండి."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"ఆడియోను ప్రారంభించడానికి సిస్టమ్ శబ్ద సెట్టింగ్‌ల్లో పరిసర వ్యాప్త శబ్దాన్ని ప్రారంభించండి"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ఛానెల్ ట్యూనర్ సెటప్"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"టీవీ ట్యూనర్ సెటప్"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB ఛానెల్ ట్యూనర్ సెటప్"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"టీవీ.సిగ్నల్ సోర్స్‌కు మీ టీవీ కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, మీరు మరిన్ని ఛానెల్‌లను స్వీకరించడానికి దాని స్థానాన్ని లేదా దిశను మార్చాల్సి రావచ్చు. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచండి."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB ట్యూనర్ ప్లగిన్ చేయబడి, టీవీ సిగ్నల్ సోర్స్‌కు కనెక్ట్ చేయబడినట్లు ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, మీరు మరిన్ని ఛానెల్‌లను స్వీకరించడానికి దాని స్థానాన్ని లేదా దిశను మార్చాల్సి రావచ్చు. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచండి."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"కొనసాగించు"</item>
- <item msgid="727245208787621142">"ఇప్పుడు కాదు"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"ఛానెల్ సెటప్‌ను మళ్లీ అమలు చేయాలా?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"ఇది టీవీ ట్యూనర్ నుండి కనుగొన్న ఛానెల్‌లను తీసివేస్తుంది మరియు మళ్లీ కొత్త ఛానెల్‌ల కోసం స్కాన్ చేస్తుంది.\n\nటీవీ సిగ్నల్ సోర్స్‌కు మీ టీవీ కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, మీరు మరిన్ని ఛానెల్‌లను స్వీకరించడానికి దాని స్థానాన్ని లేదా దిశను మార్చాల్సి రావచ్చు. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచండి."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"ఇది USB ట్యూనర్ నుండి కనుగొన్న ఛానెల్‌లను తీసివేస్తుంది మరియు మళ్లీ కొత్త ఛానెల్‌ల కోసం స్కాన్ చేస్తుంది.\n\nUSB ట్యూనర్ ప్లగిన్ చేయబడి, టీవీ సిగ్నల్ సోర్స్‌కు కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, మీరు మరిన్ని ఛానెల్‌లను స్వీకరించడానికి దాని స్థానాన్ని లేదా దిశను మార్చాల్సి రావచ్చు. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచండి."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"కొనసాగించు"</item>
- <item msgid="235450158666155406">"రద్దు చేయి"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"కనెక్షన్ రకాన్ని ఎంచుకోండి"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"ట్యూనర్‌కు బాహ్య యాంటెన్నా కనెక్ట్ చేసి ఉంటే యాంటెన్నాను ఎంచుకోండి. మీ ఛానెల్‌‍‍లను కేబుల్ సేవా ప్రదాత అందిస్తుంటే, కేబుల్‌ను ఎంచుకోండి. మీకు ఏ సంగతి ఖచ్చితంగా తెలియకుంటే, రెండు రకాలు స్కాన్ చేయబడతాయి, కానీ దీనికి ఎక్కువ సమయం పట్టవచ్చు."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"యాంటెన్నా"</item>
- <item msgid="2670079958754180142">"కేబుల్"</item>
- <item msgid="36774059871728525">"అంత ఖచ్చితంగా తెలియదు"</item>
- <item msgid="6881204453182153978">"అభివృద్ధి మాత్రమే"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"టీవీ ట్యూనర్ సెటప్"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB ఛానెల్ ట్యూనర్ సెటప్"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"దీనికి కొన్ని నిమిషాలు పట్టవచ్చు"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ట్యూనర్ తాత్కాలికంగా అందుబాటులో లేదు లేదా ఇప్పటికే రికార్డింగ్ ద్వారా ఉపయోగించబడుతోంది."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d ఛానెల్‌లు కనుగొనబడ్డాయి</item>
- <item quantity="one">%1$d ఛానెల్ కనుగొనబడింది</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"ఛానెల్ స్కాన్‌ను ఆపివేయి"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d ఛానెల్‌లు కనుగొనబడ్డాయి</item>
- <item quantity="one">%1$d ఛానెల్ కనుగొనబడింది</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">మంచిది! ఛానెల్ స్కాన్‌లో %1$d ఛానెల్‌లు కనుగొనబడ్డాయి. ఇది సరైనదిగా అనిపించకుంటే, యాంటెన్నా స్థానం సర్దుబాటు చేసి, ఆపై మళ్లీ స్కాన్ చేయడం ప్రయత్నించండి.</item>
- <item quantity="one">మంచిది! ఛానెల్ స్కాన్‌లో %1$d ఛానెల్ కనుగొనబడింది. ఇది సరైనదిగా అనిపించకుంటే, యాంటెన్నా స్థానం సర్దుబాటు చేసి, ఆపై మళ్లీ స్కాన్ చేయడం ప్రయత్నించండి.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"పూర్తయింది"</item>
- <item msgid="2480490326672924828">"మళ్లీ స్కాన్ చేయి"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"ఛానెల్‌లు ఏవీ కనుగొనబడలేదు"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"స్కాన్‌లో ఏ ఛానెల్ కనుగొనబడలేదు. టీవీ సిగ్నల్ సోర్స్‌కి మీ టీవీ కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి. \n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, దాని స్థానాన్ని లేదా దిశను సర్దుబాటు చేయండి. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచి, ఆపై మళ్లీ స్కాన్ చేయండి."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"స్కాన్‌లో ఛానెల్‌లు ఏవీ కనుగొనబడలేదు. USB ట్యూనర్ ప్లగిన్ చేయబడి, టీవీ సిగ్నల్ సోర్స్‌కు కనెక్ట్ చేయబడిందని ధృవపరుచుకోండి.\n\nప్రసారాల కోసం యాంటెన్నాను ఉపయోగిస్తుంటే, దాని స్థానాన్ని లేదా దిశను సర్దుబాటు చేయండి. ఉత్తమ ఫలితాల కోసం, దాన్ని ఎత్తులో కిటికీకి దగ్గరగా ఉంచి, ఆపై మళ్లీ స్కాన్ చేయండి."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"మళ్లీ స్కాన్ చేయి"</item>
- <item msgid="2092797862490235174">"పూర్తయింది"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"టీవీ ఛానెల్‌ల కోసం స్కాన్ చేయండి"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"టీవీ ట్యూనర్ సెటప్"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB టీవీ ట్యూనర్ సెటప్"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB టీవీ ట్యూనర్ డిస్‌కనెక్ట్ చేయబడింది."</string>
-</resources>
diff --git a/usbtuner-res/values-th/strings.xml b/usbtuner-res/values-th/strings.xml
index 217520df..703c0f02 100644
--- a/usbtuner-res/values-th/strings.xml
+++ b/usbtuner-res/values-th/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"ตัวรับสัญญาณทีวี"</string>
<string name="ut_app_name" msgid="8557698013780762454">"ตัวรับสัญญาณทีวีแบบ USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"เปิด"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"ปิด"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"ตัวรับสัญญาณทีวีเครือข่าย (เบต้า)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"โปรดรอให้การดำเนินการหยุดลงสักครู่"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"เลือกแหล่งที่มาของช่อง"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"ไม่มีสัญญาณ"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"ไม่สามารถรับสัญญาณ <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ไม่สามารถรับสัญญาณ"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"ซอฟต์แวร์ตัวรับสัญญาณมีการอัปเดตเมื่อเร็วๆ นี้ โปรดสแกนช่องอีกครั้ง"</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"เปิดใช้เสียงเซอร์ราวด์ในการตั้งค่าเสียงของระบบเพื่อเปิดใช้เสียง"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"เล่นเสียงไม่ได้ โปรดลองทีวีเครื่องอื่น"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"ตั้งค่าตัวรับสัญญาณช่อง"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"ตั้งค่าตัวรับสัญญาณทีวี"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"ตั้งค่าตัวรับสัญญาณช่องแบบ USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"ตั้งค่าตัวรับสัญญาณเครือข่าย"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"โปรดตรวจสอบว่าทีวีของคุณเชื่อมต่อกับแหล่งสัญญาณทีวีแล้ว\n\nหากใช้เสาอากาศแบบผ่านอากาศ คุณอาจต้องปรับตำแหน่งและทิศทางเพื่อรับช่องให้ได้มากที่สุด เพื่อผลลัพธ์ที่ดีที่สุด ให้วางไว้บนที่สูงใกล้หน้าต่าง"</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"โปรดตรวจสอบว่าได้เสียบปลั๊กตัวรับสัญญาณแบบ USB และเชื่อมต่อกับแหล่งสัญญาณทีวีแล้ว\n\nหากใช้เสาอากาศแบบผ่านอากาศ คุณอาจต้องปรับตำแหน่งหรือทิศทางเพื่อรับช่องให้ได้มากที่สุด เพื่อผลลัพธ์ที่ดีที่สุด ให้วางไว้บนที่สูงใกล้หน้าต่าง"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"โปรดตรวจสอบว่าตัวรับสัญญาณเครือข่ายเปิดอยู่และเชื่อมต่อกับแหล่งสัญญาณทีวีแล้ว\n\nหากใช้เสาอากาศแบบผ่านอากาศ (OTA) คุณอาจต้องปรับตำแหน่งหรือทิศทางเพื่อรับช่องให้ได้มากที่สุด เพื่อผลลัพธ์ที่ดีที่สุด ให้วางไว้บนที่สูงใกล้หน้าต่าง"</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"ต่อไป"</item>
<item msgid="727245208787621142">"ข้ามไปก่อน"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"ต้องการเริ่มการตั้งค่าช่องอีกครั้งใช่ไหม"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"วิธีนี้จะนำช่องที่พบจากตัวรับสัญญาณทีวีออกและสแกนหาช่องใหม่อีกครั้ง\n\nโปรดตรวจสอบว่าทีวีของคุณเชื่อมต่อกับแหล่งสัญญาณทีวีแล้ว\n\nหากใช้เสาอากาศแบบผ่านอากาศ คุณอาจต้องปรับตำแหน่งและทิศทางเพื่อรับช่องให้ได้มากที่สุด เพื่อผลลัพธ์ที่ดีที่สุด ให้วางไว้บนที่สูงใกล้หน้าต่าง"</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"วิธีนี้จะนำช่องที่พบจากตัวรับสัญญาณแบบ USB ออกและสแกนหาช่องใหม่อีกครั้ง\n\nโปรดตรวจสอบว่าได้เสียบปลั๊กตัวรับสัญญาณแบบ USB และเชื่อมต่อกับแหล่งสัญญาณทีวีแล้ว\n\nหากใช้เสาอากาศแบบผ่านอากาศ คุณอาจต้องปรับตำแหน่งหรือทิศทางเพื่อรับช่องให้ได้มากที่สุด เพื่อผลลัพธ์ที่ดีที่สุด ให้วางไว้บนที่สูงใกล้หน้าต่าง"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"การดำเนินการนี้จะนำช่องที่พบจากตัวรับสัญญาณเครือข่ายออกแล้วสแกนหาช่องใหม่อีกครั้ง\n\nโปรดตรวจสอบว่าตัวรับสัญญาณเครือข่ายเปิดอยู่และเชื่อมต่อกับแหล่งสัญญาณทีวีแล้ว\n\nหากใช้เสาอากาศแบบผ่านอากาศ (OTA) คุณอาจต้องปรับตำแหน่งหรือทิศทางเพื่อรับช่องให้ได้มากที่สุด เพื่อผลลัพธ์ที่ดีที่สุด ให้วางไว้บนที่สูงใกล้หน้าต่าง"</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"ต่อไป"</item>
<item msgid="235450158666155406">"ยกเลิก"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"ตั้งค่าตัวรับสัญญาณทีวี"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"ตั้งค่าตัวรับสัญญาณช่องแบบ USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"ตั้งค่าตัวรับสัญญาณช่องเครือข่าย"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"อาจใช้เวลาหลายนาที"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ตัวรับสัญญาณไม่สามารถใช้ได้ชั่วคราว หรือถูกใช้ในการบันทึกแล้ว"</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"ไม่พบช่อง"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"สแกนไม่พบช่องใดเลย โปรดตรวจสอบว่าทีวีของคุณเชื่อมต่อกับแหล่งสัญญาณทีวีแล้ว\n\nหากคุณใช้เสาอากาศแบบผ่านอากาศ ให้ปรับตำแหน่งและทิศทาง เพื่อผลลัพธ์ที่ดีที่สุด ให้วางไว้บนที่สูงใกล้หน้าต่างแล้วสแกนอีกครั้ง"</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"สแกนไม่พบช่องใดเลย โปรดตรวจสอบว่าได้เสียบปลั๊กตัวรับสัญญาณแบบ USB และเชื่อมต่อกับแหล่งสัญญาณทีวีแล้ว\n\nหากคุณใช้เสาอากาศแบบผ่านอากาศ ให้ปรับตำแหน่งหรือทิศทาง เพื่อให้ได้ผลลัพธ์ที่ดีที่สุด ให้วางไว้บนที่สูงใกล้หน้าต่างแล้วสแกนอีกครั้ง"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"สแกนไม่พบช่องใดเลย โปรดตรวจสอบว่าตัวรับสัญญาณเครือข่ายเปิดอยู่และเชื่อมต่อกับแหล่งสัญญาณทีวีแล้ว\n\nหากใช้เสาอากาศแบบผ่านอากาศ (OTA) ให้ปรับตำแหน่งหรือทิศทาง เพื่อผลลัพธ์ที่ดีที่สุด ให้วางไว้บนที่สูงใกล้หน้าต่างแล้วสแกนอีกครั้ง"</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"สแกนอีกครั้ง"</item>
<item msgid="2092797862490235174">"เสร็จสิ้น"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"สแกนหาช่องทีวี"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"ตั้งค่าตัวรับสัญญาณทีวี"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"ตั้งค่าตัวรับสัญญาณทีวีแบบ USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"ยกเลิกการเชื่อมต่อตัวรับสัญญาณทีวีผ่าน USB แล้ว"</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"สแกนหาช่องทีวี"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"ตั้งค่าตัวรับสัญญาณทีวี"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"ตั้งค่าตัวรับสัญญาณทีวีแบบ USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"ตั้งค่าตัวรับสัญญาณทีวีเครือข่าย"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"ยกเลิกการเชื่อมต่อตัวรับสัญญาณทีวีผ่าน USB แล้ว"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"ยกเลิกการเชื่อมต่อตัวรับสัญญาณเครือข่ายแล้ว"</string>
</resources>
diff --git a/usbtuner-res/values-tl/strings.xml b/usbtuner-res/values-tl/strings.xml
index 7a0ce826..52c99eac 100644
--- a/usbtuner-res/values-tl/strings.xml
+++ b/usbtuner-res/values-tl/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV Tuner"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB TV Tuner"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"I-on"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"I-off"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Network TV Tuner (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Mangyaring maghintay na matapos ang pagpoproseso"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Piliin ang pinagmulan ng iyong channel"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Walang Signal"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Hindi na-tune sa <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Hindi na-tune"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Na-update kamakailan ang software ng tuner. Paki-scan muli ang mga channel."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"I-enable ang surround sound sa mga setting ng tunog ng system upang ma-enable ang audio"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Hindi ma-play ang audio. Mangyaring sumubok ng ibang TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Setup ng channel tuner"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Setup ng TV Tuner"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Setup ng USB channel tuner"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Pag-set up ng network tuner"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"I-verify na nakakonekta ang iyong TV sa isang TV signal source.\n\nKung gumagamit ng over-the-air antenna, maaaring kailanganin mong ayusin ang pagkakalagay o direksyon nito upang makuha ang pinakamaraming channel. Para sa mga pinakamainam na resulta, ilagay ito sa mataas na lugar at malapit sa isang bintana."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"I-verify na nakasaksak at nakakonekta ang USB tuner sa isang TV source signal.\n\nKung gumagamit ka ng isang over-the-air antenna, maaaring kailanganin mong ayusin ang pagkakalagay o direksyon nito upang makuha ang pinakamaraming channel. Para sa mga pinakamainam na resulta, ilagay ito sa isang mataas na lugar at malapit sa isang bintana."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"I-verify na naka-on ang network tuner at nakakonekta sa isang pinagmumulan ng TV signal.\n\nKung gumagamit ng over-the-air na antenna, maaaring kailanganin mong ayusin ang pagkakalagay o direksyon nito upang masagap ang karamihan ng mga channel. Para sa mga pinakamainam na resulta, ilagay ito sa mataas na lugar at malapit sa bintana."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Magpatuloy"</item>
<item msgid="727245208787621142">"Hindi ngayon"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Gusto mo bang muling patakbuhin ang pag-set up ng channel?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Aalisin nito ang mga nakitang channel mula sa TV tuner at mag-scan muli para sa mga bagong channel.\n\nI-verify na nakakonekta ang iyong TV sa isang TV signal source.\n\nKung gumagamit ka ng over-the-air antenna, maaaring kailanganin mong ayusin ang pagkakalagay o direksyon nito upang makuha ang pinakamaraming channel. Para sa mga pinakamainam na resulta, ilagay ito sa mataas na lugar at malapit sa isang bintana."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Aalisin nito ang mga channel na nahanap mula sa USB tuner at mag-scan muli para sa mga bagong channel.\n\nI-verify na nakasaksak at nakakonekta ang USB tuner sa isang TV source signal.\n\nKung gumagamit ng over-the-air antenna, maaaring kailanganin mong ayusin ang pagkakalagay o direksyon nito upang makuha ang pinakamaraming channel. Para sa mga pinakamainam na resulta, ilagay ito sa isang mataas na lugar at malapit sa isang bintana."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Aalisin nito ang mga nahanap na channel sa network tuner at muling magsa-scan ng mga bagong channel.\n\nI-verify na naka-on ang network tuner at nakakonekta sa isang pinagmumulan ng TV signal.\n\nKung gumagamit ng over-the-air na antenna, maaaring kailanganin mong ayusin ang pagkakalagay o direksyon nito upang masagap ang karamihan ng mga channel. Para sa mga pinakamainam na resulta, ilagay ito sa mataas na lugar at malapit sa bintana."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Magpatuloy"</item>
<item msgid="235450158666155406">"Kanselahin"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Setup ng TV tuner"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Setup ng USB channel tuner"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Pag-set up ng network channel tuner"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Maaari itong tumagal ng ilang minuto"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Pansamantalang hindi available ang Tuner o ginagamit na ito ng recording."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Walang nakitang Mga Channel"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Hindi nakahanap ng anumang mga channel ang pag-scan. I-verify na nakakonekta ang iyong TV sa isang TV signal source.\n\nKung gumagamit ka ng over-the-air antenna, ayusin ang pagkakalagay o direksyon nito. Para sa mga pinakamainam na resulta, ilagay ito sa mataas na lugar malapit sa isang bintana at mag-scan muli."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Walang nahanap na anumang mga channel noong nag-scan. I-verify na nakasaksak at nakakonekta ang USB tuner sa isang TV signal source.\n\nKung gumagamit ka ng over-the-air antenna, ayusin ang pagkakalagay o direksyon nito. Para sa mga pinakamainam na resulta, ilagay ito sa isang mataas na lugar at malapit sa isang bintana mag-scan muli."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Walang nahanap na channel sa pag-scan. I-verify na naka-on ang network tuner at nakakonekta sa isang pinagmumulan ng TV signal.\n\nKung gumagamit ng over-the-air na antenna, ayusin ang pagkakalagay o direksyon nito. Para sa mga pinakamainam na resulta, ilagay ito sa mataas na lugar at malapit sa bintana at muling mag-scan."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Muling mag-scan"</item>
<item msgid="2092797862490235174">"Tapos Na"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Mag-scan ng mga channel sa TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Setup ng TV Tuner"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Setup ng USB TV Tuner"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Nadiskonekta ang USB TV tuner."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Mag-scan ng mga channel sa TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Setup ng TV Tuner"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Setup ng USB TV Tuner"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Setup ng Network TV Tuner"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Nadiskonekta ang USB TV tuner."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Nadiskonekta ang network tuner."</string>
</resources>
diff --git a/usbtuner-res/values-tr/strings.xml b/usbtuner-res/values-tr/strings.xml
index 29910f9e..5196bfa3 100644
--- a/usbtuner-res/values-tr/strings.xml
+++ b/usbtuner-res/values-tr/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"TV Kanal Ayarlayıcı"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB TV Kanal Ayarlayıcı"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Açık"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Kapalı"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Ağ TV Kanal Ayarlayıcı (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Lütfen işlemin tamamlanmasını bekleyin"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Kanal kaynağınızı seçin"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Sinyal Yok"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> adlı kanala ayarlanamadı"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Kanal ayarlanamadı"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Kanal ayarlayıcı yazılımı yakın zamanda güncellendi. Lütfen kanalları yeniden tarayın."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Sesi etkinleştirmek için sistemin ses ayarlarında surround sesi etkinleştirin"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Ses çalınamıyor. Lütfen başka bir TV deneyin"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Kanal ayarlayıcı kurulumu"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"TV Kanal Ayarlayıcı kurulumu"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB kanal ayarlayıcı kurulumu"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Ağ kanal ayarlayıcı kurulumu"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"TV\'nizin bir TV sinyal kaynağına bağlı olduğunu doğrulayın.\n\nHavadan yayın alan bir anten kullanıyorsanız en çok sayıda kanalı almak için antenin yerini veya yönünü ayarlamanız gerekebilir. En iyi sonucu elde etmek için anteni yüksek ve pencereye yakın bir yere yerleştirin."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"USB kanal ayarlayıcının takılı olduğunu ve bir TV sinyali kaynağına bağlandığını doğrulayın.\n\nHavadan yayın alan bir anten kullanıyorsanız en çok sayıda kanalı almak için antenin yerini veya yönünü ayarlamanız gerekebilir. En iyi sonucu elde etmek için anteni yüksek ve pencereye yakın bir yere yerleştirin."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Ağ kanal ayarlayıcının açık olduğunu ve TV sinyali alabileceği bir kaynağa bağlandığını doğrulayın.\n\nHavadan gelen yayını alacak bir anten kullanıyorsanız en fazla sayıda kanalı almak için antenin yerini veya yönünü ayarlamanız gerekebilir. En iyi sonuçları elde etmek için anteni yüksek ve pencereye yakın bir yere yerleştirin."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Devam"</item>
<item msgid="727245208787621142">"Şimdi değil"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Kanal kurulumu yeniden çalıştırılsın mı?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Bu işlem, TV kanal ayarlayıcının bulduğu kanalları kaldıracak ve tekrar yeni kanallar arayacak.\n\nTV\'nizin bir TV sinyal kaynağına bağlı olduğunu doğrulayın.\n\nHavadan yayın alan bir anten kullanıyorsanız en çok sayıda kanalı almak için antenin yerini veya yönünü ayarlamanız gerekebilir. En iyi sonucu elde etmek için anteni yüksek ve pencereye yakın bir yere yerleştirin."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Bu işlem, USB kanal ayarlayıcıdan bulunan kanalları kaldıracak ve yeni kanallar için tekrar tarama yapacaktır.\n\nUSB kanal ayarlayıcının takılı olduğunu ve bir TV sinyali kaynağına bağlandığını doğrulayın.\n\nHavadan yayın alan bir anten kullanıyorsanız en çok sayıda kanalı almak için antenin yerini veya yönünü ayarlamanız gerekebilir. En iyi sonucu elde etmek için anteni yüksek ve pencereye yakın bir yere yerleştirin."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Bu işlem, bulunan kanalları ağ kanal ayarlayıcıdan kaldıracak ve yeni kanalların bulunması için tekrar tarama yapacak.\n\nAğ kanal ayarlayıcının açık olduğunu ve TV sinyali alabileceği bir kaynağa bağlandığını doğrulayın.\n\nHavadan gelen yayını alacak bir anten kullanıyorsanız en fazla sayıda kanalı almak için antenin yerini veya yönünü ayarlamanız gerekebilir. En iyi sonucu elde etmek için anteni yüksek ve pencereye yakın bir yere yerleştirin."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Devam"</item>
<item msgid="235450158666155406">"İptal"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"TV kanal ayarlayıcı kurulumu"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB kanal ayarlayıcı kurulumu"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Ağ kanal ayarlayıcı kurulumu"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Bu işlem birkaç dakika sürebilir"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Kanal ayarlayıcı geçici olarak kullanılamıyor veya şu anda kayıt yapmak için kullanılıyor."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Hiçbir kanal bulunamadı"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Tarama işleminde hiçbir kanal bulunamadı. TV\'nizin bir TV sinyal kaynağına bağlı olduğunu doğrulayın.\n\nHavadan yayın alan bir anten kullanıyorsanız yerini veya yönünü ayarlayın. En iyi sonucu elde etmek için anteni yüksek ve pencereye yakın bir yere yerleştirerek tekrar tarayın."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Tarama işlemi herhangi bir kanal bulamadı. USB kanal ayarlayıcının takılı olduğunu ve bir TV sinyali kaynağına bağlandığını doğrulayın.\n\nHavadan yayın alan bir anten kullanıyorsanız yerini veya yönünü ayarlayın. En iyi sonucu elde etmek için anteni yüksek ve pencereye yakın bir yere yerleştirerek tekrar tarayın."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Taramada herhangi bir kanal bulunamadı. Ağ kanal ayarlayıcının açık olduğunu ve TV sinyali alabileceği bir kaynağa bağlandığını doğrulayın.\n\nHavadan gelen yayınları alacak bir anten kullanıyorsanız antenin yerini veya yönünü ayarlayın. En iyi sonucu elde etmek için anteni yüksek ve pencereye yakın bir yere yerleştirin."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Yeniden tara"</item>
<item msgid="2092797862490235174">"Bitti"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"TV kanallarını tarayın"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV Kanal Ayarlayıcı kurulumu"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV Kanal Ayarlayıcı kurulumu"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB TV kanal ayarlayıcı bağlantısı kesildi."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"TV kanallarını tarayın"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV Kanal Ayarlayıcı kurulumu"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV Kanal Ayarlayıcı kurulumu"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Ağ TV Kanal Ayarlayıcı kurulumu"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB TV kanal ayarlayıcı bağlantısı kesildi."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Ağ kanal ayarlayıcı bağlantısı kesildi."</string>
</resources>
diff --git a/usbtuner-res/values-uk/strings.xml b/usbtuner-res/values-uk/strings.xml
index cf7cc85e..50c84efc 100644
--- a/usbtuner-res/values-uk/strings.xml
+++ b/usbtuner-res/values-uk/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"ТВ-тюнер"</string>
<string name="ut_app_name" msgid="8557698013780762454">"ТВ-тюнер USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Увімкнути"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Вимкнути"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Мережевий ТВ-тюнер (БЕТА-ВЕРСІЯ)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Зачекайте, доки завершиться пошук"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Виберіть джерело каналу"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Немає сигналу"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Не вдалося налаштувати канал <xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Не вдалося налаштувати"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Програмне забезпечення тюнера нещодавно оновлено. Проскануйте канали знову."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Увімкнути об’ємний звук у налаштуваннях системи, щоб слухати аудіо"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Не вдається відтворити відео. Спробуйте на іншому телевізорі"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Налаштування тюнера"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Налаштування ТВ-тюнера"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Налаштування USB-тюнера"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Налаштування мережевого тюнера"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Переконайтеся, що ви під’єднали телевізор до джерела вхідного телевізійного сигналу.\n\nЯкщо ви користуєтесь ефірною антеною, змініть її положення,щоб знайти більше каналів. Розмістіть антену вище та біля вікна."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Переконайтеся, що ви підключили USB-тюнер і під’єднали джерело вхідного телевізійного сигналу.\n\nЯкщо ви користуєтесь ефірною антеною, змініть її положення, щоб знайти більше каналів. Розмістіть антену вище та біля вікна."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Переконайтеся, що мережевий тюнер увімкнено та під’єднано до джерела телевізійного сигналу.\n\nЯкщо у вас ефірна антена, змініть її положення. Розмістіть антену вище та біля вікна й повторіть спробу."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Продовжити"</item>
<item msgid="727245208787621142">"Не зараз"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Відновити налаштування каналу?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Канали, знайдені за допомогою ТВ-тюнера, буде видалено. Пошук почнеться знову.\n\nПереконайтеся, що ви під’єднали телевізор до джерела вхідного телевізійного сигналу.\n\nЯкщо ви користуєтесь ефірною антеною, змініть її положення, щоб знайти більше каналів. Розмістіть антену вище та біля вікна й повторіть спробу."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Канали, знайдені за допомогою USB-тюнера, буде видалено. Пошук почнеться знову.\n\nПереконайтеся, що ви підключили USB-тюнер і під’єднали джерело вхідного телевізійного сигналу.\n\nЯкщо ви користуєтесь ефірною антеною, змініть її положення, щоб знайти більше каналів. Розмістіть антену вище та біля вікна."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Канали, знайдені мережевим тюнером, буде видалено. Пошук почнеться знову.\n\nПереконайтеся, що мережевий тюнер увімкнено та під’єднано до джерела телевізійного сигналу.\n\nЯкщо у вас ефірна антена, змініть її положення. Розмістіть антену вище та біля вікна й повторіть спробу."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Продовжити"</item>
<item msgid="235450158666155406">"Скасувати"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Налаштування ТВ-тюнера"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Налаштування USB-тюнера"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Налаштування мережевого тюнера"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Це може зайняти декілька хвилин"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Тюнер тимчасово недоступний або вже використовується для запису."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -82,12 +82,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Канали не знайдено"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Канали не знайдено. Переконайтеся, що ви під’єднали телевізор до джерела вхідного телевізійного сигналу.\n\nЯкщо ви користуєтесь ефірною антеною, змініть її положення. Розмістіть антену вище та біля вікна й повторіть спробу."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Канали не знайдено. Переконайтеся, що ви підключили USB-тюнер і під’єднали джерело вхідного телевізійного сигналу.\n\nЯкщо ви користуєтесь ефірною антеною, змініть її положення. Розмістіть антену вище та біля вікна й повторіть спробу."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Каналів не знайдено. Переконайтеся, що мережевий тюнер увімкнено та під’єднано до джерела телевізійного сигналу.\n\nЯкщо у вас ефірна антена, змініть її положення. Розмістіть антену вище та біля вікна й повторіть спробу."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Шукати знову"</item>
<item msgid="2092797862490235174">"Готово"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Пошук телевізійних каналів"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Налаштування ТВ-тюнера"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Налаштування ТВ-тюнера USB"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"ТВ-тюнер USB від’єднано."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Пошук телевізійних каналів"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Налаштування ТВ-тюнера"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Налаштування ТВ-тюнера USB"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Налаштування мережевого ТВ-тюнера"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"ТВ-тюнер USB від’єднано."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Мережевий тюнер від’єднано."</string>
</resources>
diff --git a/usbtuner-res/values-ur-rPK/strings.xml b/usbtuner-res/values-ur-rPK/strings.xml
new file mode 100644
index 00000000..49dc9e34
--- /dev/null
+++ b/usbtuner-res/values-ur-rPK/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"‏TV ٹیونر"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"‏USB TV ٹیونر"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"‏نیٹ ورک TV ٹیونر (بی ٹا)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"براہ کرم کارروائی ختم ہونے کا انتظار کریں"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"ٹیونر سافٹ ویئر حال ہی میں اپ ڈیٹ کیا گیا ہے۔ براہ کرم چینلز کو دوبارہ اسکین کریں۔"</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"آڈیو کو فعال کرنے کیلئے سسٹم کی آواز کی ترتیبات میں محیط آواز فعال کریں"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"آڈیو نہیں چل رہی۔ براہ کرم کوئی اور ٹی وی آزمائیں"</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"چینل ٹیونر سیٹ اپ"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"‏TV ٹیونر سیٹ اپ"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"‏USB چینل ٹیونر سیٹ اپ"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"نیٹ ورک ٹیونر سیٹ اپ"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"‏اپنے TV کے کسی TV سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو زیادہ تر چینلز موصول کرنے کیلئے آپ کو اس کا مقام یا سمت ایڈجسٹ کرنے کی ضرورت پیش آ سکتی ہے۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں۔"</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"‏USB ٹیونر کے پلگ ان ہونے اور TV سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو زیادہ تر چینلز موصول کرنے کیلئے آپ کو اس کا مقام یا سمت ایڈجسٹ کرنے کی ضرورت پیش آ سکتی ہے۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں۔"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"‏نیٹ ورک ٹیونر کے آن ہونے اور TV سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو زیادہ تر چینلز موصول کرنے کیلئے آپ کو اس کا مقام یا سمت ایڈجسٹ کرنے کی ضرورت پیش آ سکتی ہے۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں۔"</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"جاری رکھیں"</item>
+ <item msgid="727245208787621142">"ابھی نہیں"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"چینل سیٹ اپ دوبارہ چلائیں؟"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"‏یہ TV ٹیونر سے ملے چینلز ہٹا دے گا اور دوبارہ نئے چینلز کیلئے اسکین کرے گا۔\n\nاپنے TV کے کسی سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو زیادہ تر چینلز موصول کرنے کیلئے آپ کو اس کا مقام یا سمت ایڈجسٹ کرنے کی ضرورت پیش آ سکتی ہے۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں۔"</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"‏یہ USB ٹیونر سے ملے چینلز ہٹا دے گا اور دوبارہ نئے چینلز کیلئے اسکین کرے گا۔\n\nTV ٹیونر کے پلگ ان ہونے اور سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو زیادہ تر چینلز موصول کرنے کیلئے آپ کو اس کا مقام یا سمت ایڈجسٹ کرنے کی ضرورت پیش آ سکتی ہے۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں۔"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"‏یہ نیٹ ورک ٹیونر سے ملنے والے چیلنز ہٹا دے گا اور دوبارہ نئے چینلز کیلئے اسکین کرے گا۔\n\nTV ٹیونر کے آن ہونے اور سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں، تو زیادہ تر چینلز موصول کرنے کیلئے آپ کو اس کی مقام بندی یا سمت ایڈجسٹ کرنے کی ضرورت پیش آ سکتی ہے۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں۔"</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"جاری رکھیں"</item>
+ <item msgid="235450158666155406">"منسوخ کریں"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"کنکشن کی قسم منتخب کریں"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"اگر ٹیونر سے کوئی بیرونی انٹینا منسلک ہے تو انٹینا کا انتخاب کریں۔ اگر آپ کے چینلز کسی کیبل سروس فراہم کنندہ کی طرف سے موصول ہوتے ہیں تو کیبل کا انتخاب کریں۔ اگر آپ پُر یقین نہیں ہیں تو دونوں اقسام کو اسکین کیا جائے گا، مگر اس میں زیادہ وقت لگ سکتا ہے۔"</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"انٹینا"</item>
+ <item msgid="2670079958754180142">"کیبل"</item>
+ <item msgid="36774059871728525">"یقین نہیں ہے"</item>
+ <item msgid="6881204453182153978">"صرف ڈیولپمنٹ"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"‏TV ٹیونر سیٹ اپ"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"‏USB چینل ٹیونر سیٹ اپ"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"نیٹ ورک چینل ٹیونر سیٹ اپ"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"اس میں کئی منٹ لگ سکتے ہیں"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ٹیونر عارضی طور پر غیر دستیاب ہے یا پہلے سے ریکارڈنگ کی وجہ سے استعمال ہو گیا ہے۔"</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">‏%1$d چینلز ملے</item>
+ <item quantity="one">‏%1$d چینل ملا</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"چینل اسکین روکیں"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">‏‎%1$d چینلز ملے</item>
+ <item quantity="one">‏%1$d چینل ملا</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">‏خوب! چینل اسکین کے دوران ‎%1$d چینلز ملے۔ اگر یہ ٹھیک نہیں لگ رہا تو انٹینا کی پوزیشن ایڈجسٹ کرنے کی کوشش کریں اور دوبارہ اسکین کریں۔</item>
+ <item quantity="one">‏خوب! چینل اسکین کے دوران ‎%1$d چینل ملا۔ اگر یہ ٹھیک نہیں لگ رہا تو انٹینا کی پوزیشن ایڈجسٹ کرنے کی کوشش کریں اور دوبارہ اسکین کریں۔</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"ہو گیا"</item>
+ <item msgid="2480490326672924828">"دوبارہ اسکین کریں"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"کوئی چینلز نہیں ملے"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"‏اسکین سے کوئی چینلز نہیں ملے۔ اپنے TV کے ایک TV سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو اس کا مقام یا سمت ایڈجسٹ کریں۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں اور دوبارہ اسکین کریں۔"</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"‏اسکین سے کوئی چینلز نہیں ملے۔ USB ٹیونر کے پلگ ان ہونے اور TV سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو اس کا مقام یا سمت ایڈجسٹ کریں۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں اور دوبارہ اسکین کریں۔"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"‏اسکین سے کوئی چینلز نہیں ملے۔ توثیق کریں کہ نیٹ ورک ٹیونر آن ہے اور TV سگنل ماخذ سے منسلک ہے۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں، تو اس کا مقام یا سمت ایڈجسٹ کریں۔ بہترین نتائج کیلئے، اسے اونچی جگہ اور کھڑکی کے قریب رکھیں اور دوبارہ اسکین کریں۔"</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"دوبارہ اسکین کریں"</item>
+ <item msgid="2092797862490235174">"ہو گیا"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"‏TV چینلز کے لیے اسکین کریں"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"‏TV ٹیونر سیٹ اپ"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"‏USB TV ٹیونر سیٹ اپ"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"‏نیٹ ورک TV ٹیونر سیٹ اپ"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"‏USB TV ٹیونر غیر منسلک ہے۔"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"نیٹ ورک ٹیونر غیر منسلک ہے۔"</string>
+</resources>
diff --git a/usbtuner-res/values-ur/strings.xml b/usbtuner-res/values-ur/strings.xml
deleted file mode 100644
index 68c85d05..00000000
--- a/usbtuner-res/values-ur/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"‏TV ٹیونر"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"‏USB TV ٹیونر"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"آن"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"آف"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"براہ کرم کارروائی ختم ہونے کا انتظار کریں"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"اپنے چینل کا ماخذ منتخب کریں"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"کوئی سگنل نہیں ہے"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"<xliff:g id="CHANNEL_NAME">%s</xliff:g> پر ٹیون ہونے میں ناکام ہوگیا"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"ٹیون کرنے میں ناکام ہو گیا"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"ٹیونر سافٹ ویئر حال ہی میں اپ ڈیٹ کیا گیا ہے۔ براہ کرم چینلز کو دوبارہ اسکین کریں۔"</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"آڈیو کو فعال کرنے کیلئے سسٹم کی آواز کی ترتیبات میں محیط آواز فعال کریں"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"چینل ٹیونر سیٹ اپ"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"‏TV ٹیونر سیٹ اپ"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"‏USB چینل ٹیونر سیٹ اپ"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"‏اپنے TV کے کسی TV سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو زیادہ تر چینلز موصول کرنے کیلئے آپ کو اس کا مقام یا سمت ایڈجسٹ کرنے کی ضرورت پیش آ سکتی ہے۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں۔"</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"‏USB ٹیونر کے پلگ ان ہونے اور TV سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو زیادہ تر چینلز موصول کرنے کیلئے آپ کو اس کا مقام یا سمت ایڈجسٹ کرنے کی ضرورت پیش آ سکتی ہے۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں۔"</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"جاری رکھیں"</item>
- <item msgid="727245208787621142">"ابھی نہیں"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"چینل سیٹ اپ دوبارہ چلائیں؟"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"‏یہ TV ٹیونر سے ملے چینلز ہٹا دے گا اور دوبارہ نئے چینلز کیلئے اسکین کرے گا۔\n\nاپنے TV کے کسی سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو زیادہ تر چینلز موصول کرنے کیلئے آپ کو اس کا مقام یا سمت ایڈجسٹ کرنے کی ضرورت پیش آ سکتی ہے۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں۔"</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"‏یہ USB ٹیونر سے ملے چینلز ہٹا دے گا اور دوبارہ نئے چینلز کیلئے اسکین کرے گا۔\n\nTV ٹیونر کے پلگ ان ہونے اور سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو زیادہ تر چینلز موصول کرنے کیلئے آپ کو اس کا مقام یا سمت ایڈجسٹ کرنے کی ضرورت پیش آ سکتی ہے۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں۔"</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"جاری رکھیں"</item>
- <item msgid="235450158666155406">"منسوخ کریں"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"کنکشن کی قسم منتخب کریں"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"اگر ٹیونر سے کوئی بیرونی انٹینا منسلک ہے تو انٹینا کا انتخاب کریں۔ اگر آپ کے چینلز کسی کیبل سروس فراہم کنندہ کی طرف سے موصول ہوتے ہیں تو کیبل کا انتخاب کریں۔ اگر آپ پُر یقین نہیں ہیں تو دونوں اقسام کو اسکین کیا جائے گا، مگر اس میں زیادہ وقت لگ سکتا ہے۔"</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"انٹینا"</item>
- <item msgid="2670079958754180142">"کیبل"</item>
- <item msgid="36774059871728525">"یقین نہیں ہے"</item>
- <item msgid="6881204453182153978">"صرف ڈیولپمنٹ"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"‏TV ٹیونر سیٹ اپ"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"‏USB چینل ٹیونر سیٹ اپ"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"اس میں کئی منٹ لگ سکتے ہیں"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"ٹیونر عارضی طور پر غیر دستیاب ہے یا پہلے سے ریکارڈنگ کی وجہ سے استعمال ہو گیا ہے۔"</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">‏%1$d چینلز ملے</item>
- <item quantity="one">‏%1$d چینل ملا</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"چینل اسکین روکیں"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">‏‎%1$d چینلز ملے</item>
- <item quantity="one">‏%1$d چینل ملا</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">‏خوب! چینل اسکین کے دوران ‎%1$d چینلز ملے۔ اگر یہ ٹھیک نہیں لگ رہا تو انٹینا کی پوزیشن ایڈجسٹ کرنے کی کوشش کریں اور دوبارہ اسکین کریں۔</item>
- <item quantity="one">‏خوب! چینل اسکین کے دوران ‎%1$d چینل ملا۔ اگر یہ ٹھیک نہیں لگ رہا تو انٹینا کی پوزیشن ایڈجسٹ کرنے کی کوشش کریں اور دوبارہ اسکین کریں۔</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"ہو گیا"</item>
- <item msgid="2480490326672924828">"دوبارہ اسکین کریں"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"کوئی چینلز نہیں ملے"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"‏اسکین سے کوئی چینلز نہیں ملے۔ اپنے TV کے ایک TV سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو اس کا مقام یا سمت ایڈجسٹ کریں۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں اور دوبارہ اسکین کریں۔"</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"‏اسکین سے کوئی چینلز نہیں ملے۔ USB ٹیونر کے پلگ ان ہونے اور TV سگنل ماخذ سے منسلک ہونے کی توثیق کریں۔\n\nاگر وائرلیس نیٹ ورک کنکشن انٹینا استعمال کر رہے ہیں تو اس کا مقام یا سمت ایڈجسٹ کریں۔ بہترین نتائج کیلئے اسے اونچی جگہ اور کھڑکی کے پاس رکھیں اور دوبارہ اسکین کریں۔"</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"دوبارہ اسکین کریں"</item>
- <item msgid="2092797862490235174">"ہو گیا"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"‏TV چینلز کے لیے اسکین کریں"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"‏TV ٹیونر سیٹ اپ"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"‏USB TV ٹیونر سیٹ اپ"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"‏USB TV ٹیونر غیر منسلک ہے۔"</string>
-</resources>
diff --git a/usbtuner-res/values-uz-rUZ/strings.xml b/usbtuner-res/values-uz-rUZ/strings.xml
new file mode 100644
index 00000000..2709dec0
--- /dev/null
+++ b/usbtuner-res/values-uz-rUZ/strings.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="bt_app_name" msgid="5515382901862469770">"TV-tyuner"</string>
+ <string name="ut_app_name" msgid="8557698013780762454">"USB TV-tyuner"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Tarmoq TV-tyuneri (BETA)"</string>
+ <string name="ut_setup_cancel" msgid="5318292052302751909">"Iltimos, jarayon tugashini kuting"</string>
+ <string name="ut_rescan_needed" msgid="2273655435759849436">"Tyunerning dasturiy ta’minoti yaqinda yangilandi. Kanallarni qaytadan qidiring."</string>
+ <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Audioni yoqish uchun tizim ovozi sozlamalari orqali qamrovli ovozni yoqing"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Audioni ijro ettirib bo‘lmadi. Boshqa kanalni sinab ko‘ring."</string>
+ <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Tyunerni sozlash"</string>
+ <string name="bt_setup_new_title" msgid="8447554965697762891">"TV-tyunerni sozlash"</string>
+ <string name="ut_setup_new_title" msgid="2118880835101453405">"USB-tyunerni sozlash"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Tarmoq tyunerini sozlash"</string>
+ <string name="bt_setup_new_description" msgid="256690722062003128">"Televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, ko‘proq kanal topilishi uchun uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating."</string>
+ <string name="ut_setup_new_description" msgid="2610122936163002137">"USB-tyuner suqilgan hamda televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, ko‘proq kanal topilishi uchun uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Tarmoq tyuneri yoqilgan hamda televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, ko‘proq kanal topilishi uchun uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating."</string>
+ <string-array name="ut_setup_new_choices">
+ <item msgid="8728069574888601683">"Davom etish"</item>
+ <item msgid="727245208787621142">"Hozir emas"</item>
+ </string-array>
+ <string name="bt_setup_again_title" msgid="884713873101099572">"Kanallar qaytadan sozlansinmi?"</string>
+ <string name="bt_setup_again_description" msgid="1247792492948741337">"Buning natijasida TV-tyuner orqali topilgan kanallar o‘chirib tashlanadi va kanallar boshqatdan qidiriladi.\n\nTelevizor signal manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating hamda qaytadan qidiring."</string>
+ <string name="ut_setup_again_description" msgid="7837706010887799255">"Buning natijasida USB-tyuner orqali topilgan kanallar o‘chirib tashlanadi va kanallar boshqatdan qidiriladi.\n\nUSB-tyuner suqilgan hamda televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating hamda qaytadan qidiring."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Buning natijasida tarmoq tyuneri orqali topilgan kanallar o‘chirib tashlanadi va kanallar boshqatdan qidiriladi.\n\nTarmoq tyuneri yoqilgan hamda televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating hamda qaytadan qidiring."</string>
+ <string-array name="ut_setup_again_choices">
+ <item msgid="2557527790311851317">"Davom etish"</item>
+ <item msgid="235450158666155406">"Bekor qilish"</item>
+ </string-array>
+ <string name="ut_connection_title" msgid="8435949189164677545">"Aloqa turini tanlang"</string>
+ <string name="ut_connection_description" msgid="7234582943233286192">"Agar tyunerga tashqi antenna ulangan bo‘lsa, “Antenna” variantini tanlang. Agar kanallar kabel televideniye ta’minotchisidan olinadigan bo‘lsa, “Kabel TV” variantini tanlang. Agar qaysi biri ekanligini aniq bilmasangiz, har ikkala tur ham qidiriladi, shuning uchun uzoqroq vaqt ketishi mumkin."</string>
+ <string-array name="ut_connection_choices">
+ <item msgid="1499878461856892555">"Antenna"</item>
+ <item msgid="2670079958754180142">"Kabel"</item>
+ <item msgid="36774059871728525">"Aniq bilmayman"</item>
+ <item msgid="6881204453182153978">"Faqat dasturchilar uchun"</item>
+ </string-array>
+ <string name="bt_channel_scan" msgid="3291924771702347469">"TV-tyunerni sozlash"</string>
+ <string name="ut_channel_scan" msgid="6100090671500464604">"USB-tyunerni sozlash"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Tarmoq tyuneri kanallarini sozlash"</string>
+ <string name="ut_channel_scan_time" msgid="1844845425359642393">"Bu bir necha daqiqa vaqt olishi mumkin"</string>
+ <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tyunerdan vaqtinchalik foydalanib bo‘lmaydi yoki allaqachon yozib olishda foydalanilmoqda."</string>
+ <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
+ <item quantity="other">%1$d ta kanal topildi</item>
+ <item quantity="one">%1$d ta kanal topildi</item>
+ </plurals>
+ <string name="ut_stop_channel_scan" msgid="566811986747774193">"KANAL QIDIRUVINI TO‘XTATISH"</string>
+ <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
+ <item quantity="other">%1$d ta kanal topildi</item>
+ <item quantity="one">%1$d ta kanal topildi</item>
+ </plurals>
+ <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
+ <item quantity="other">Ajoyib! Kanal qidirish natijasida %1$d ta kanal topildi. Agar yanada ko‘proq kanal topilishi kerak deb hisoblasangiz, antenna joylashuvini sozlang va qaytadan qidiring.</item>
+ <item quantity="one">Ajoyib! Kanal qidirish natijasida %1$d ta kanal topildi. Agar yanada ko‘proq kanal topilishi kerak deb hisoblasangiz, antenna joylashuvini sozlang va qaytadan qidiring.</item>
+ </plurals>
+ <string-array name="ut_result_found_choices">
+ <item msgid="3220617441427115421">"Tayyor"</item>
+ <item msgid="2480490326672924828">"Yana qidirish"</item>
+ </string-array>
+ <string name="ut_result_not_found_title" msgid="4649533929056795595">"Hech qanday kanal topilmadi"</string>
+ <string name="bt_result_not_found_description" msgid="7378208337325024042">"Qidiruv natijasida hech qanday kanal topilmadi. Televizor signal manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating hamda qaytadan qidiring."</string>
+ <string name="ut_result_not_found_description" msgid="1080746285957681414">"Qidiruv natijasida hech qanday kanal topilmadi. USB-tyuner suqilgan hamda televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating hamda qaytadan qidiring."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Qidiruv natijasida hech qanday kanal topilmadi. Tarmoq tyuneri yoqilgan hamda televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating hamda qaytadan qidiring."</string>
+ <string-array name="ut_result_not_found_choices">
+ <item msgid="5436884968471542030">"Yana qidirish"</item>
+ <item msgid="2092797862490235174">"Tayyor"</item>
+ </string-array>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Telekanallarni qidiring"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"TV-tyunerni sozlash"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB TV-tyunerni sozlang"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Tarmoq TV-tyunerini sozlash"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB-tyuner o‘chirib qo‘yildi."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Tarmoq tyuneri uzib qo‘yildi."</string>
+</resources>
diff --git a/usbtuner-res/values-uz/strings.xml b/usbtuner-res/values-uz/strings.xml
deleted file mode 100644
index 9aefd57b..00000000
--- a/usbtuner-res/values-uz/strings.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bt_app_name" msgid="5515382901862469770">"TV-tyuner"</string>
- <string name="ut_app_name" msgid="8557698013780762454">"USB TV-tyuner"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Yoqish"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"O‘chirib qo‘yish"</string>
- <string name="ut_setup_cancel" msgid="5318292052302751909">"Iltimos, jarayon tugashini kuting"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Kanal manbasini tanlang"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Signal yo‘q"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"“<xliff:g id="CHANNEL_NAME">%s</xliff:g>” kanaliga sozlab bo‘lmadi"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Sozlab bo‘lmadi"</string>
- <string name="ut_rescan_needed" msgid="2273655435759849436">"Tyunerning dasturiy ta’minoti yaqinda yangilandi. Kanallarni qaytadan qidiring."</string>
- <string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Audioni yoqish uchun tizim ovozi sozlamalari orqali qamrovli ovozni yoqing"</string>
- <string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Tyunerni sozlash"</string>
- <string name="bt_setup_new_title" msgid="8447554965697762891">"TV-tyunerni sozlash"</string>
- <string name="ut_setup_new_title" msgid="2118880835101453405">"USB-tyunerni sozlash"</string>
- <string name="bt_setup_new_description" msgid="256690722062003128">"Televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, ko‘proq kanal topilishi uchun uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating."</string>
- <string name="ut_setup_new_description" msgid="2610122936163002137">"USB-tyuner suqilgan hamda televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, ko‘proq kanal topilishi uchun uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating."</string>
- <string-array name="ut_setup_new_choices">
- <item msgid="8728069574888601683">"Davom etish"</item>
- <item msgid="727245208787621142">"Hozir emas"</item>
- </string-array>
- <string name="bt_setup_again_title" msgid="884713873101099572">"Kanallar qaytadan sozlansinmi?"</string>
- <string name="bt_setup_again_description" msgid="1247792492948741337">"Buning natijasida TV-tyuner orqali topilgan kanallar o‘chirib tashlanadi va kanallar boshqatdan qidiriladi.\n\nTelevizor signal manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating hamda qaytadan qidiring."</string>
- <string name="ut_setup_again_description" msgid="7837706010887799255">"Buning natijasida USB-tyuner orqali topilgan kanallar o‘chirib tashlanadi va kanallar boshqatdan qidiriladi.\n\nUSB-tyuner suqilgan hamda televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating hamda qaytadan qidiring."</string>
- <string-array name="ut_setup_again_choices">
- <item msgid="2557527790311851317">"Davom etish"</item>
- <item msgid="235450158666155406">"Bekor qilish"</item>
- </string-array>
- <string name="ut_connection_title" msgid="8435949189164677545">"Aloqa turini tanlang"</string>
- <string name="ut_connection_description" msgid="7234582943233286192">"Agar tyunerga tashqi antenna ulangan bo‘lsa, “Antenna” variantini tanlang. Agar kanallar kabel televideniye ta’minotchisidan olinadigan bo‘lsa, “Kabel TV” variantini tanlang. Agar qaysi biri ekanligini aniq bilmasangiz, har ikkala tur ham qidiriladi, shuning uchun uzoqroq vaqt ketishi mumkin."</string>
- <string-array name="ut_connection_choices">
- <item msgid="1499878461856892555">"Antenna"</item>
- <item msgid="2670079958754180142">"Kabel"</item>
- <item msgid="36774059871728525">"Aniq bilmayman"</item>
- <item msgid="6881204453182153978">"Faqat dasturchilar uchun"</item>
- </string-array>
- <string name="bt_channel_scan" msgid="3291924771702347469">"TV-tyunerni sozlash"</string>
- <string name="ut_channel_scan" msgid="6100090671500464604">"USB-tyunerni sozlash"</string>
- <string name="ut_channel_scan_time" msgid="1844845425359642393">"Bu bir necha daqiqa vaqt olishi mumkin"</string>
- <string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Tyunerdan vaqtinchalik foydalanib bo‘lmaydi yoki allaqachon yozib olishda foydalanilmoqda."</string>
- <plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
- <item quantity="other">%1$d ta kanal topildi</item>
- <item quantity="one">%1$d ta kanal topildi</item>
- </plurals>
- <string name="ut_stop_channel_scan" msgid="566811986747774193">"KANAL QIDIRUVINI TO‘XTATISH"</string>
- <plurals name="ut_result_found_title" formatted="false" msgid="1448908152026339099">
- <item quantity="other">%1$d ta kanal topildi</item>
- <item quantity="one">%1$d ta kanal topildi</item>
- </plurals>
- <plurals name="ut_result_found_description" formatted="false" msgid="4132691388395648565">
- <item quantity="other">Ajoyib! Kanal qidirish natijasida %1$d ta kanal topildi. Agar yanada ko‘proq kanal topilishi kerak deb hisoblasangiz, antenna joylashuvini sozlang va qaytadan qidiring.</item>
- <item quantity="one">Ajoyib! Kanal qidirish natijasida %1$d ta kanal topildi. Agar yanada ko‘proq kanal topilishi kerak deb hisoblasangiz, antenna joylashuvini sozlang va qaytadan qidiring.</item>
- </plurals>
- <string-array name="ut_result_found_choices">
- <item msgid="3220617441427115421">"Tayyor"</item>
- <item msgid="2480490326672924828">"Yana qidirish"</item>
- </string-array>
- <string name="ut_result_not_found_title" msgid="4649533929056795595">"Hech qanday kanal topilmadi"</string>
- <string name="bt_result_not_found_description" msgid="7378208337325024042">"Qidiruv natijasida hech qanday kanal topilmadi. Televizor signal manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating hamda qaytadan qidiring."</string>
- <string name="ut_result_not_found_description" msgid="1080746285957681414">"Qidiruv natijasida hech qanday kanal topilmadi. USB-tyuner suqilgan hamda televizor signali manbasiga ulangan ekanligini tekshiring.\n\nAgar havo orqali to‘lqin tutuvchi antennadan foydalanayotgan bo‘lsangiz, uning joyi va yo‘nalishini sozlang. Eng yaxshi natijaga erishish uchun uni yuqoriroq va oynaga yaqin joyga o‘rnating hamda qaytadan qidiring."</string>
- <string-array name="ut_result_not_found_choices">
- <item msgid="5436884968471542030">"Yana qidirish"</item>
- <item msgid="2092797862490235174">"Tayyor"</item>
- </string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Telekanallarni qidiring"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"TV-tyunerni sozlash"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB TV-tyunerni sozlang"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB-tyuner o‘chirib qo‘yildi."</string>
-</resources>
diff --git a/usbtuner-res/values-vi/strings.xml b/usbtuner-res/values-vi/strings.xml
index 605234e4..6e6cef72 100644
--- a/usbtuner-res/values-vi/strings.xml
+++ b/usbtuner-res/values-vi/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Bộ dò TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Bộ dò TV USB"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Bật"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Tắt"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Bộ dò TV mạng (BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Vui lòng đợi để hoàn tất xử lý"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Chọn nguồn kênh của bạn"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Không có tín hiệu"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Dò tới <xliff:g id="CHANNEL_NAME">%s</xliff:g> không thành công"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Dò không thành công"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Phần mềm bộ dò đã được cập nhật gần đây. Vui lòng quét lại các kênh."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Bật tính năng âm thanh vòm trong cài đặt âm thanh hệ thống để bật âm thanh"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Không thể phát âm thanh. Vui lòng thử TV khác"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Thiết lập bộ dò kênh"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Thiết lập bộ dò TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Thiết lập bộ dò kênh USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Thiết lập bộ dò mạng"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Hãy xác minh rằng TV của bạn đã được kết nối với nguồn tín hiệu TV.\n\nNếu sử dụng ăng-ten không dây thì bạn có thể cần phải điều chỉnh vị trí hoặc hướng của ăng-ten đó để nhận nhiều kênh nhất. Để có kết quả tốt nhất, hãy đặt ăng-ten lên cao và gần cửa sổ."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Xác minh rằng bộ dò USB đã được cắm và được kết nối với nguồn tín hiệu TV.\n\nNếu sử dụng ăng-ten không dây, có thể bạn cần phải điều chỉnh vị trí hoặc hướng của ăng-ten đó để nhận được nhiều kênh nhất. Để có kết quả tốt nhất, hãy đặt ăng-ten lên cao và gần cửa sổ."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Hãy xác minh là bộ dò mạng đã được bật nguồn và kết nối với một nguồn tín hiệu TV.\n\nNếu sử dụng ăng-ten không dây, hãy điều chỉnh vị trí hoặc hướng của ăng-ten để nhận hầu hết kênh. Để có kết quả tốt nhất, hãy đặt ăng-ten ở vị trí cao và gần cửa sổ."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Tiếp tục"</item>
<item msgid="727245208787621142">"Không phải bây giờ"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Chạy lại quá trình thiết lập kênh?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Điều này sẽ xóa các kênh được tìm thấy khỏi bộ dò TV và quét các kênh mới lần nữa.\n\nHãy xác minh rằng TV của bạn đã được kết nối với nguồn tín hiệu TV.\n\nNếu sử dụng ăng-ten không dây thì bạn có thể cần phải điều chỉnh vị trí hoặc hướng của ăng-ten đó để nhận nhiều kênh nhất. Để có kết quả tốt nhất, hãy đặt ăng-ten lên cao và gần cửa sổ."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Quá trình này sẽ xóa các kênh bộ dò USB đã tìm thấy và quét lại để tìm các kênh mới.\n\nHãy xác minh rằng bộ dò USB đã được cắm và kết nối với nguồn tín hiệu TV.\n\nNếu sử dụng ăng-ten không dây, bạn có thể cần phải điều chỉnh vị trí hoặc hướng của ăng-ten đó để nhận được nhiều kênh nhất. Để có kết quả tốt nhất, hãy đặt ăng-ten lên cao và gần cửa sổ."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Điều này sẽ xóa các kênh được tìm thấy từ bộ dò mạng và quét các kênh mới một lần nữa.\n\nHãy xác minh là bộ dò mạng đã được bật nguồn và kết nối với một nguồn tín hiệu TV.\n\nNếu sử dụng ăng-ten không dây, hãy điều chỉnh vị trí hoặc hướng của ăng-ten để nhận hầu hết kênh. Để có kết quả tốt nhất, hãy đặt ăng-ten ở vị trí cao và gần cửa sổ."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Tiếp tục"</item>
<item msgid="235450158666155406">"Hủy"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Thiết lập bộ dò TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Thiết lập bộ dò kênh USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Thiết lập bộ do kênh mạng"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Quá trình này có thể mất vài phút"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Bộ dò tạm thời không có sẵn hoặc đã được sử dụng để ghi."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Không tìm thấy kênh nào"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Quá trình quét không tìm thấy bất kỳ kênh nào. Hãy xác minh rằng TV của bạn đã được kết nối với nguồn tín hiệu TV.\n\nNếu sử dụng ăng-ten không dây, hãy điều chỉnh vị trí hoặc hướng của ăng-ten đó. Để có kết quả tốt nhất, hãy đặt ăng-ten lên cao và gần cửa sổ rồi quét lại."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Quá trình quét không tìm thấy bất kỳ kênh nào. Hãy xác minh rằng bộ dò USB đã được cắm và kết nối với nguồn tín hiệu TV.\n\nNếu sử dụng ăng-ten không dây, hãy điều chỉnh vị trí hoặc hướng của ăng-ten đó. Để có kết quả tốt nhất, hãy đặt ăng-ten lên cao và gần cửa sổ rồi quét lại."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Quá trình quét không tìm thấy bất kỳ kênh nào. Hãy xác minh là bộ dò mạng đã được bật nguồn và kết nối với một nguồn tín hiệu TV.\n\nNếu sử dụng ăng-ten không dây, hãy điều chỉnh vị trí hoặc hướng của ăng-ten. Để có kết quả tốt nhất, hãy đặt ăng-ten ở vị trí cao và gần cửa sổ và quét lại."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Quét lại"</item>
<item msgid="2092797862490235174">"Xong"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Quét tìm các kênh TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Thiết lập bộ dò TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Thiết lập bộ dò TV USB."</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Đã ngắt kết nối bộ điều chỉnh TV USB."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Quét tìm các kênh TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Thiết lập bộ dò TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Thiết lập bộ dò TV USB."</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Thiết lập bộ dò TV mạng"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Đã ngắt kết nối bộ dò truyền hình USB."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Đã ngắt kết nối bộ dò mạng."</string>
</resources>
diff --git a/usbtuner-res/values-zh-rCN/strings.xml b/usbtuner-res/values-zh-rCN/strings.xml
index a4f6da22..cf2b477f 100644
--- a/usbtuner-res/values-zh-rCN/strings.xml
+++ b/usbtuner-res/values-zh-rCN/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"电视调谐器"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB 电视调谐器"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"开启"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"关闭"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"网络电视调谐器(测试版)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"请耐心等待处理完毕"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"选择您的频道来源"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"无信号"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"无法调到<xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"无法调到相应频道"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"调谐器软件近期已更新。请重新扫描频道。"</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"在系统声音设置中启用环绕声即可启用音频"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"无法播放音频,请试试其他电视频道"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"频道调谐器设置"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"电视调谐器设置"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB 频道调谐器设置"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"网络调谐器设置"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"请检查您的电视是否已连接到电视信号源。\n\n如果您使用的是无线电视,则可能需要调节天线的位置或方向,以便接收尽可能多的频道。要获得最佳效果,请将天线的位置调高并靠近窗户。"</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"请检查 USB 调谐器是否已插好并连接到电视信号源。\n\n如果您使用的是无线电视,则可能需要调节天线的位置或方向,以便接收尽可能多的频道。要获得最佳效果,请将天线的位置调高并靠近窗户。"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"请检查网络调谐器是否已接通电源并连接到电视信号源。\n\n如果您使用的是无线电视,则可能需要调节天线的位置或方向,以便接收尽可能多的频道。要获得最佳效果,请将天线的位置调高并靠近窗户。"</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"继续"</item>
<item msgid="727245208787621142">"以后再说"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"要重新进行频道设置吗?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"此操作将移除通过电视调谐器找到的频道,并重新扫描新频道。\n\n请检查您的电视是否已连接到电视信号源。\n\n如果您使用的是无线电视,则可能需要调节天线的位置或方向,以便接收尽可能多的频道。要获得最佳效果,请将天线的位置调高并靠近窗户。"</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"此操作将移除通过 USB 调谐器找到的频道,并重新扫描新频道。\n\n请检查 USB 调谐器是否已插好并连接到电视信号源。\n\n如果您使用的是无线电视,则可能需要调节天线的位置或方向,以便接收尽可能多的频道。要获得最佳效果,请将天线的位置调高并靠近窗户。"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"此操作将移除通过网络调谐器找到的频道,并重新扫描新频道。\n\n请检查网络调谐器是否已接通电源并连接到电视信号源。\n\n如果您使用的是无线电视,则可能需要调节天线的位置或方向,以便接收尽可能多的频道。要获得最佳效果,请将天线的位置调高并靠近窗户。"</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"继续"</item>
<item msgid="235450158666155406">"取消"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"电视调谐器设置"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB 频道调谐器设置"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"网络频道调谐器设置"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"此过程可能需要几分钟时间"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"调谐器暂时无法使用或已用于录制。"</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"未找到任何频道"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"扫描后未找到任何频道。请检查您的电视是否已连接到电视信号源。\n\n如果您使用的是无线电视,请调节天线的位置或方向。要获得最佳效果,请将天线的位置调高并靠近窗户,然后再扫描一次。"</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"扫描后未找到任何频道。请检查 USB 调谐器是否已插好并连接到电视信号源。\n\n如果您使用的是无线电视,请调节天线的位置或方向。要获得最佳效果,请将天线的位置调高并靠近窗户,然后再扫描一次。"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"扫描后未找到任何频道。请检查网络调谐器是否已接通电源并连接到电视信号源。\n\n如果您使用的是无线电视,请调节天线的位置或方向。要获得最佳效果,请将天线的位置调高并靠近窗户,然后再扫描一次。"</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"重新扫描"</item>
<item msgid="2092797862490235174">"完成"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"扫描电视频道"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"电视调谐器设置"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB 电视调谐器设置"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB 电视调谐器已断开连接。"</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"扫描电视频道"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"电视调谐器设置"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB 电视调谐器设置"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"网络电视调谐器设置"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB 电视调谐器已断开连接。"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"网络调谐器已断开连接。"</string>
</resources>
diff --git a/usbtuner-res/values-zh-rHK/strings.xml b/usbtuner-res/values-zh-rHK/strings.xml
index 6d40401e..f2b89519 100644
--- a/usbtuner-res/values-zh-rHK/strings.xml
+++ b/usbtuner-res/values-zh-rHK/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"電視調諧器"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB 電視調諧器"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"開啟"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"關閉"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"網絡電視調諧器 (測試版)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"請等待系統完成處理程序"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"請選擇您的頻道來源"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"無訊號"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"無法調校至<xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"無法調校頻道"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"調諧器軟件最近已更新。請重新掃瞄頻道。"</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"在系統音效設定中啟用環迴立體聲功能即可啟用音效"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"無法播放音效,請嘗試使用其他電視頻道"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"頻道調諧器設定"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"電視調諧器設定"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB 頻道調諧器設定"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"網絡調諧器設定"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"請確定電視已連接至電視訊號來源。\n\n如果您使用無線天線,可能需要調整天線的位置或方向,以接收最多頻道。您亦可將天線放在較高位置並靠近窗戶,以獲得最佳效果。"</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"請確定 USB 調諧器已接駁並連接至電視訊號來源。\n\n如果您使用無線天線,可能需要調整天線的位置或方向,以接收最多頻道。您亦可以將天線放在較高位置並靠近窗戶,以獲取最佳效果。"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"請確定網絡調諧器已開啟電源,並連接至電視訊號來源。\n\n如果您使用無線天線,可能需要調整天線的位置或方向,以接收最多頻道。要取得最佳效果,請將天線放在較高位置並靠近窗戶,然後重新掃瞄。"</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"繼續"</item>
<item msgid="727245208787621142">"暫時不要"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"要重新設定頻道嗎?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"這項操作將移除電視調諧器找到的頻道,並重新掃瞄新的頻道。\n\n請確定電視已連接至電視訊號來源。\n\n如果您使用無線天線,可能需要調整天線的位置或方向,以接收最多頻道。您亦可將天線放在較高位置並靠近窗戶,以獲得最佳效果。"</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"這項操作將移除 USB 調諧器找到的頻道,並會重新掃瞄新頻道。\n\n請確定 USB 調諧器已接駁並連接至電視訊號來源。\n\n如果您使用無線天線,可能需要調整天線的位置或方向,以接收最多頻道。您亦可將天線放在較高位置並靠近窗戶,以獲取最佳效果。"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"這項操作將移除網絡調諧器找到的頻道,並再次掃瞄新頻道。\n\n請確定網絡調諧器已開啟電源並連接至電視訊號來源。\n\n如果您使用無線天線,請調整天線的位置或方向。要取得最佳效果,請將天線放在較高位置並靠近窗戶,然後重新掃瞄。"</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"繼續"</item>
<item msgid="235450158666155406">"取消"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"電視調諧器設定"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB 頻道調諧器設定"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"網絡頻道調諧器設定"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"可能需時數分鐘"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"調諧器暫時無法使用,或已用於錄影。"</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"找不到頻道"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"掃瞄後找不到頻道。請確定電視已連接至電視訊號來源。\n\n如果您使用無線天線,請調整天線的位置或方向。您亦可將天線放在較高位置並靠近窗戶,然後重新掃瞄,以獲得最佳效果。"</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"掃瞄找不到頻道。請確定 USB 調諧器已接駁並連接至電視訊號來源。\n\n如果您使用無線天線,請調整天線的位置或方向。您亦可將天線放在較高位置並靠近窗戶,然後重新掃瞄,以獲取最佳效果。"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"掃瞄後找不到任何頻道。請確定網絡調諧器已開啟電源,並連接至電視訊號來源。\n\n如果您使用無線天線,請調整天線的位置或方向。要取得最佳效果,請將天線放在較高位置並靠近窗戶,然後重新掃瞄。"</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"重新掃瞄"</item>
<item msgid="2092797862490235174">"完成"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"掃瞄電視頻道"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"電視調諧器設定"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB 電視調諧器設定"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"已解除 USB 電視調諧器的連接。"</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"掃瞄電視頻道"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"電視調諧器設定"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB 電視調諧器設定"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"網絡電視調諧器設定"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB 電視調諧器已中斷連線。"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"網絡調諧器已中斷連線。"</string>
</resources>
diff --git a/usbtuner-res/values-zh-rTW/strings.xml b/usbtuner-res/values-zh-rTW/strings.xml
index 802d8b73..86624ef5 100644
--- a/usbtuner-res/values-zh-rTW/strings.xml
+++ b/usbtuner-res/values-zh-rTW/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"電視調諧器"</string>
<string name="ut_app_name" msgid="8557698013780762454">"USB 電視調諧器"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"開啟"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"關閉"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"網路電視調諧器 (測試版)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"請等待處理程序完成"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"選取你的頻道來源"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"無訊號"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"無法轉到「<xliff:g id="CHANNEL_NAME">%s</xliff:g>」"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"無法轉台"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"調諧器軟體最近已更新。請重新掃描頻道。"</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"前往系統音效設定開啟環繞音效即可啟用音訊"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"無法播放音訊,請改用其他電視頻道"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"頻道調諧器設定"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"電視調諧器設定"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"USB 頻道調諧器設定"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"網路調諧器設定"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"請確認你的電視已連接到電視訊號來源。\n\n如果你使用無線電視天線,可能需要調整天線的位置和方向,以便接收最多頻道。為達最佳效果,請將天線放在靠近窗戶的較高位置。"</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"請確認 USB 調諧器已插入並連接到電視訊號來源。\n\n如果你使用無線電視天線,可能需要調整天線的位置和方向,以便接收最多頻道。為達最佳效果,請將天線放在靠近窗戶的較高位置。"</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"請確認你的網路調諧器已開啟電源,並連接到電視訊號來源。\n\n如果你使用無線電視天線,可能需要調整天線的位置和方向,以便接收最多頻道。為達最佳效果,請將天線放在靠近窗戶的較高位置。"</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"繼續"</item>
<item msgid="727245208787621142">"暫時不要"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"要重新設定頻道嗎?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"這項動作將移除電視調諧器找到的頻道,並再次掃描新的頻道。\n\n請確認你的電視已連接到電視訊號來源。\n\n如果你使用無線電視天線,可能需要調整天線的位置和方向,以便接收最多頻道。為達最佳效果,請將天線放在靠近窗戶的較高位置。"</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"這項動作將移除 USB 調諧器找到的頻道,並再次掃描新的頻道。\n\n請確認 USB 調諧器已插入並連接到電視訊號來源。\n\n如果你使用無線電視天線,可能需要調整天線的位置和方向,以便接收最多頻道。為達最佳效果,請將天線放在靠近窗戶的較高位置。"</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"這個動作將移除網路調諧器找到的頻道,並再次掃描新的頻道。\n\n請確認你的網路調諧器已開啟電源,並連接到電視訊號來源。\n\n如果你使用無線電視天線,可能需要調整天線的位置和方向,以便接收最多頻道。為達最佳效果,請將天線放在靠近窗戶的較高位置。"</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"繼續"</item>
<item msgid="235450158666155406">"取消"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"電視調諧器設定"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"USB 頻道調諧器設定"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"網路頻道調諧器設定"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"這可能需要幾分鐘的時間"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"調諧器暫時無法使用,或是已用於錄製。"</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"找不到任何頻道"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"掃描後並未發現任何頻道。請確認你的電視已連接到電視訊號來源。\n\n如果你使用無線電視天線,請調整天線的位置和方向。為達最佳效果,請將天線放在靠近窗戶的較高位置,然後再掃描一次。"</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"掃描後並未發現任何頻道。請確認 USB 調諧器已插入並連接到電視訊號來源。\n\n如果你使用無線電視天線,請調整天線的位置和方向。為達最佳效果,請將天線放在靠近窗戶的較高位置,然後再掃描一次。"</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"掃描後並未發現任何頻道。請確認你的網路調諧器已開啟電源,並連接到電視訊號來源。\n\n如果你使用無線電視天線,請調整天線的位置和方向。為達最佳效果,請將天線放在靠近窗戶的較高位置,然後再掃描一次。"</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"重新掃描"</item>
<item msgid="2092797862490235174">"完成"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"掃描電視頻道"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"電視調諧器設定"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"USB 電視調諧器設定"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"USB 電視調諧器已中斷連結。"</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"掃描電視頻道"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"電視調諧器設定"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"USB 電視調諧器設定"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"網路電視調諧器設定"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"USB 電視調諧器已中斷連線。"</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"網路調諧器已中斷連線。"</string>
</resources>
diff --git a/usbtuner-res/values-zu/strings.xml b/usbtuner-res/values-zu/strings.xml
index 905e9a16..fa8df8d3 100644
--- a/usbtuner-res/values-zu/strings.xml
+++ b/usbtuner-res/values-zu/strings.xml
@@ -19,20 +19,18 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="bt_app_name" msgid="5515382901862469770">"Ishuna ye-TV"</string>
<string name="ut_app_name" msgid="8557698013780762454">"Ishuna ye-USB TV"</string>
- <string name="ut_setup_on" msgid="7755608253387551795">"Vuliwe"</string>
- <string name="ut_setup_off" msgid="1333878787059290524">"Valiwe"</string>
+ <string name="nt_app_name" msgid="4627006858832620833">"Ishuna yenethiwekhi ye-TV (i-BETA)"</string>
<string name="ut_setup_cancel" msgid="5318292052302751909">"Sicela ulinde ukuze uqede ukucubungula"</string>
- <string name="ut_select_channel_map" msgid="4831940000362338865">"Khetha umthombo wesiteshi sakho"</string>
- <string name="ut_no_signal" msgid="7390099185275997984">"Ayikho isignali"</string>
- <string name="ut_fail_to_tune" msgid="2964582177222053143">"Yehlulekile ukushunela ku-<xliff:g id="CHANNEL_NAME">%s</xliff:g>"</string>
- <string name="ut_fail_to_tune_to_unknown_channel" msgid="7078953579048783762">"Yehlulekile ukushuna"</string>
<string name="ut_rescan_needed" msgid="2273655435759849436">"Isofthiwe yeshuna ibuyekezwe kamuva. Sicela uphinde uskene iziteshi."</string>
<string name="ut_surround_sound_disabled" msgid="6465044734143962900">"Nika amandla umsindo ozungezile kuzilungiselelo zomsindo wesistimu"</string>
+ <string name="audio_passthrough_not_supported" msgid="8766302073295760976">"Ayikwazi ukudlala umsindo. Sicela uzame enye i-TV"</string>
<string name="ut_setup_breadcrumb" msgid="2810318605327367247">"Ukusethwa kweshuna yesiteshi"</string>
<string name="bt_setup_new_title" msgid="8447554965697762891">"Ukusethwa kweshuna ye-TV"</string>
<string name="ut_setup_new_title" msgid="2118880835101453405">"Ukusetha kweshuna yesiteshi se-USB"</string>
+ <string name="nt_setup_new_title" msgid="2996573474450060002">"Ukusethwa kweshuna yenethiwekhi"</string>
<string name="bt_setup_new_description" msgid="256690722062003128">"Qinisekisa ukuthi i-TV yakho ixhunywe kumthombo wesignali ye-TV.\n\nUma usebenzisa i-antenna esemoyeni, kungenzeka ukuthi kumele ulungise ukubekwa noma ukubheka ukuze uthole iziteshi eziningi. Ukuze uthole imiphumela ehamba phambili, beka phezulu naseduze kwewindi."</string>
<string name="ut_setup_new_description" msgid="2610122936163002137">"Qinisekisa ukuthi ishuna ye-USB ixhunyiwe futhi ixhumeke kumthombo wesignali ye-TV.\n\nUma usebenzisa i-antenna esemoyeni, kuzomele ulungise ukubekwa kwayo noma ukubheka kwayo ukuze uthole iziteshi eziningi. Ukuze uthole imiphumela ehamba phambili, yibeke phezulu eduze kwewindi."</string>
+ <string name="nt_setup_new_description" msgid="8315318180352515751">"Qinisekisa ukuthi ishuna yenethiwekhi ivuliwe yaphinde yaxhunywa kumthombo wesignali ye-TV.\n\nUma usebenzisa i-antenna esemoyeni, kungenzeka ukuthi kumele ulungise ukubekwa kwayo noma indawo ebhekiwe ukuze uthole iziteshi eziningi. Ukuze uthole imiphumela ehamba phambili, ibeke ngaphezulu naseduze kwewindi."</string>
<string-array name="ut_setup_new_choices">
<item msgid="8728069574888601683">"Qhubeka"</item>
<item msgid="727245208787621142">"Hhayi manje"</item>
@@ -40,6 +38,7 @@
<string name="bt_setup_again_title" msgid="884713873101099572">"Phinda uqalise ukusethwa kwesiteshi?"</string>
<string name="bt_setup_again_description" msgid="1247792492948741337">"Lokhu kuzosusa iziteshi ezitholwe kusukela kushuna ye-TV kuphinde kuskenele iziteshi ezintsha.\n\nQinisekisa ukuthi i-TV yakho ixhunywe kumthombo wesignali ye-TV.\n\nUma usebenzisa i-antenna esemoyeni, kungenzeka ukuthi kumele ulungise ukubekwa noma ukubheka ukuze uthole iziteshi eziningi. Ukuze uthole imiphumela ehamba phambili, beka phezulu naseduze kwewindi."</string>
<string name="ut_setup_again_description" msgid="7837706010887799255">"Lokhu kuzosusa iziteshi ezitholakele kusukela kushuna ye-USB kuphinde kuskenele iziteshi ezintsha futhi.\n\nQinisekisa ukuthi ishuna ye-USB ixhunyiwe futhi ixhumeke kumthombo wesignali ye-TV.\n\nUma usebenzisa i-antenna esemoyeni, kuzomele ulungise ukubekwa kwayo noma ukubheka kwayo ukuze uthole iziteshi eziningi. Ukuze uthole imiphumela ehamba phambili, yibeke ngaphezulu naseduze kwewindi."</string>
+ <string name="nt_setup_again_description" msgid="681642895365018072">"Lokhu kuzosusa iziteshi ezitholakele kusukela kushuna yenethiwekhi kuphinde kuskenele iziteshi ezintsha futhi.\n\nQinisekisa ukuthi ishuna yenethiwekhi ixhunyiwe futhi ixhumeke kumthombo wesignali ye-TV.\n\nUma usebenzisa i-antenna esemoyeni, kuzomele ulungise ukubekwa kwayo noma ukubheka kwayo ukuze uthole iziteshi eziningi. Ukuze uthole imiphumela ehamba phambili, yibeke ngaphezulu naseduze kwewindi."</string>
<string-array name="ut_setup_again_choices">
<item msgid="2557527790311851317">"Qhubeka"</item>
<item msgid="235450158666155406">"Khansela"</item>
@@ -54,6 +53,7 @@
</string-array>
<string name="bt_channel_scan" msgid="3291924771702347469">"Ukusethwa kweshuna ye-TV"</string>
<string name="ut_channel_scan" msgid="6100090671500464604">"Ukusetha kweshuna yesiteshi se-USB"</string>
+ <string name="nt_channel_scan" msgid="30206992732534178">"Ukusethwa kweshuna yesiteshi senethiwekhi"</string>
<string name="ut_channel_scan_time" msgid="1844845425359642393">"Lokhu kungathatha amaminithi athile"</string>
<string name="ut_channel_scan_tuner_unavailable" msgid="3135723754380409658">"Ishuna okwamanje ayitholakali noma isivele isetshenziswa ngokurekhodwa."</string>
<plurals name="ut_channel_scan_message" formatted="false" msgid="3131606783282632056">
@@ -76,12 +76,15 @@
<string name="ut_result_not_found_title" msgid="4649533929056795595">"Azikho iziteshi ezitholiwe"</string>
<string name="bt_result_not_found_description" msgid="7378208337325024042">"Ukuskena akuzange kuthole iziteshi. Qinisekisa ukuthi i-TV yakho ixhumeke kumthombo wesignali we-TV.\n\nUma usebenzisa i-antenna esemoyeni, kungenzeka ukuthi kumele ulungise ukubekwa noma ukubheka ukuze uthole iziteshi eziningi. Ukuze uthole imiphumela ehamba phambili, beka phezulu naseduze kwewindi."</string>
<string name="ut_result_not_found_description" msgid="1080746285957681414">"Iskena asizange sithole noma yiziphi iziteshi. Qinisekisa ukuthi ishuna ye-USB ixhunyiwe futhi ixhumeke kumthombo wesignali ye-TV.\n\nUma usebenzisa i-antenna esemoyeni, lungisa ukubekwa kwayo noma ukuma kwayo. Ukuze uthole imiphumela ehamba phambili, yibeke phezulu naseduze kwewindi uphinde uskene."</string>
+ <string name="nt_result_not_found_description" msgid="2177919867285510855">"Iskena asizange sithole noma iziphi iziteshi. Qinisekisa ukuthi ishuna ye-USB ixhunyiwe futhi ixhumeke kumthombo wesignali ye-TV.\n\nUma usebenzisa i-antenna esemoyeni, lungisa ukubekwa kwayo noma ukuma kwayo. Ukuze uthole imiphumela ehamba phambili, yibeke phezulu naseduze kwewindi uphinde uskene."</string>
<string-array name="ut_result_not_found_choices">
<item msgid="5436884968471542030">"Skena futhi"</item>
<item msgid="2092797862490235174">"Kwenziwe"</item>
</string-array>
- <string name="ut_setup_recommendation_card_focused_title" msgid="7434151993964505386">"Skenela iziteshi ze-TV"</string>
- <string name="bt_setup_recommendation_card_title" msgid="1026906771141769829">"Ukusethwa kweshuna ye-TV"</string>
- <string name="ut_setup_recommendation_card_title" msgid="1093869817128338226">"Ukusetha kweshuna ye-USB TV"</string>
- <string name="msg_usb_device_detached" msgid="5123930566630230724">"Isishuni se-USB TV sinqanyuliwe."</string>
+ <string name="ut_setup_notification_content_title" msgid="3439301313253273422">"Skenela iziteshi ze-TV"</string>
+ <string name="bt_setup_notification_content_text" msgid="7578820978070596694">"Ukusethwa kweshuna ye-TV"</string>
+ <string name="ut_setup_notification_content_text" msgid="1656697878628557384">"Ukusetha kweshuna ye-USB TV"</string>
+ <string name="nt_setup_notification_content_text" msgid="1186152789699583895">"Ukusethwa kweshuna yenethiwekhi ye-TV"</string>
+ <string name="msg_usb_tuner_disconnected" msgid="1206606328815245830">"Ishuna ye-USB TV inqanyuliwe."</string>
+ <string name="msg_network_tuner_disconnected" msgid="7103193099674978964">"Ishuna yenethiwekhi inqanyuliwe."</string>
</resources>
diff --git a/usbtuner-res/values/colors.xml b/usbtuner-res/values/colors.xml
index bbcc431f..873ecc8e 100644
--- a/usbtuner-res/values/colors.xml
+++ b/usbtuner-res/values/colors.xml
@@ -16,15 +16,9 @@
-->
<resources>
- <color name="ut_guidedstep_background">#01579B</color>
- <color name="ut_guidance_title_text">#EEEEEE</color>
- <color name="ut_guidance_breadcrumb_text">#EEEEEE</color>
- <color name="ut_guidance_description_text">#B3EEEEEE</color>
- <color name="ut_guidedactions_title_text">#EEEEEE</color>
<color name="ut_scan_title_text">#EEEEEE</color>
<color name="ut_scan_description_text">#B3EEEEEE</color>
<color name="ut_scan_progress">#EEEEEE</color>
<color name="ut_scan_progress_background">#26EEEEEE</color>
<color name="ut_scan_button_text">#EEEEEE</color>
- <color name="ut_scan_channellist_background">#26EEEEEE</color>
</resources> \ No newline at end of file
diff --git a/usbtuner-res/values/dimens.xml b/usbtuner-res/values/dimens.xml
index 0a09b062..1fe39f6c 100644
--- a/usbtuner-res/values/dimens.xml
+++ b/usbtuner-res/values/dimens.xml
@@ -16,41 +16,7 @@
-->
<resources>
- <!-- Default screen margins, per the Android Design guidelines. -->
- <dimen name="ut_activity_horizontal_margin">16dp</dimen>
- <dimen name="ut_activity_vertical_margin">16dp</dimen>
-
- <dimen name="ut_guidance_section_width">592dp</dimen>
- <dimen name="ut_guidedactions_section_width">368dp</dimen>
-
- <dimen name="ut_guidedstep_entry_slide_from">100dp</dimen>
- <dimen name="ut_guidedstep_exit_slide_to">-100dp</dimen>
-
- <dimen name="ut_guidance_padding_start">56dp</dimen>
- <dimen name="ut_guidance_padding_end">32dp</dimen>
- <dimen name="ut_guidance_padding_top">27dp</dimen>
- <dimen name="ut_guidance_anchor_height">156dp</dimen>
-
- <dimen name="ut_guidance_title_text_size">34sp</dimen>
- <dimen name="ut_guidance_breadcrumb_text_size">14sp</dimen>
- <dimen name="ut_guidance_description_text_size">14sp</dimen>
- <dimen name="ut_guidance_description_margin_top">8dp</dimen>
-
- <dimen name="ut_guidedactions_padding_start">24dp</dimen>
- <dimen name="ut_guidedactions_padding_end">40dp</dimen>
- <dimen name="ut_guidedactions_padding_top">27dp</dimen>
- <dimen name="ut_guidedactions_padding_bottom">48dp</dimen>
- <dimen name="ut_guidedactions_anchor_height">163dp</dimen>
- <dimen name="ut_guidedactions_selector_height">48dp</dimen>
-
- <dimen name="ut_guidedactions_item_height">48dp</dimen>
- <dimen name="ut_guidedactions_item_padding_start">16dp</dimen>
- <dimen name="ut_guidedactions_item_padding_end">16dp</dimen>
- <dimen name="ut_guidedactions_item_padding_top">14dp</dimen>
- <dimen name="ut_guidedactions_item_padding_bottom">15dp</dimen>
-
<dimen name="ut_scan_icon_width">80dp</dimen>
- <dimen name="ut_scan_icon_height">80dp</dimen>
<dimen name="ut_scan_icon_margin_right">24dp</dimen>
<dimen name="ut_scan_title_text_size">34sp</dimen>
diff --git a/usbtuner-res/values/integers.xml b/usbtuner-res/values/integers.xml
index 21b438e9..65d20c67 100644
--- a/usbtuner-res/values/integers.xml
+++ b/usbtuner-res/values/integers.xml
@@ -16,10 +16,5 @@
-->
<resources>
- <integer name="ut_guidance_title_max_lines">2</integer>
- <integer name="ut_guidance_description_max_lines">10</integer>
- <integer name="ut_guidedactions_vertical_spcae">8</integer>
<integer name="ut_scan_title_max_lines">2</integer>
- <integer name="ut_entry_anim_duration">300</integer>
- <integer name="ut_exit_anim_duration">300</integer>
</resources> \ No newline at end of file
diff --git a/usbtuner-res/values/strings.xml b/usbtuner-res/values/strings.xml
index e3a8586d..dd393c3e 100644
--- a/usbtuner-res/values/strings.xml
+++ b/usbtuner-res/values/strings.xml
@@ -18,26 +18,15 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Name of this application. It appears in TV app UI, as one of available TV inputs. -->
<string name="bt_app_name">TV Tuner</string>
- <!-- Name of this application when one uses USB tuner. It appears in TV app UI, as one of
+ <!-- Name of this application when one uses USB tuners. It appears in TV app UI, as one of
available TV inputs. -->
<string name="ut_app_name">USB TV Tuner</string>
- <!-- Title for an action which turns a feature on [CHAR LIMIT=30] -->
- <string name="ut_setup_on">On</string>
- <!-- Title for an action which turns a feature off [CHAR LIMIT=30] -->
- <string name="ut_setup_off">Off</string>
+ <!-- Name of this application when one uses network tuners. It appears in TV app UI, as one of
+ available TV inputs. -->
+ <string name="nt_app_name">Network TV Tuner (BETA)</string>
<!-- Message shown when the scanning process is being canceled by a user and the scanning
process needs the time to wait to finish the processing -->
<string name="ut_setup_cancel">Please wait to finish processing</string>
- <!-- Message that asks a user to select the type of signal to be used for input among
- the choices like terrestrial, cable, or satellite -->
- <string name="ut_select_channel_map">Select your channel source</string>
- <!-- Message that indicates TV input signal is lost due to physical disconnection or bad
- reception -->
- <string name="ut_no_signal">No Signal</string>
- <!-- Message that says TV failed to change to a channel (or tune) -->
- <string name="ut_fail_to_tune">Failed to tune to <xliff:g id="channel_name">%s</xliff:g></string>
- <!-- Message that says TV failed to change(or tune) to a channel which has no title -->
- <string name="ut_fail_to_tune_to_unknown_channel">Failed to tune</string>
<!-- Message shown when the scanned channels became invalid due to incompatible changes
found across application versions, hence a user is required to rescan the channels -->
<string name="ut_rescan_needed">Tuner software has been recently updated. Please re-scan the
@@ -45,12 +34,16 @@
<!-- Message that says audio of the current channel is not available due to surround sound
of TV device disabled -->
<string name="ut_surround_sound_disabled">Enable surround sound in system sound settings to enable audio</string>
+ <!-- Message that says audio of the current channel is not available due to AC3 passthrough is not usable -->
+ <string name="audio_passthrough_not_supported">Cannot play audio. Please try another TV</string>
<!-- Usb Tuner setup common UI breadcrumb -->
<string name="ut_setup_breadcrumb">Channel tuner setup</string>
<!-- Title for TV Tuner main setup menu when no channel exists -->
<string name="bt_setup_new_title">TV Tuner setup</string>
<!-- Title for USB tuner main setup menu when no channel exists -->
<string name="ut_setup_new_title">USB channel tuner setup</string>
+ <!-- Title for network tuner main setup menu when no channel exists -->
+ <string name="nt_setup_new_title">Network tuner setup</string>
<!-- Description for TV tuner main setup menu when no channel exists -->
<string name="bt_setup_new_description">Verify your TV is connected to a TV signal
source.\n\nIf using an over-the-air antenna, you may need to adjust its placement or
@@ -61,6 +54,11 @@
to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its
placement or direction to receive the most channels. For best results,
place it high and near a window.</string>
+ <!-- Description for network tuner main setup menu when no channel exists -->
+ <string name="nt_setup_new_description">Verify the network tuner is powered on and connected
+ to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its
+ placement or direction to receive the most channels. For best results,
+ place it high and near a window.</string>
<!-- Menu items for USB tuner main setup menu when no channel exists -->
<string-array name="ut_setup_new_choices">
<!-- Continue setup -->
@@ -82,6 +80,12 @@
to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust its
placement or direction to receive the most channels. For best results, place it high and
near a window.</string>
+ <!-- Description for network tuner main setup menu when channel exists already -->
+ <string name="nt_setup_again_description">This will remove the channels found from the network
+ tuner and scan for new channels again.\n\nVerify the network tuner is powered on and
+ connected to a TV signal source.\n\nIf using an over-the-air antenna, you may need to adjust
+ its placement or direction to receive the most channels. For best results, place it high and
+ near a window.</string>
<!-- Menu items for USB tuner main setup menu when channel exists already -->
<string-array name="ut_setup_again_choices">
<!-- Continue setup -->
@@ -109,6 +113,8 @@
<string name="bt_channel_scan">TV tuner setup</string>
<!-- Title for channel scanning menu. Use this title with USB tuners -->
<string name="ut_channel_scan">USB channel tuner setup</string>
+ <!-- Title for channel scanning menu. Use this title with network tuners -->
+ <string name="nt_channel_scan">Network channel tuner setup</string>
<!-- Message that says channel is not yet scanned during channel scanning process -->
<string name="ut_channel_scan_time">This may take several minutes</string>
<!-- Message that says Tuner is not available -->
@@ -145,29 +151,41 @@
your TV is connected to a TV signal source.\n\nIf using an over-the-air antenna, adjust
its placement or direction. For best results, place it high and near a window and scan
again.</string>
- <!-- Description for channel scanning result menu when no channel was found -->
+ <!-- Description for channel scanning result menu when no channel was found with USB tuners-->
<string name="ut_result_not_found_description">The scan did not find any channels. Verify the
USB tuner is plugged in and connected to a TV signal source.\n\nIf using an over-the-air
antenna, adjust its placement or direction. For best results, place it high and near a
window and scan again.</string>
+ <!-- Description for channel scanning result menu when no channel was found with network
+ tuners -->
+ <string name="nt_result_not_found_description">The scan did not find any channels. Verify the
+ network tuner is powered on and connected to a TV signal source.\n\nIf using an over-the-air
+ antenna, adjust its placement or direction. For best results, place it high and near a
+ window and scan again.</string>
<!-- Menu items for channel scanning result menu when no channel was found -->
<string-array name="ut_result_not_found_choices">
<item>Scan again</item>
<item>Done</item>
</string-array>
- <!-- Recommendation card of USB channel tuner setup strings. -->
- <!-- Content title of the recommendation card to launch the setup application of
- USB tuner TV input for scanning channels. This text is shown only when the card is
- focused. -->
- <string name="ut_setup_recommendation_card_focused_title">Scan for TV channels</string>
- <!-- Content text and info of the recommendation card to launch the setup application of
+ <!-- Notification of USB channel tuner setup strings. -->
+ <!-- Name of notification channel which is for tuner setup. -->
+ <string name="ut_setup_notification_channel_name" translatable="false">USB tuner set up</string>
+ <!-- Content title of the notification to launch the setup application of
+ USB tuner TV input for scanning channels. -->
+ <string name="ut_setup_notification_content_title">Scan for TV channels</string>
+ <!-- Content text and info of the notification to launch the setup application of
built-in tuner TV input for scanning channels. -->
- <string name="bt_setup_recommendation_card_title">TV Tuner setup</string>
- <!-- Content text and info of the recommendation card to launch the setup application of
+ <string name="bt_setup_notification_content_text">TV Tuner setup</string>
+ <!-- Content text and info of the notification to launch the setup application of
USB tuner TV input for scanning channels. -->
- <string name="ut_setup_recommendation_card_title">USB TV Tuner setup</string>
+ <string name="ut_setup_notification_content_text">USB TV Tuner setup</string>
+ <!-- Content text and info of the notification to launch the setup application of
+ network tuner TV input for scanning channels. -->
+ <string name="nt_setup_notification_content_text">Network TV Tuner setup</string>
- <!-- Message when usb tuner device is unplugged. [CHAR LIMIT=NONE] -->
- <string name="msg_usb_device_detached">USB TV tuner disconnected.</string>
+ <!-- Message when USB tuner device is unplugged or disconnected. [CHAR LIMIT=NONE] -->
+ <string name="msg_usb_tuner_disconnected">USB TV tuner disconnected.</string>
+ <!-- Message when Network tuner device is unplugged or disconnected. [CHAR LIMIT=NONE] -->
+ <string name="msg_network_tuner_disconnected">Network tuner disconnected.</string>
</resources>
diff --git a/usbtuner-res/values/styles.xml b/usbtuner-res/values/styles.xml
deleted file mode 100644
index c79319ba..00000000
--- a/usbtuner-res/values/styles.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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 xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="ut_guidance_anchor">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">@dimen/ut_guidance_anchor_height</item>
- </style>
- <style name="ut_guidance_container">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">match_parent</item>
- <item name="android:background">@null</item>
- <item name="android:clipToPadding">false</item>
- <item name="android:clipChildren">false</item>
- </style>
- <style name="ut_guidance_title">
- <item name="android:layout_width">wrap_content</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:layout_alignWithParentIfMissing">true</item>
- <item name="android:layout_below">@id/guidance_anchor_space</item>
- <item name="android:ellipsize">end</item>
- <item name="android:fontFamily">sans-serif-light</item>
- <item name="android:maxLines">@integer/ut_guidance_title_max_lines</item>
- <item name="android:textColor">@color/ut_guidance_title_text</item>
- <item name="android:textSize">@dimen/ut_guidance_title_text_size</item>
- </style>
- <style name="ut_guidance_breadcrumb">
- <item name="android:layout_above">@id/guidance_title</item>
- <item name="android:layout_width">wrap_content</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:layout_alignWithParentIfMissing">true</item>
- <item name="android:ellipsize">end</item>
- <item name="android:fontFamily">sans-serif-condensed</item>
- <item name="android:singleLine">true</item>
- <item name="android:textColor">@color/ut_guidance_breadcrumb_text</item>
- <item name="android:textSize">@dimen/ut_guidance_breadcrumb_text_size</item>
- </style>
- <style name="ut_guidance_desc">
- <item name="android:layout_below">@id/guidance_title</item>
- <item name="android:layout_width">wrap_content</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:layout_marginTop">@dimen/ut_guidance_description_margin_top</item>
- <item name="android:layout_alignWithParentIfMissing">true</item>
- <item name="android:ellipsize">end</item>
- <item name="android:fontFamily">sans-serif</item>
- <item name="android:maxLines">@integer/ut_guidance_description_max_lines</item>
- <item name="android:textColor">@color/ut_guidance_description_text</item>
- <item name="android:textSize">@dimen/ut_guidance_description_text_size</item>
- </style>
- <style name="ut_guidedactions_container">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">match_parent</item>
- <item name="android:background">@null</item>
- <item name="android:clipToPadding">false</item>
- <item name="android:clipChildren">false</item>
- </style>
- <style name="ut_guidedactions_anchor">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">@dimen/ut_guidedactions_anchor_height</item>
- </style>
- <style name="ut_guidedactions_null_selector">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">@dimen/ut_guidedactions_selector_height</item>
- <item name="android:layout_below">@id/guidedactions_anchor_space</item>
- <item name="android:background">@null</item>
- </style>
- <style name="ut_guidedactions_list">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">match_parent</item>
- <item name="android:layout_below">@id/guidedactions_anchor_space</item>
- <item name="android:background">@null</item>
- <item name="android:clipToPadding">false</item>
- <item name="android:clipChildren">false</item>
- <item name="android:focusable">true</item>
- </style>
- <style name="ut_guidedactions_item_container">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">@dimen/ut_guidedactions_item_height</item>
- <item name="android:background">@drawable/ut_selector_background</item>
- <item name="android:focusable">true</item>
- <item name="android:paddingStart">@dimen/ut_guidedactions_item_padding_start</item>
- <item name="android:paddingEnd">@dimen/ut_guidedactions_item_padding_end</item>
- <item name="android:paddingTop">@dimen/ut_guidedactions_item_padding_top</item>
- <item name="android:paddingBottom">@dimen/ut_guidedactions_item_padding_bottom</item>
- </style>
- <style name="ut_guidedactions_item_checkmark">
- <item name="android:layout_width">@dimen/lb_guidedactions_item_checkmark_diameter</item>
- <item name="android:layout_height">@dimen/lb_guidedactions_item_checkmark_diameter</item>
- <item name="android:visibility">gone</item>
- </style>
- <style name="ut_guidedactions_item_title">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:ellipsize">end</item>
- <item name="android:fontFamily">sans-serif-condensed</item>
- <item name="android:singleLine">true</item>
- <item name="android:textColor">@color/ut_guidedactions_title_text</item>
- <item name="android:textSize">14sp</item>
- <item name="android:background">@null</item>
- </style>
- <style name="ut_guidedactions_item_chevron">
- <item name="android:layout_width">wrap_content</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:visibility">gone</item>
- </style>
-</resources>
diff --git a/version.mk b/version.mk
index f63f5834..6886dc07 100644
--- a/version.mk
+++ b/version.mk
@@ -48,13 +48,13 @@
base_version_major := 1
# Change this for each branch
-base_version_minor := 11
+base_version_minor := 15
# code_version_major will overflow at 22
code_version_major := $(shell echo $$(($(base_version_major)+3)))
# x86 and arm sometimes don't match.
-code_version_build := 011
+code_version_build := 007
#####################################################
#####################################################
# Collect automatic version code parameters
@@ -96,7 +96,7 @@ version_code_package := $(code_version_major)$(base_version_minor)$(code_version
ifdef TARGET_BUILD_APPS
ifneq "" "$(filter eng.%,$(BUILD_NUMBER))"
git_hash := $(shell git --git-dir $(LOCAL_PATH)/.git log -n 1 --pretty=format:%h)
- date_string := $(shell date +%m%d%y_%H%M%S)
+ date_string := $(shell date +%Y-%m-%d)
version_name_package := $(base_version_major).$(base_version_minor).$(code_version_build) (eng.$(USER).$(git_hash).$(date_string)-$(base_version_arch)$(base_version_density))
else
version_name_package := $(base_version_major).$(base_version_minor).$(code_version_build) ($(BUILD_NUMBER)-$(base_version_arch)$(base_version_density))